All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V10 00/15] Xen device model support
@ 2011-02-02 14:49 ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Hi,

There is a lot of change since the V9 of the Xen device model. One of theme is
to use the 'pc' machine for Xen instead of duplicate this machine in another
file.

Here is the change since the last version:
  - typedef of qemu_xc_interface, qemu_xc_gnttab and qemu_xc_evtchn have been
    renamed to XenXC, XenGnttab and XenEvtchn;
  - replace asprintf by snprintf;
  - rename "Xen i8259" to Xen Interrupt Controller;
  - remove xen_redirect.h file and replace all Xen calls to use xen_interfaces
    calls;
  - add copyright header in some files;
  - in mapcache, use RLIMIT_AS to have the max mapcache size, instead of have a
    max depends on the architecture;
  - in mapcache, set rlimit_as.rlim_cur = rlimit_as.rlim_max;
  - in xen platform pci device, removed the throttle;
  - qemu_ram_ptr_unlock renamed to qemu_put_ram_ptr;
  - put specific xen calls into pc_piix and xen_machine_fv have been removed;
  - fix few coding style.


This series depends on the series "Introduce "machine" QemuOpts".


You can find a git tree here:

git://xenbits.xen.org/people/aperard/qemu-dm.git qemu-dm-v10


Anthony PERARD (12):
  xen: Replace some tab-indents with spaces (clean-up).
  xen: Make xen build only on x86 target.
  xen: Support new libxc calls from xen unstable.
  xen: Add initialisation of Xen
  xen: Add xenfv machine
  piix_pci: Introduces Xen specific call for irq.
  xen: Introduce Xen Interrupt Controller
  configure: Always use 64bits target physical addresses with xen
    enabled.
  Introduce qemu_put_ram_ptr
  vl.c: Introduce getter for shutdown_requested and reset_requested.
  xen: Set running state in xenstore.
  xen: Add Xen hypercall for sleep state in the cmos_s3 callback.

Arun Sharma (1):
  xen: Initialize event channels and io rings

Jun Nakajima (1):
  xen: Introduce the Xen mapcache

Steven Smith (1):
  xen: Add the Xen platform pci device

 Makefile.objs        |    4 -
 Makefile.target      |   14 ++-
 configure            |   71 ++++++-
 cpu-common.h         |    1 +
 exec.c               |   50 ++++-
 hw/hw.h              |    3 +
 hw/pc.c              |   19 ++-
 hw/pc_piix.c         |   39 +++-
 hw/pci_ids.h         |    2 +
 hw/piix_pci.c        |   28 +++-
 hw/xen.h             |   41 ++++
 hw/xen_backend.c     |  372 ++++++++++++++++----------------
 hw/xen_backend.h     |    7 +-
 hw/xen_common.h      |   40 +++--
 hw/xen_console.c     |   10 +-
 hw/xen_devconfig.c   |   10 +-
 hw/xen_disk.c        |  402 ++++++++++++++++++-----------------
 hw/xen_domainbuild.c |   29 ++--
 hw/xen_interfaces.c  |  191 +++++++++++++++++
 hw/xen_interfaces.h  |  198 +++++++++++++++++
 hw/xen_nic.c         |  230 ++++++++++----------
 hw/xen_platform.c    |  348 ++++++++++++++++++++++++++++++
 hw/xenfb.c           |   14 +-
 sysemu.h             |    2 +
 vl.c                 |   12 +
 xen-all.c            |  579 ++++++++++++++++++++++++++++++++++++++++++++++++++
 xen-mapcache-stub.c  |   40 ++++
 xen-mapcache.c       |  344 ++++++++++++++++++++++++++++++
 xen-mapcache.h       |   22 ++
 xen-stub.c           |   47 ++++
 30 files changed, 2599 insertions(+), 570 deletions(-)
 create mode 100644 hw/xen_interfaces.c
 create mode 100644 hw/xen_interfaces.h
 create mode 100644 hw/xen_platform.c
 create mode 100644 xen-all.c
 create mode 100644 xen-mapcache-stub.c
 create mode 100644 xen-mapcache.c
 create mode 100644 xen-mapcache.h
 create mode 100644 xen-stub.c

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [PATCH V10 00/15] Xen device model support
@ 2011-02-02 14:49 ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Hi,

There is a lot of change since the V9 of the Xen device model. One of theme is
to use the 'pc' machine for Xen instead of duplicate this machine in another
file.

Here is the change since the last version:
  - typedef of qemu_xc_interface, qemu_xc_gnttab and qemu_xc_evtchn have been
    renamed to XenXC, XenGnttab and XenEvtchn;
  - replace asprintf by snprintf;
  - rename "Xen i8259" to Xen Interrupt Controller;
  - remove xen_redirect.h file and replace all Xen calls to use xen_interfaces
    calls;
  - add copyright header in some files;
  - in mapcache, use RLIMIT_AS to have the max mapcache size, instead of have a
    max depends on the architecture;
  - in mapcache, set rlimit_as.rlim_cur = rlimit_as.rlim_max;
  - in xen platform pci device, removed the throttle;
  - qemu_ram_ptr_unlock renamed to qemu_put_ram_ptr;
  - put specific xen calls into pc_piix and xen_machine_fv have been removed;
  - fix few coding style.


This series depends on the series "Introduce "machine" QemuOpts".


You can find a git tree here:

git://xenbits.xen.org/people/aperard/qemu-dm.git qemu-dm-v10


Anthony PERARD (12):
  xen: Replace some tab-indents with spaces (clean-up).
  xen: Make xen build only on x86 target.
  xen: Support new libxc calls from xen unstable.
  xen: Add initialisation of Xen
  xen: Add xenfv machine
  piix_pci: Introduces Xen specific call for irq.
  xen: Introduce Xen Interrupt Controller
  configure: Always use 64bits target physical addresses with xen
    enabled.
  Introduce qemu_put_ram_ptr
  vl.c: Introduce getter for shutdown_requested and reset_requested.
  xen: Set running state in xenstore.
  xen: Add Xen hypercall for sleep state in the cmos_s3 callback.

Arun Sharma (1):
  xen: Initialize event channels and io rings

Jun Nakajima (1):
  xen: Introduce the Xen mapcache

Steven Smith (1):
  xen: Add the Xen platform pci device

 Makefile.objs        |    4 -
 Makefile.target      |   14 ++-
 configure            |   71 ++++++-
 cpu-common.h         |    1 +
 exec.c               |   50 ++++-
 hw/hw.h              |    3 +
 hw/pc.c              |   19 ++-
 hw/pc_piix.c         |   39 +++-
 hw/pci_ids.h         |    2 +
 hw/piix_pci.c        |   28 +++-
 hw/xen.h             |   41 ++++
 hw/xen_backend.c     |  372 ++++++++++++++++----------------
 hw/xen_backend.h     |    7 +-
 hw/xen_common.h      |   40 +++--
 hw/xen_console.c     |   10 +-
 hw/xen_devconfig.c   |   10 +-
 hw/xen_disk.c        |  402 ++++++++++++++++++-----------------
 hw/xen_domainbuild.c |   29 ++--
 hw/xen_interfaces.c  |  191 +++++++++++++++++
 hw/xen_interfaces.h  |  198 +++++++++++++++++
 hw/xen_nic.c         |  230 ++++++++++----------
 hw/xen_platform.c    |  348 ++++++++++++++++++++++++++++++
 hw/xenfb.c           |   14 +-
 sysemu.h             |    2 +
 vl.c                 |   12 +
 xen-all.c            |  579 ++++++++++++++++++++++++++++++++++++++++++++++++++
 xen-mapcache-stub.c  |   40 ++++
 xen-mapcache.c       |  344 ++++++++++++++++++++++++++++++
 xen-mapcache.h       |   22 ++
 xen-stub.c           |   47 ++++
 30 files changed, 2599 insertions(+), 570 deletions(-)
 create mode 100644 hw/xen_interfaces.c
 create mode 100644 hw/xen_interfaces.h
 create mode 100644 hw/xen_platform.c
 create mode 100644 xen-all.c
 create mode 100644 xen-mapcache-stub.c
 create mode 100644 xen-mapcache.c
 create mode 100644 xen-mapcache.h
 create mode 100644 xen-stub.c

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 01/15] xen: Replace some tab-indents with spaces (clean-up).
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 hw/xen_backend.c |  308 +++++++++++++++++++++---------------------
 hw/xen_disk.c    |  394 +++++++++++++++++++++++++++---------------------------
 hw/xen_nic.c     |  222 +++++++++++++++---------------
 3 files changed, 462 insertions(+), 462 deletions(-)

diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index a2e408f..860b038 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -59,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val)
 
     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
     if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
-	return -1;
+        return -1;
     return 0;
 }
 
@@ -95,7 +95,7 @@ int xenstore_read_int(const char *base, const char *node, int *ival)
 
     val = xenstore_read_str(base, node);
     if (val && 1 == sscanf(val, "%d", ival))
-	rc = 0;
+        rc = 0;
     qemu_free(val);
     return rc;
 }
@@ -134,16 +134,16 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
 
 const char *xenbus_strstate(enum xenbus_state state)
 {
-	static const char *const name[] = {
-		[ XenbusStateUnknown      ] = "Unknown",
-		[ XenbusStateInitialising ] = "Initialising",
-		[ XenbusStateInitWait     ] = "InitWait",
-		[ XenbusStateInitialised  ] = "Initialised",
-		[ XenbusStateConnected    ] = "Connected",
-		[ XenbusStateClosing      ] = "Closing",
-		[ XenbusStateClosed	  ] = "Closed",
-	};
-	return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
+    static const char *const name[] = {
+        [ XenbusStateUnknown      ] = "Unknown",
+        [ XenbusStateInitialising ] = "Initialising",
+        [ XenbusStateInitWait     ] = "InitWait",
+        [ XenbusStateInitialised  ] = "Initialised",
+        [ XenbusStateConnected    ] = "Connected",
+        [ XenbusStateClosing      ] = "Closing",
+        [ XenbusStateClosed       ] = "Closed",
+    };
+    return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
 }
 
 int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
@@ -152,9 +152,9 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
 
     rc = xenstore_write_be_int(xendev, "state", state);
     if (rc < 0)
-	return rc;
+        return rc;
     xen_be_printf(xendev, 1, "backend state: %s -> %s\n",
-		  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
+                  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
     xendev->be_state = state;
     return 0;
 }
@@ -166,13 +166,13 @@ struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
     struct XenDevice *xendev;
 
     QTAILQ_FOREACH(xendev, &xendevs, next) {
-	if (xendev->dom != dom)
-	    continue;
-	if (xendev->dev != dev)
-	    continue;
-	if (strcmp(xendev->type, type) != 0)
-	    continue;
-	return xendev;
+        if (xendev->dom != dom)
+            continue;
+        if (xendev->dev != dev)
+            continue;
+        if (strcmp(xendev->type, type) != 0)
+            continue;
+        return xendev;
     }
     return NULL;
 }
@@ -188,7 +188,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 
     xendev = xen_be_find_xendev(type, dom, dev);
     if (xendev)
-	return xendev;
+        return xendev;
 
     /* init new xendev */
     xendev = qemu_mallocz(ops->size);
@@ -199,9 +199,9 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 
     dom0 = xs_get_domain_path(xenstore, 0);
     snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
-	     dom0, xendev->type, xendev->dom, xendev->dev);
+             dom0, xendev->type, xendev->dom, xendev->dev);
     snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
-	     xendev->type, xendev->dev);
+             xendev->type, xendev->dev);
     free(dom0);
 
     xendev->debug      = debug;
@@ -209,28 +209,28 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 
     xendev->evtchndev = xc_evtchn_open();
     if (xendev->evtchndev < 0) {
-	xen_be_printf(NULL, 0, "can't open evtchn device\n");
-	qemu_free(xendev);
-	return NULL;
+        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);
 
     if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
-	xendev->gnttabdev = xc_gnttab_open();
-	if (xendev->gnttabdev < 0) {
-	    xen_be_printf(NULL, 0, "can't open gnttab device\n");
-	    xc_evtchn_close(xendev->evtchndev);
-	    qemu_free(xendev);
-	    return NULL;
-	}
+        xendev->gnttabdev = xc_gnttab_open();
+        if (xendev->gnttabdev < 0) {
+            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 = -1;
     }
 
     QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
 
     if (xendev->ops->alloc)
-	xendev->ops->alloc(xendev);
+        xendev->ops->alloc(xendev);
 
     return xendev;
 }
@@ -251,28 +251,28 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
         xendev = xnext;
         xnext = xendev->next.tqe_next;
 
-	if (xendev->dom != dom)
-	    continue;
-	if (xendev->dev != dev && dev != -1)
-	    continue;
+        if (xendev->dom != dom)
+            continue;
+        if (xendev->dev != dev && dev != -1)
+            continue;
 
-	if (xendev->ops->free)
-	    xendev->ops->free(xendev);
+        if (xendev->ops->free)
+            xendev->ops->free(xendev);
 
-	if (xendev->fe) {
-	    char token[XEN_BUFSIZE];
-	    snprintf(token, sizeof(token), "fe:%p", xendev);
-	    xs_unwatch(xenstore, xendev->fe, token);
-	    qemu_free(xendev->fe);
-	}
+        if (xendev->fe) {
+            char token[XEN_BUFSIZE];
+            snprintf(token, sizeof(token), "fe:%p", xendev);
+            xs_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 >= 0)
+            xc_evtchn_close(xendev->evtchndev);
+        if (xendev->gnttabdev >= 0)
+            xc_gnttab_close(xendev->gnttabdev);
 
-	QTAILQ_REMOVE(&xendevs, xendev, next);
-	qemu_free(xendev);
+        QTAILQ_REMOVE(&xendevs, xendev, next);
+        qemu_free(xendev);
     }
     return NULL;
 }
@@ -285,14 +285,14 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
 static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
 {
     if (node == NULL  ||  strcmp(node, "online") == 0) {
-	if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1)
-	    xendev->online = 0;
+        if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1)
+            xendev->online = 0;
     }
 
     if (node) {
-	xen_be_printf(xendev, 2, "backend update: %s\n", node);
-	if (xendev->ops->backend_changed)
-	    xendev->ops->backend_changed(xendev, node);
+        xen_be_printf(xendev, 2, "backend update: %s\n", node);
+        if (xendev->ops->backend_changed)
+            xendev->ops->backend_changed(xendev, node);
     }
 }
 
@@ -301,25 +301,25 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
     int fe_state;
 
     if (node == NULL  ||  strcmp(node, "state") == 0) {
-	if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1)
-	    fe_state = XenbusStateUnknown;
-	if (xendev->fe_state != fe_state)
-	    xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
-			  xenbus_strstate(xendev->fe_state),
-			  xenbus_strstate(fe_state));
-	xendev->fe_state = fe_state;
+        if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1)
+            fe_state = XenbusStateUnknown;
+        if (xendev->fe_state != fe_state)
+            xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
+                          xenbus_strstate(xendev->fe_state),
+                          xenbus_strstate(fe_state));
+        xendev->fe_state = fe_state;
     }
     if (node == NULL  ||  strcmp(node, "protocol") == 0) {
-	qemu_free(xendev->protocol);
-	xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
-	if (xendev->protocol)
-	    xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
+        qemu_free(xendev->protocol);
+        xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
+        if (xendev->protocol)
+            xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
     }
 
     if (node) {
-	xen_be_printf(xendev, 2, "frontend update: %s\n", node);
-	if (xendev->ops->frontend_changed)
-	    xendev->ops->frontend_changed(xendev, node);
+        xen_be_printf(xendev, 2, "frontend update: %s\n", node);
+        if (xendev->ops->frontend_changed)
+            xendev->ops->frontend_changed(xendev, node);
     }
 }
 
@@ -340,28 +340,28 @@ static int xen_be_try_setup(struct XenDevice *xendev)
     int be_state;
 
     if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
-	xen_be_printf(xendev, 0, "reading backend state failed\n");
-	return -1;
+        xen_be_printf(xendev, 0, "reading backend state failed\n");
+        return -1;
     }
 
     if (be_state != XenbusStateInitialising) {
-	xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
-		      xenbus_strstate(be_state));
-	return -1;
+        xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
+                      xenbus_strstate(be_state));
+        return -1;
     }
 
     xendev->fe = xenstore_read_be_str(xendev, "frontend");
     if (xendev->fe == NULL) {
-	xen_be_printf(xendev, 0, "reading frontend path failed\n");
-	return -1;
+        xen_be_printf(xendev, 0, "reading frontend path failed\n");
+        return -1;
     }
 
     /* setup frontend watch */
     snprintf(token, sizeof(token), "fe:%p", xendev);
     if (!xs_watch(xenstore, xendev->fe, token)) {
-	xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
-		      xendev->fe);
-	return -1;
+        xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
+                      xendev->fe);
+        return -1;
     }
     xen_be_set_state(xendev, XenbusStateInitialising);
 
@@ -383,15 +383,15 @@ static int xen_be_try_init(struct XenDevice *xendev)
     int rc = 0;
 
     if (!xendev->online) {
-	xen_be_printf(xendev, 1, "not online\n");
-	return -1;
+        xen_be_printf(xendev, 1, "not online\n");
+        return -1;
     }
 
     if (xendev->ops->init)
-	rc = xendev->ops->init(xendev);
+        rc = xendev->ops->init(xendev);
     if (rc != 0) {
-	xen_be_printf(xendev, 1, "init() failed\n");
-	return rc;
+        xen_be_printf(xendev, 1, "init() failed\n");
+        return rc;
     }
 
     xenstore_write_be_str(xendev, "hotplug-status", "connected");
@@ -411,20 +411,20 @@ static int xen_be_try_connect(struct XenDevice *xendev)
     int rc = 0;
 
     if (xendev->fe_state != XenbusStateInitialised  &&
-	xendev->fe_state != XenbusStateConnected) {
-	if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
-	    xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
-	} else {
-	    xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
-	    return -1;
-	}
+        xendev->fe_state != XenbusStateConnected) {
+        if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
+            xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
+        } else {
+            xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
+            return -1;
+        }
     }
 
     if (xendev->ops->connect)
-	rc = xendev->ops->connect(xendev);
+        rc = xendev->ops->connect(xendev);
     if (rc != 0) {
-	xen_be_printf(xendev, 0, "connect() failed\n");
-	return rc;
+        xen_be_printf(xendev, 0, "connect() failed\n");
+        return rc;
     }
 
     xen_be_set_state(xendev, XenbusStateConnected);
@@ -441,7 +441,7 @@ static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
     if (xendev->be_state != XenbusStateClosing &&
         xendev->be_state != XenbusStateClosed  &&
         xendev->ops->disconnect)
-	xendev->ops->disconnect(xendev);
+        xendev->ops->disconnect(xendev);
     if (xendev->be_state != state)
         xen_be_set_state(xendev, state);
 }
@@ -468,31 +468,31 @@ void xen_be_check_state(struct XenDevice *xendev)
 
     /* frontend may request shutdown from almost anywhere */
     if (xendev->fe_state == XenbusStateClosing ||
-	xendev->fe_state == XenbusStateClosed) {
-	xen_be_disconnect(xendev, xendev->fe_state);
-	return;
+        xendev->fe_state == XenbusStateClosed) {
+        xen_be_disconnect(xendev, xendev->fe_state);
+        return;
     }
 
     /* check for possible backend state transitions */
     for (;;) {
-	switch (xendev->be_state) {
-	case XenbusStateUnknown:
-	    rc = xen_be_try_setup(xendev);
-	    break;
-	case XenbusStateInitialising:
-	    rc = xen_be_try_init(xendev);
-	    break;
-	case XenbusStateInitWait:
-	    rc = xen_be_try_connect(xendev);
-	    break;
+        switch (xendev->be_state) {
+        case XenbusStateUnknown:
+            rc = xen_be_try_setup(xendev);
+            break;
+        case XenbusStateInitialising:
+            rc = xen_be_try_init(xendev);
+            break;
+        case XenbusStateInitWait:
+            rc = xen_be_try_connect(xendev);
+            break;
         case XenbusStateClosed:
             rc = xen_be_try_reset(xendev);
             break;
-	default:
-	    rc = -1;
-	}
-	if (rc != 0)
-	    break;
+        default:
+            rc = -1;
+        }
+        if (rc != 0)
+            break;
     }
 }
 
@@ -511,26 +511,26 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
     snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
     free(dom0);
     if (!xs_watch(xenstore, path, token)) {
-	xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
-	return -1;
+        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);
     if (!dev)
-	return 0;
+        return 0;
     for (j = 0; j < cdev; j++) {
-	xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
-	if (xendev == NULL)
-	    continue;
-	xen_be_check_state(xendev);
+        xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
+        if (xendev == NULL)
+            continue;
+        xen_be_check_state(xendev);
     }
     free(dev);
     return 0;
 }
 
 static void xenstore_update_be(char *watch, char *type, int dom,
-			       struct XenDevOps *ops)
+                               struct XenDevOps *ops)
 {
     struct XenDevice *xendev;
     char path[XEN_BUFSIZE], *dom0;
@@ -540,24 +540,24 @@ static void xenstore_update_be(char *watch, char *type, int dom,
     len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
     free(dom0);
     if (strncmp(path, watch, len) != 0)
-	return;
+        return;
     if (sscanf(watch+len, "/%u/%255s", &dev, path) != 2) {
-	strcpy(path, "");
-	if (sscanf(watch+len, "/%u", &dev) != 1)
-	    dev = -1;
+        strcpy(path, "");
+        if (sscanf(watch+len, "/%u", &dev) != 1)
+            dev = -1;
     }
     if (dev == -1)
-	return;
+        return;
 
     if (0) {
-	/* FIXME: detect devices being deleted from xenstore ... */
-	xen_be_del_xendev(dom, dev);
+        /* FIXME: detect devices being deleted from xenstore ... */
+        xen_be_del_xendev(dom, dev);
     }
 
     xendev = xen_be_get_xendev(type, dom, dev, ops);
     if (xendev != NULL) {
-	xen_be_backend_changed(xendev, path);
-	xen_be_check_state(xendev);
+        xen_be_backend_changed(xendev, path);
+        xen_be_check_state(xendev);
     }
 }
 
@@ -568,9 +568,9 @@ static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
 
     len = strlen(xendev->fe);
     if (strncmp(xendev->fe, watch, len) != 0)
-	return;
+        return;
     if (watch[len] != '/')
-	return;
+        return;
     node = watch + len + 1;
 
     xen_be_frontend_changed(xendev, node);
@@ -585,13 +585,13 @@ static void xenstore_update(void *unused)
 
     vec = xs_read_watch(xenstore, &count);
     if (vec == NULL)
-	goto cleanup;
+        goto cleanup;
 
     if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
                &type, &dom, &ops) == 3)
-	xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
+        xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
     if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1)
-	xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
+        xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
 
 cleanup:
     free(vec);
@@ -604,14 +604,14 @@ static void xen_be_evtchn_event(void *opaque)
 
     port = xc_evtchn_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;
+        xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n",
+                      port, xendev->local_port);
+        return;
     }
     xc_evtchn_unmask(xendev->evtchndev, port);
 
     if (xendev->ops->event)
-	xendev->ops->event(xendev);
+        xendev->ops->event(xendev);
 }
 
 /* -------------------------------------------------------------------- */
@@ -620,17 +620,17 @@ int xen_be_init(void)
 {
     xenstore = xs_daemon_open();
     if (!xenstore) {
-	xen_be_printf(NULL, 0, "can't connect to xenstored\n");
-	return -1;
+        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)
-	goto err;
+        goto err;
 
     xen_xc = xc_interface_open();
     if (xen_xc == -1) {
-	xen_be_printf(NULL, 0, "can't open xen interface\n");
-	goto err;
+        xen_be_printf(NULL, 0, "can't open xen interface\n");
+        goto err;
     }
     return 0;
 
@@ -650,23 +650,23 @@ int xen_be_register(const char *type, struct XenDevOps *ops)
 int xen_be_bind_evtchn(struct XenDevice *xendev)
 {
     if (xendev->local_port != -1)
-	return 0;
+        return 0;
     xendev->local_port = xc_evtchn_bind_interdomain
-	(xendev->evtchndev, xendev->dom, xendev->remote_port);
+        (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, 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),
-			xen_be_evtchn_event, NULL, xendev);
+                        xen_be_evtchn_event, NULL, xendev);
     return 0;
 }
 
 void xen_be_unbind_evtchn(struct XenDevice *xendev)
 {
     if (xendev->local_port == -1)
-	return;
+        return;
     qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
     xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
     xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index ed9e5eb..7f6aaca 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -120,17 +120,17 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
     struct ioreq *ioreq = NULL;
 
     if (QLIST_EMPTY(&blkdev->freelist)) {
-	if (blkdev->requests_total >= max_requests)
-	    goto out;
-	/* allocate new struct */
-	ioreq = qemu_mallocz(sizeof(*ioreq));
-	ioreq->blkdev = blkdev;
-	blkdev->requests_total++;
+        if (blkdev->requests_total >= max_requests)
+            goto out;
+        /* allocate new struct */
+        ioreq = qemu_mallocz(sizeof(*ioreq));
+        ioreq->blkdev = blkdev;
+        blkdev->requests_total++;
         qemu_iovec_init(&ioreq->v, BLKIF_MAX_SEGMENTS_PER_REQUEST);
     } else {
-	/* get one from freelist */
-	ioreq = QLIST_FIRST(&blkdev->freelist);
-	QLIST_REMOVE(ioreq, list);
+        /* get one from freelist */
+        ioreq = QLIST_FIRST(&blkdev->freelist);
+        QLIST_REMOVE(ioreq, list);
         qemu_iovec_reset(&ioreq->v);
     }
     QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
@@ -173,30 +173,30 @@ static int ioreq_parse(struct ioreq *ioreq)
     int i;
 
     xen_be_printf(&blkdev->xendev, 3,
-		  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
-		  ioreq->req.operation, ioreq->req.nr_segments,
-		  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
+                  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
+                  ioreq->req.operation, ioreq->req.nr_segments,
+                  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
-	ioreq->prot = PROT_WRITE; /* to memory */
-	break;
+        ioreq->prot = PROT_WRITE; /* to memory */
+        break;
     case BLKIF_OP_WRITE_BARRIER:
         if (!ioreq->req.nr_segments) {
             ioreq->presync = 1;
             return 0;
         }
-	if (!syncwrite)
-	    ioreq->presync = ioreq->postsync = 1;
-	/* fall through */
+        if (!syncwrite)
+            ioreq->presync = ioreq->postsync = 1;
+        /* fall through */
     case BLKIF_OP_WRITE:
-	ioreq->prot = PROT_READ; /* from memory */
-	if (syncwrite)
-	    ioreq->postsync = 1;
-	break;
+        ioreq->prot = PROT_READ; /* from memory */
+        if (syncwrite)
+            ioreq->postsync = 1;
+        break;
     default:
-	xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
-		      ioreq->req.operation);
-	goto err;
+        xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
+                      ioreq->req.operation);
+        goto err;
     };
 
     if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
@@ -206,29 +206,29 @@ static int ioreq_parse(struct ioreq *ioreq)
 
     ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
     for (i = 0; i < ioreq->req.nr_segments; i++) {
-	if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-	    xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
-	    goto err;
-	}
-	if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-	    xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n");
-	    goto err;
-	}
-	if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-	    xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
-	    goto err;
-	}
-
-	ioreq->domids[i] = blkdev->xendev.dom;
-	ioreq->refs[i]   = ioreq->req.seg[i].gref;
-
-	mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
-	len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
+        if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+            xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
+            xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
+            xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
+            goto err;
+        }
+
+        ioreq->domids[i] = blkdev->xendev.dom;
+        ioreq->refs[i]   = ioreq->req.seg[i].gref;
+
+        mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
+        len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
         qemu_iovec_add(&ioreq->v, (void*)mem, len);
     }
     if (ioreq->start + ioreq->v.size > blkdev->file_size) {
-	xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
-	goto err;
+        xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
+        goto err;
     }
     return 0;
 
@@ -245,23 +245,23 @@ static void ioreq_unmap(struct ioreq *ioreq)
     if (ioreq->v.niov == 0)
         return;
     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",
-			  strerror(errno));
-	ioreq->blkdev->cnt_map -= ioreq->v.niov;
-	ioreq->pages = NULL;
+        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",
+                          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",
-			      strerror(errno));
-	    ioreq->blkdev->cnt_map--;
-	    ioreq->page[i] = NULL;
-	}
+        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",
+                              strerror(errno));
+            ioreq->blkdev->cnt_map--;
+            ioreq->page[i] = NULL;
+        }
     }
 }
 
@@ -273,32 +273,32 @@ static int ioreq_map(struct ioreq *ioreq)
     if (ioreq->v.niov == 0)
         return 0;
     if (batch_maps) {
-	ioreq->pages = xc_gnttab_map_grant_refs
-	    (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
-	if (ioreq->pages == NULL) {
-	    xen_be_printf(&ioreq->blkdev->xendev, 0,
-			  "can't map %d grant refs (%s, %d maps)\n",
-			  ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
-	    return -1;
-	}
-	for (i = 0; i < ioreq->v.niov; i++)
-	    ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
-		(uintptr_t)ioreq->v.iov[i].iov_base;
-	ioreq->blkdev->cnt_map += ioreq->v.niov;
+        ioreq->pages = xc_gnttab_map_grant_refs
+            (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
+        if (ioreq->pages == NULL) {
+            xen_be_printf(&ioreq->blkdev->xendev, 0,
+                          "can't map %d grant refs (%s, %d maps)\n",
+                          ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
+            return -1;
+        }
+        for (i = 0; i < ioreq->v.niov; i++)
+            ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
+                (uintptr_t)ioreq->v.iov[i].iov_base;
+        ioreq->blkdev->cnt_map += ioreq->v.niov;
     } else  {
-	for (i = 0; i < ioreq->v.niov; i++) {
-	    ioreq->page[i] = xc_gnttab_map_grant_ref
-		(gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
-	    if (ioreq->page[i] == NULL) {
-		xen_be_printf(&ioreq->blkdev->xendev, 0,
-			      "can't map grant ref %d (%s, %d maps)\n",
-			      ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
-		ioreq_unmap(ioreq);
-		return -1;
-	    }
-	    ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
-	    ioreq->blkdev->cnt_map++;
-	}
+        for (i = 0; i < ioreq->v.niov; i++) {
+            ioreq->page[i] = xc_gnttab_map_grant_ref
+                (gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
+            if (ioreq->page[i] == NULL) {
+                xen_be_printf(&ioreq->blkdev->xendev, 0,
+                              "can't map grant ref %d (%s, %d maps)\n",
+                              ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
+                ioreq_unmap(ioreq);
+                return -1;
+            }
+            ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
+            ioreq->blkdev->cnt_map++;
+        }
     }
     return 0;
 }
@@ -310,53 +310,53 @@ static int ioreq_runio_qemu_sync(struct ioreq *ioreq)
     off_t pos;
 
     if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1)
-	goto err;
+        goto err;
     if (ioreq->presync)
-	bdrv_flush(blkdev->bs);
+        bdrv_flush(blkdev->bs);
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
-	pos = ioreq->start;
-	for (i = 0; i < ioreq->v.niov; i++) {
-	    rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,
-			   ioreq->v.iov[i].iov_base,
-			   ioreq->v.iov[i].iov_len / BLOCK_SIZE);
-	    if (rc != 0) {
-		xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",
-			      ioreq->v.iov[i].iov_base,
-			      ioreq->v.iov[i].iov_len);
-		goto err;
-	    }
-	    len += ioreq->v.iov[i].iov_len;
-	    pos += ioreq->v.iov[i].iov_len;
-	}
-	break;
+        pos = ioreq->start;
+        for (i = 0; i < ioreq->v.niov; i++) {
+            rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,
+                           ioreq->v.iov[i].iov_base,
+                           ioreq->v.iov[i].iov_len / BLOCK_SIZE);
+            if (rc != 0) {
+                xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",
+                              ioreq->v.iov[i].iov_base,
+                              ioreq->v.iov[i].iov_len);
+                goto err;
+            }
+            len += ioreq->v.iov[i].iov_len;
+            pos += ioreq->v.iov[i].iov_len;
+        }
+        break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_WRITE_BARRIER:
         if (!ioreq->req.nr_segments)
             break;
-	pos = ioreq->start;
-	for (i = 0; i < ioreq->v.niov; i++) {
-	    rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,
-			    ioreq->v.iov[i].iov_base,
-			    ioreq->v.iov[i].iov_len / BLOCK_SIZE);
-	    if (rc != 0) {
-		xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",
-			      ioreq->v.iov[i].iov_base,
-			      ioreq->v.iov[i].iov_len);
-		goto err;
-	    }
-	    len += ioreq->v.iov[i].iov_len;
-	    pos += ioreq->v.iov[i].iov_len;
-	}
-	break;
+        pos = ioreq->start;
+        for (i = 0; i < ioreq->v.niov; i++) {
+            rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,
+                            ioreq->v.iov[i].iov_base,
+                            ioreq->v.iov[i].iov_len / BLOCK_SIZE);
+            if (rc != 0) {
+                xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",
+                              ioreq->v.iov[i].iov_base,
+                              ioreq->v.iov[i].iov_len);
+                goto err;
+            }
+            len += ioreq->v.iov[i].iov_len;
+            pos += ioreq->v.iov[i].iov_len;
+        }
+        break;
     default:
-	/* unknown operation (shouldn't happen -- parse catches this) */
-	goto err;
+        /* unknown operation (shouldn't happen -- parse catches this) */
+        goto err;
     }
 
     if (ioreq->postsync)
-	bdrv_flush(blkdev->bs);
+        bdrv_flush(blkdev->bs);
     ioreq->status = BLKIF_RSP_OKAY;
 
     ioreq_unmap(ioreq);
@@ -393,11 +393,11 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
     struct XenBlkDev *blkdev = ioreq->blkdev;
 
     if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1)
-	goto err;
+        goto err;
 
     ioreq->aio_inflight++;
     if (ioreq->presync)
-	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
+        bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
@@ -405,7 +405,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                        qemu_aio_complete, ioreq);
-	break;
+        break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_WRITE_BARRIER:
         ioreq->aio_inflight++;
@@ -414,14 +414,14 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
                         &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                         qemu_aio_complete, ioreq);
-	break;
+        break;
     default:
-	/* unknown operation (shouldn't happen -- parse catches this) */
-	goto err;
+        /* unknown operation (shouldn't happen -- parse catches this) */
+        goto err;
     }
 
     if (ioreq->postsync)
-	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
+        bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
     qemu_aio_complete(ioreq, 0);
 
     return 0;
@@ -446,36 +446,36 @@ static int blk_send_response_one(struct ioreq *ioreq)
     /* Place on the response ring for the relevant domain. */
     switch (blkdev->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
-	dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
-	break;
+        dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
+        break;
     case BLKIF_PROTOCOL_X86_32:
         dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
                                 blkdev->rings.x86_32_part.rsp_prod_pvt);
-	break;
+        break;
     case BLKIF_PROTOCOL_X86_64:
         dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
                                 blkdev->rings.x86_64_part.rsp_prod_pvt);
-	break;
+        break;
     default:
-	dst = NULL;
+        dst = NULL;
     }
     memcpy(dst, &resp, sizeof(resp));
     blkdev->rings.common.rsp_prod_pvt++;
 
     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
     if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
-	/*
-	 * Tail check for pending requests. Allows frontend to avoid
-	 * notifications if requests are already in flight (lower
-	 * overheads and promotes batching).
-	 */
-	RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
+        /*
+         * Tail check for pending requests. Allows frontend to avoid
+         * notifications if requests are already in flight (lower
+         * overheads and promotes batching).
+         */
+        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
     } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
-	have_requests = 1;
+        have_requests = 1;
     }
 
     if (have_requests)
-	blkdev->more_work++;
+        blkdev->more_work++;
     return send_notify;
 }
 
@@ -487,28 +487,28 @@ static void blk_send_response_all(struct XenBlkDev *blkdev)
 
     while (!QLIST_EMPTY(&blkdev->finished)) {
         ioreq = QLIST_FIRST(&blkdev->finished);
-	send_notify += blk_send_response_one(ioreq);
-	ioreq_release(ioreq);
+        send_notify += blk_send_response_one(ioreq);
+        ioreq_release(ioreq);
     }
     if (send_notify)
-	xen_be_send_notify(&blkdev->xendev);
+        xen_be_send_notify(&blkdev->xendev);
 }
 
 static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_IDX rc)
 {
     switch (blkdev->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
-	memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
-	       sizeof(ioreq->req));
-	break;
+        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
+               sizeof(ioreq->req));
+        break;
     case BLKIF_PROTOCOL_X86_32:
         blkif_get_x86_32_req(&ioreq->req,
                              RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
-	break;
+        break;
     case BLKIF_PROTOCOL_X86_64:
         blkif_get_x86_64_req(&ioreq->req,
                              RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
-	break;
+        break;
     }
     return 0;
 }
@@ -589,44 +589,44 @@ static int blk_init(struct XenDevice *xendev)
 
     /* read xenstore entries */
     if (blkdev->params == NULL) {
-	blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
+        blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
         h = strchr(blkdev->params, ':');
-	if (h != NULL) {
-	    blkdev->fileproto = blkdev->params;
-	    blkdev->filename  = h+1;
-	    *h = 0;
-	} else {
-	    blkdev->fileproto = "<unset>";
-	    blkdev->filename  = blkdev->params;
-	}
+        if (h != NULL) {
+            blkdev->fileproto = blkdev->params;
+            blkdev->filename  = h+1;
+            *h = 0;
+        } else {
+            blkdev->fileproto = "<unset>";
+            blkdev->filename  = blkdev->params;
+        }
     }
     if (blkdev->mode == NULL)
-	blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
+        blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
     if (blkdev->type == NULL)
-	blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type");
+        blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type");
     if (blkdev->dev == NULL)
-	blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev");
+        blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev");
     if (blkdev->devtype == NULL)
-	blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type");
+        blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type");
 
     /* do we have all we need? */
     if (blkdev->params == NULL ||
-	blkdev->mode == NULL   ||
-	blkdev->type == NULL   ||
-	blkdev->dev == NULL)
-	return -1;
+        blkdev->mode == NULL   ||
+        blkdev->type == NULL   ||
+        blkdev->dev == NULL)
+        return -1;
 
     /* read-only ? */
     if (strcmp(blkdev->mode, "w") == 0) {
-	qflags = BDRV_O_RDWR;
+        qflags = BDRV_O_RDWR;
     } else {
-	qflags = 0;
-	info  |= VDISK_READONLY;
+        qflags = 0;
+        info  |= VDISK_READONLY;
     }
 
     /* cdrom ? */
     if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom"))
-	info  |= VDISK_CDROM;
+        info  |= VDISK_CDROM;
 
     /* init qemu block driver */
     index = (blkdev->xendev.dev - 202 * 256) / 16;
@@ -643,7 +643,7 @@ static int blk_init(struct XenDevice *xendev)
     } else {
         /* setup via qemu cmdline -> already setup for us */
         xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
-	blkdev->bs = blkdev->dinfo->bdrv;
+        blkdev->bs = blkdev->dinfo->bdrv;
     }
     blkdev->file_blk  = BLOCK_SIZE;
     blkdev->file_size = bdrv_getlength(blkdev->bs);
@@ -651,21 +651,21 @@ static int blk_init(struct XenDevice *xendev)
         xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
                       (int)blkdev->file_size, strerror(-blkdev->file_size),
                       blkdev->bs->drv ? blkdev->bs->drv->format_name : "-");
-	blkdev->file_size = 0;
+        blkdev->file_size = 0;
     }
     have_barriers = blkdev->bs->drv && blkdev->bs->drv->bdrv_flush ? 1 : 0;
 
     xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
-		  " size %" PRId64 " (%" PRId64 " MB)\n",
-		  blkdev->type, blkdev->fileproto, blkdev->filename,
-		  blkdev->file_size, blkdev->file_size >> 20);
+                  " size %" PRId64 " (%" PRId64 " MB)\n",
+                  blkdev->type, blkdev->fileproto, blkdev->filename,
+                  blkdev->file_size, blkdev->file_size >> 20);
 
     /* fill info */
     xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers);
     xenstore_write_be_int(&blkdev->xendev, "info",            info);
     xenstore_write_be_int(&blkdev->xendev, "sector-size",     blkdev->file_blk);
     xenstore_write_be_int(&blkdev->xendev, "sectors",
-			  blkdev->file_size / blkdev->file_blk);
+                          blkdev->file_size / blkdev->file_blk);
     return 0;
 }
 
@@ -674,10 +674,10 @@ static int blk_connect(struct XenDevice *xendev)
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
     if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1)
-	return -1;
+        return -1;
     if (xenstore_read_fe_int(&blkdev->xendev, "event-channel",
                              &blkdev->xendev.remote_port) == -1)
-	return -1;
+        return -1;
 
     blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
     if (blkdev->xendev.protocol) {
@@ -688,42 +688,42 @@ static int blk_connect(struct XenDevice *xendev)
     }
 
     blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev,
-					    blkdev->xendev.dom,
-					    blkdev->ring_ref,
-					    PROT_READ | PROT_WRITE);
+                                            blkdev->xendev.dom,
+                                            blkdev->ring_ref,
+                                            PROT_READ | PROT_WRITE);
     if (!blkdev->sring)
-	return -1;
+        return -1;
     blkdev->cnt_map++;
 
     switch (blkdev->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
     {
-	blkif_sring_t *sring_native = blkdev->sring;
-	BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);
-	break;
+        blkif_sring_t *sring_native = blkdev->sring;
+        BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);
+        break;
     }
     case BLKIF_PROTOCOL_X86_32:
     {
-	blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
 
         BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, XC_PAGE_SIZE);
-	break;
+        break;
     }
     case BLKIF_PROTOCOL_X86_64:
     {
-	blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
 
         BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, XC_PAGE_SIZE);
-	break;
+        break;
     }
     }
 
     xen_be_bind_evtchn(&blkdev->xendev);
 
     xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
-		  "remote port %d, local port %d\n",
-		  blkdev->xendev.protocol, blkdev->ring_ref,
-		  blkdev->xendev.remote_port, blkdev->xendev.local_port);
+                  "remote port %d, local port %d\n",
+                  blkdev->xendev.protocol, blkdev->ring_ref,
+                  blkdev->xendev.remote_port, blkdev->xendev.local_port);
     return 0;
 }
 
@@ -737,14 +737,14 @@ static void blk_disconnect(struct XenDevice *xendev)
             bdrv_close(blkdev->bs);
             bdrv_delete(blkdev->bs);
         }
-	blkdev->bs = NULL;
+        blkdev->bs = NULL;
     }
     xen_be_unbind_evtchn(&blkdev->xendev);
 
     if (blkdev->sring) {
-	xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
-	blkdev->cnt_map--;
-	blkdev->sring = NULL;
+        xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
+        blkdev->cnt_map--;
+        blkdev->sring = NULL;
     }
 }
 
@@ -754,10 +754,10 @@ static int blk_free(struct XenDevice *xendev)
     struct ioreq *ioreq;
 
     while (!QLIST_EMPTY(&blkdev->freelist)) {
-	ioreq = QLIST_FIRST(&blkdev->freelist);
+        ioreq = QLIST_FIRST(&blkdev->freelist);
         QLIST_REMOVE(ioreq, list);
         qemu_iovec_destroy(&ioreq->v);
-	qemu_free(ioreq);
+        qemu_free(ioreq);
     }
 
     qemu_free(blkdev->params);
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 08055b8..8fcf856 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -75,19 +75,19 @@ static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, i
 
 #if 0
     if (txp->flags & NETTXF_extra_info)
-	RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
+        RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
 #endif
 
     netdev->tx_ring.rsp_prod_pvt = ++i;
     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
     if (notify)
-	xen_be_send_notify(&netdev->xendev);
+        xen_be_send_notify(&netdev->xendev);
 
     if (i == netdev->tx_ring.req_cons) {
-	int more_to_do;
-	RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
-	if (more_to_do)
-	    netdev->tx_work++;
+        int more_to_do;
+        RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
+        if (more_to_do)
+            netdev->tx_work++;
     }
 }
 
@@ -101,10 +101,10 @@ static void net_tx_error(struct XenNetDev *netdev, netif_tx_request_t *txp, RING
     RING_IDX cons = netdev->tx_ring.req_cons;
 
     do {
-	make_tx_response(netif, txp, NETIF_RSP_ERROR);
-	if (cons >= end)
-	    break;
-	txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
+        make_tx_response(netif, txp, NETIF_RSP_ERROR);
+        if (cons >= end)
+            break;
+        txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
     } while (1);
     netdev->tx_ring.req_cons = cons;
     netif_schedule_work(netif);
@@ -122,75 +122,75 @@ static void net_tx_packets(struct XenNetDev *netdev)
     void *tmpbuf = NULL;
 
     for (;;) {
-	rc = netdev->tx_ring.req_cons;
-	rp = netdev->tx_ring.sring->req_prod;
-	xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
+        rc = netdev->tx_ring.req_cons;
+        rp = netdev->tx_ring.sring->req_prod;
+        xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-	while ((rc != rp)) {
-	    if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc))
-		break;
-	    memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
-	    netdev->tx_ring.req_cons = ++rc;
+        while ((rc != rp)) {
+            if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc))
+                break;
+            memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
+            netdev->tx_ring.req_cons = ++rc;
 
 #if 1
-	    /* should not happen in theory, we don't announce the *
-	     * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
-	    if (txreq.flags & NETTXF_extra_info) {
-		xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-	    if (txreq.flags & NETTXF_more_data) {
-		xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
+            /* should not happen in theory, we don't announce the *
+             * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
+            if (txreq.flags & NETTXF_extra_info) {
+                xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+            if (txreq.flags & NETTXF_more_data) {
+                xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
 #endif
 
-	    if (txreq.size < 14) {
-		xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-
-	    if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
-		xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-
-	    xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
-			  txreq.gref, txreq.offset, txreq.size, txreq.flags,
-			  (txreq.flags & NETTXF_csum_blank)     ? " csum_blank"     : "",
-			  (txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
-			  (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);
-	    if (page == NULL) {
-		xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
+            if (txreq.size < 14) {
+                xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+
+            if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
+                xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+
+            xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
+                          txreq.gref, txreq.offset, txreq.size, txreq.flags,
+                          (txreq.flags & NETTXF_csum_blank)     ? " csum_blank"     : "",
+                          (txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
+                          (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);
+            if (page == NULL) {
+                xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
                               txreq.gref);
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-	    if (txreq.flags & NETTXF_csum_blank) {
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+            if (txreq.flags & NETTXF_csum_blank) {
                 /* have read-only mapping -> can't fill checksum in-place */
                 if (!tmpbuf)
                     tmpbuf = qemu_malloc(XC_PAGE_SIZE);
                 memcpy(tmpbuf, page + txreq.offset, txreq.size);
-		net_checksum_calculate(tmpbuf, txreq.size);
+                net_checksum_calculate(tmpbuf, txreq.size);
                 qemu_send_packet(&netdev->nic->nc, tmpbuf, txreq.size);
             } else {
                 qemu_send_packet(&netdev->nic->nc, page + txreq.offset, txreq.size);
             }
-	    xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
-	    net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
-	}
-	if (!netdev->tx_work)
-	    break;
-	netdev->tx_work = 0;
+            xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
+            net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
+        }
+        if (!netdev->tx_work)
+            break;
+        netdev->tx_work = 0;
     }
     qemu_free(tmpbuf);
 }
@@ -198,9 +198,9 @@ static void net_tx_packets(struct XenNetDev *netdev)
 /* ------------------------------------------------------------- */
 
 static void net_rx_response(struct XenNetDev *netdev,
-			    netif_rx_request_t *req, int8_t st,
-			    uint16_t offset, uint16_t size,
-			    uint16_t flags)
+                            netif_rx_request_t *req, int8_t st,
+                            uint16_t offset, uint16_t size,
+                            uint16_t flags)
 {
     RING_IDX i = netdev->rx_ring.rsp_prod_pvt;
     netif_rx_response_t *resp;
@@ -212,15 +212,15 @@ static void net_rx_response(struct XenNetDev *netdev,
     resp->id         = req->id;
     resp->status     = (int16_t)size;
     if (st < 0)
-	resp->status = (int16_t)st;
+        resp->status = (int16_t)st;
 
     xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n",
-		  i, resp->status, resp->flags);
+                  i, resp->status, resp->flags);
 
     netdev->rx_ring.rsp_prod_pvt = ++i;
     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
     if (notify)
-	xen_be_send_notify(&netdev->xendev);
+        xen_be_send_notify(&netdev->xendev);
 }
 
 #define NET_IP_ALIGN 2
@@ -231,16 +231,16 @@ static int net_rx_ok(VLANClientState *nc)
     RING_IDX rc, rp;
 
     if (netdev->xendev.be_state != XenbusStateConnected)
-	return 0;
+        return 0;
 
     rc = netdev->rx_ring.req_cons;
     rp = netdev->rx_ring.sring->req_prod;
     xen_rmb();
 
     if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
-	xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
-		      __FUNCTION__, rc, rp);
-	return 0;
+        xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
+                      __FUNCTION__, rc, rp);
+        return 0;
     }
     return 1;
 }
@@ -253,33 +253,33 @@ static ssize_t net_rx_packet(VLANClientState *nc, const uint8_t *buf, size_t siz
     void *page;
 
     if (netdev->xendev.be_state != XenbusStateConnected)
-	return -1;
+        return -1;
 
     rc = netdev->rx_ring.req_cons;
     rp = netdev->rx_ring.sring->req_prod;
     xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
     if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
-	xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
-	return -1;
+        xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
+        return -1;
     }
     if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
-	xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
-		      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
-	return -1;
+        xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
+                      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
+        return -1;
     }
 
     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);
+                                   netdev->xendev.dom,
+                                   rxreq.gref, PROT_WRITE);
     if (page == NULL) {
-	xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
+        xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
                       rxreq.gref);
-	net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
-	return -1;
+        net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
+        return -1;
     }
     memcpy(page + NET_IP_ALIGN, buf, size);
     xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
@@ -303,11 +303,11 @@ static int net_init(struct XenDevice *xendev)
 
     /* read xenstore entries */
     if (netdev->mac == NULL)
-	netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac");
+        netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac");
 
     /* do we have all we need? */
     if (netdev->mac == NULL)
-	return -1;
+        return -1;
 
     if (net_parse_macaddr(netdev->conf.macaddr.a, netdev->mac) < 0)
         return -1;
@@ -334,41 +334,41 @@ static int net_connect(struct XenDevice *xendev)
     int rx_copy;
 
     if (xenstore_read_fe_int(&netdev->xendev, "tx-ring-ref",
-				   &netdev->tx_ring_ref) == -1)
-	return -1;
+                             &netdev->tx_ring_ref) == -1)
+        return -1;
     if (xenstore_read_fe_int(&netdev->xendev, "rx-ring-ref",
-				   &netdev->rx_ring_ref) == -1)
-	return 1;
+                             &netdev->rx_ring_ref) == -1)
+        return 1;
     if (xenstore_read_fe_int(&netdev->xendev, "event-channel",
-				   &netdev->xendev.remote_port) == -1)
-	return -1;
+                             &netdev->xendev.remote_port) == -1)
+        return -1;
 
     if (xenstore_read_fe_int(&netdev->xendev, "request-rx-copy", &rx_copy) == -1)
-	rx_copy = 0;
+        rx_copy = 0;
     if (rx_copy == 0) {
-	xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
-	return -1;
+        xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
+        return -1;
     }
 
     netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
-					  netdev->xendev.dom,
-					  netdev->tx_ring_ref,
-					  PROT_READ | PROT_WRITE);
+                                          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->xendev.dom,
+                                          netdev->rx_ring_ref,
+                                          PROT_READ | PROT_WRITE);
     if (!netdev->txs || !netdev->rxs)
-	return -1;
+        return -1;
     BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XC_PAGE_SIZE);
     BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XC_PAGE_SIZE);
 
     xen_be_bind_evtchn(&netdev->xendev);
 
     xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
-		  "remote port %d, local port %d\n",
-		  netdev->tx_ring_ref, netdev->rx_ring_ref,
-		  netdev->xendev.remote_port, netdev->xendev.local_port);
+                  "remote port %d, local port %d\n",
+                  netdev->tx_ring_ref, netdev->rx_ring_ref,
+                  netdev->xendev.remote_port, netdev->xendev.local_port);
 
     net_tx_packets(netdev);
     return 0;
@@ -381,12 +381,12 @@ 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);
-	netdev->txs = NULL;
+        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
+        netdev->txs = NULL;
     }
     if (netdev->rxs) {
-	xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
-	netdev->rxs = NULL;
+        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
+        netdev->rxs = NULL;
     }
     if (netdev->nic) {
         qemu_del_vlan_client(&netdev->nic->nc);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 01/15] xen: Replace some tab-indents with spaces (clean-up).
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 hw/xen_backend.c |  308 +++++++++++++++++++++---------------------
 hw/xen_disk.c    |  394 +++++++++++++++++++++++++++---------------------------
 hw/xen_nic.c     |  222 +++++++++++++++---------------
 3 files changed, 462 insertions(+), 462 deletions(-)

diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index a2e408f..860b038 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -59,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val)
 
     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
     if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
-	return -1;
+        return -1;
     return 0;
 }
 
@@ -95,7 +95,7 @@ int xenstore_read_int(const char *base, const char *node, int *ival)
 
     val = xenstore_read_str(base, node);
     if (val && 1 == sscanf(val, "%d", ival))
-	rc = 0;
+        rc = 0;
     qemu_free(val);
     return rc;
 }
@@ -134,16 +134,16 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
 
 const char *xenbus_strstate(enum xenbus_state state)
 {
-	static const char *const name[] = {
-		[ XenbusStateUnknown      ] = "Unknown",
-		[ XenbusStateInitialising ] = "Initialising",
-		[ XenbusStateInitWait     ] = "InitWait",
-		[ XenbusStateInitialised  ] = "Initialised",
-		[ XenbusStateConnected    ] = "Connected",
-		[ XenbusStateClosing      ] = "Closing",
-		[ XenbusStateClosed	  ] = "Closed",
-	};
-	return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
+    static const char *const name[] = {
+        [ XenbusStateUnknown      ] = "Unknown",
+        [ XenbusStateInitialising ] = "Initialising",
+        [ XenbusStateInitWait     ] = "InitWait",
+        [ XenbusStateInitialised  ] = "Initialised",
+        [ XenbusStateConnected    ] = "Connected",
+        [ XenbusStateClosing      ] = "Closing",
+        [ XenbusStateClosed       ] = "Closed",
+    };
+    return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
 }
 
 int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
@@ -152,9 +152,9 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
 
     rc = xenstore_write_be_int(xendev, "state", state);
     if (rc < 0)
-	return rc;
+        return rc;
     xen_be_printf(xendev, 1, "backend state: %s -> %s\n",
-		  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
+                  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
     xendev->be_state = state;
     return 0;
 }
@@ -166,13 +166,13 @@ struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
     struct XenDevice *xendev;
 
     QTAILQ_FOREACH(xendev, &xendevs, next) {
-	if (xendev->dom != dom)
-	    continue;
-	if (xendev->dev != dev)
-	    continue;
-	if (strcmp(xendev->type, type) != 0)
-	    continue;
-	return xendev;
+        if (xendev->dom != dom)
+            continue;
+        if (xendev->dev != dev)
+            continue;
+        if (strcmp(xendev->type, type) != 0)
+            continue;
+        return xendev;
     }
     return NULL;
 }
@@ -188,7 +188,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 
     xendev = xen_be_find_xendev(type, dom, dev);
     if (xendev)
-	return xendev;
+        return xendev;
 
     /* init new xendev */
     xendev = qemu_mallocz(ops->size);
@@ -199,9 +199,9 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 
     dom0 = xs_get_domain_path(xenstore, 0);
     snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
-	     dom0, xendev->type, xendev->dom, xendev->dev);
+             dom0, xendev->type, xendev->dom, xendev->dev);
     snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
-	     xendev->type, xendev->dev);
+             xendev->type, xendev->dev);
     free(dom0);
 
     xendev->debug      = debug;
@@ -209,28 +209,28 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 
     xendev->evtchndev = xc_evtchn_open();
     if (xendev->evtchndev < 0) {
-	xen_be_printf(NULL, 0, "can't open evtchn device\n");
-	qemu_free(xendev);
-	return NULL;
+        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);
 
     if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
-	xendev->gnttabdev = xc_gnttab_open();
-	if (xendev->gnttabdev < 0) {
-	    xen_be_printf(NULL, 0, "can't open gnttab device\n");
-	    xc_evtchn_close(xendev->evtchndev);
-	    qemu_free(xendev);
-	    return NULL;
-	}
+        xendev->gnttabdev = xc_gnttab_open();
+        if (xendev->gnttabdev < 0) {
+            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 = -1;
     }
 
     QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
 
     if (xendev->ops->alloc)
-	xendev->ops->alloc(xendev);
+        xendev->ops->alloc(xendev);
 
     return xendev;
 }
@@ -251,28 +251,28 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
         xendev = xnext;
         xnext = xendev->next.tqe_next;
 
-	if (xendev->dom != dom)
-	    continue;
-	if (xendev->dev != dev && dev != -1)
-	    continue;
+        if (xendev->dom != dom)
+            continue;
+        if (xendev->dev != dev && dev != -1)
+            continue;
 
-	if (xendev->ops->free)
-	    xendev->ops->free(xendev);
+        if (xendev->ops->free)
+            xendev->ops->free(xendev);
 
-	if (xendev->fe) {
-	    char token[XEN_BUFSIZE];
-	    snprintf(token, sizeof(token), "fe:%p", xendev);
-	    xs_unwatch(xenstore, xendev->fe, token);
-	    qemu_free(xendev->fe);
-	}
+        if (xendev->fe) {
+            char token[XEN_BUFSIZE];
+            snprintf(token, sizeof(token), "fe:%p", xendev);
+            xs_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 >= 0)
+            xc_evtchn_close(xendev->evtchndev);
+        if (xendev->gnttabdev >= 0)
+            xc_gnttab_close(xendev->gnttabdev);
 
-	QTAILQ_REMOVE(&xendevs, xendev, next);
-	qemu_free(xendev);
+        QTAILQ_REMOVE(&xendevs, xendev, next);
+        qemu_free(xendev);
     }
     return NULL;
 }
@@ -285,14 +285,14 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
 static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
 {
     if (node == NULL  ||  strcmp(node, "online") == 0) {
-	if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1)
-	    xendev->online = 0;
+        if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1)
+            xendev->online = 0;
     }
 
     if (node) {
-	xen_be_printf(xendev, 2, "backend update: %s\n", node);
-	if (xendev->ops->backend_changed)
-	    xendev->ops->backend_changed(xendev, node);
+        xen_be_printf(xendev, 2, "backend update: %s\n", node);
+        if (xendev->ops->backend_changed)
+            xendev->ops->backend_changed(xendev, node);
     }
 }
 
@@ -301,25 +301,25 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
     int fe_state;
 
     if (node == NULL  ||  strcmp(node, "state") == 0) {
-	if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1)
-	    fe_state = XenbusStateUnknown;
-	if (xendev->fe_state != fe_state)
-	    xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
-			  xenbus_strstate(xendev->fe_state),
-			  xenbus_strstate(fe_state));
-	xendev->fe_state = fe_state;
+        if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1)
+            fe_state = XenbusStateUnknown;
+        if (xendev->fe_state != fe_state)
+            xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
+                          xenbus_strstate(xendev->fe_state),
+                          xenbus_strstate(fe_state));
+        xendev->fe_state = fe_state;
     }
     if (node == NULL  ||  strcmp(node, "protocol") == 0) {
-	qemu_free(xendev->protocol);
-	xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
-	if (xendev->protocol)
-	    xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
+        qemu_free(xendev->protocol);
+        xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
+        if (xendev->protocol)
+            xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
     }
 
     if (node) {
-	xen_be_printf(xendev, 2, "frontend update: %s\n", node);
-	if (xendev->ops->frontend_changed)
-	    xendev->ops->frontend_changed(xendev, node);
+        xen_be_printf(xendev, 2, "frontend update: %s\n", node);
+        if (xendev->ops->frontend_changed)
+            xendev->ops->frontend_changed(xendev, node);
     }
 }
 
@@ -340,28 +340,28 @@ static int xen_be_try_setup(struct XenDevice *xendev)
     int be_state;
 
     if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
-	xen_be_printf(xendev, 0, "reading backend state failed\n");
-	return -1;
+        xen_be_printf(xendev, 0, "reading backend state failed\n");
+        return -1;
     }
 
     if (be_state != XenbusStateInitialising) {
-	xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
-		      xenbus_strstate(be_state));
-	return -1;
+        xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
+                      xenbus_strstate(be_state));
+        return -1;
     }
 
     xendev->fe = xenstore_read_be_str(xendev, "frontend");
     if (xendev->fe == NULL) {
-	xen_be_printf(xendev, 0, "reading frontend path failed\n");
-	return -1;
+        xen_be_printf(xendev, 0, "reading frontend path failed\n");
+        return -1;
     }
 
     /* setup frontend watch */
     snprintf(token, sizeof(token), "fe:%p", xendev);
     if (!xs_watch(xenstore, xendev->fe, token)) {
-	xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
-		      xendev->fe);
-	return -1;
+        xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
+                      xendev->fe);
+        return -1;
     }
     xen_be_set_state(xendev, XenbusStateInitialising);
 
@@ -383,15 +383,15 @@ static int xen_be_try_init(struct XenDevice *xendev)
     int rc = 0;
 
     if (!xendev->online) {
-	xen_be_printf(xendev, 1, "not online\n");
-	return -1;
+        xen_be_printf(xendev, 1, "not online\n");
+        return -1;
     }
 
     if (xendev->ops->init)
-	rc = xendev->ops->init(xendev);
+        rc = xendev->ops->init(xendev);
     if (rc != 0) {
-	xen_be_printf(xendev, 1, "init() failed\n");
-	return rc;
+        xen_be_printf(xendev, 1, "init() failed\n");
+        return rc;
     }
 
     xenstore_write_be_str(xendev, "hotplug-status", "connected");
@@ -411,20 +411,20 @@ static int xen_be_try_connect(struct XenDevice *xendev)
     int rc = 0;
 
     if (xendev->fe_state != XenbusStateInitialised  &&
-	xendev->fe_state != XenbusStateConnected) {
-	if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
-	    xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
-	} else {
-	    xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
-	    return -1;
-	}
+        xendev->fe_state != XenbusStateConnected) {
+        if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
+            xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
+        } else {
+            xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
+            return -1;
+        }
     }
 
     if (xendev->ops->connect)
-	rc = xendev->ops->connect(xendev);
+        rc = xendev->ops->connect(xendev);
     if (rc != 0) {
-	xen_be_printf(xendev, 0, "connect() failed\n");
-	return rc;
+        xen_be_printf(xendev, 0, "connect() failed\n");
+        return rc;
     }
 
     xen_be_set_state(xendev, XenbusStateConnected);
@@ -441,7 +441,7 @@ static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
     if (xendev->be_state != XenbusStateClosing &&
         xendev->be_state != XenbusStateClosed  &&
         xendev->ops->disconnect)
-	xendev->ops->disconnect(xendev);
+        xendev->ops->disconnect(xendev);
     if (xendev->be_state != state)
         xen_be_set_state(xendev, state);
 }
@@ -468,31 +468,31 @@ void xen_be_check_state(struct XenDevice *xendev)
 
     /* frontend may request shutdown from almost anywhere */
     if (xendev->fe_state == XenbusStateClosing ||
-	xendev->fe_state == XenbusStateClosed) {
-	xen_be_disconnect(xendev, xendev->fe_state);
-	return;
+        xendev->fe_state == XenbusStateClosed) {
+        xen_be_disconnect(xendev, xendev->fe_state);
+        return;
     }
 
     /* check for possible backend state transitions */
     for (;;) {
-	switch (xendev->be_state) {
-	case XenbusStateUnknown:
-	    rc = xen_be_try_setup(xendev);
-	    break;
-	case XenbusStateInitialising:
-	    rc = xen_be_try_init(xendev);
-	    break;
-	case XenbusStateInitWait:
-	    rc = xen_be_try_connect(xendev);
-	    break;
+        switch (xendev->be_state) {
+        case XenbusStateUnknown:
+            rc = xen_be_try_setup(xendev);
+            break;
+        case XenbusStateInitialising:
+            rc = xen_be_try_init(xendev);
+            break;
+        case XenbusStateInitWait:
+            rc = xen_be_try_connect(xendev);
+            break;
         case XenbusStateClosed:
             rc = xen_be_try_reset(xendev);
             break;
-	default:
-	    rc = -1;
-	}
-	if (rc != 0)
-	    break;
+        default:
+            rc = -1;
+        }
+        if (rc != 0)
+            break;
     }
 }
 
@@ -511,26 +511,26 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
     snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
     free(dom0);
     if (!xs_watch(xenstore, path, token)) {
-	xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
-	return -1;
+        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);
     if (!dev)
-	return 0;
+        return 0;
     for (j = 0; j < cdev; j++) {
-	xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
-	if (xendev == NULL)
-	    continue;
-	xen_be_check_state(xendev);
+        xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
+        if (xendev == NULL)
+            continue;
+        xen_be_check_state(xendev);
     }
     free(dev);
     return 0;
 }
 
 static void xenstore_update_be(char *watch, char *type, int dom,
-			       struct XenDevOps *ops)
+                               struct XenDevOps *ops)
 {
     struct XenDevice *xendev;
     char path[XEN_BUFSIZE], *dom0;
@@ -540,24 +540,24 @@ static void xenstore_update_be(char *watch, char *type, int dom,
     len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
     free(dom0);
     if (strncmp(path, watch, len) != 0)
-	return;
+        return;
     if (sscanf(watch+len, "/%u/%255s", &dev, path) != 2) {
-	strcpy(path, "");
-	if (sscanf(watch+len, "/%u", &dev) != 1)
-	    dev = -1;
+        strcpy(path, "");
+        if (sscanf(watch+len, "/%u", &dev) != 1)
+            dev = -1;
     }
     if (dev == -1)
-	return;
+        return;
 
     if (0) {
-	/* FIXME: detect devices being deleted from xenstore ... */
-	xen_be_del_xendev(dom, dev);
+        /* FIXME: detect devices being deleted from xenstore ... */
+        xen_be_del_xendev(dom, dev);
     }
 
     xendev = xen_be_get_xendev(type, dom, dev, ops);
     if (xendev != NULL) {
-	xen_be_backend_changed(xendev, path);
-	xen_be_check_state(xendev);
+        xen_be_backend_changed(xendev, path);
+        xen_be_check_state(xendev);
     }
 }
 
@@ -568,9 +568,9 @@ static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
 
     len = strlen(xendev->fe);
     if (strncmp(xendev->fe, watch, len) != 0)
-	return;
+        return;
     if (watch[len] != '/')
-	return;
+        return;
     node = watch + len + 1;
 
     xen_be_frontend_changed(xendev, node);
@@ -585,13 +585,13 @@ static void xenstore_update(void *unused)
 
     vec = xs_read_watch(xenstore, &count);
     if (vec == NULL)
-	goto cleanup;
+        goto cleanup;
 
     if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
                &type, &dom, &ops) == 3)
-	xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
+        xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
     if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1)
-	xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
+        xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
 
 cleanup:
     free(vec);
@@ -604,14 +604,14 @@ static void xen_be_evtchn_event(void *opaque)
 
     port = xc_evtchn_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;
+        xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n",
+                      port, xendev->local_port);
+        return;
     }
     xc_evtchn_unmask(xendev->evtchndev, port);
 
     if (xendev->ops->event)
-	xendev->ops->event(xendev);
+        xendev->ops->event(xendev);
 }
 
 /* -------------------------------------------------------------------- */
@@ -620,17 +620,17 @@ int xen_be_init(void)
 {
     xenstore = xs_daemon_open();
     if (!xenstore) {
-	xen_be_printf(NULL, 0, "can't connect to xenstored\n");
-	return -1;
+        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)
-	goto err;
+        goto err;
 
     xen_xc = xc_interface_open();
     if (xen_xc == -1) {
-	xen_be_printf(NULL, 0, "can't open xen interface\n");
-	goto err;
+        xen_be_printf(NULL, 0, "can't open xen interface\n");
+        goto err;
     }
     return 0;
 
@@ -650,23 +650,23 @@ int xen_be_register(const char *type, struct XenDevOps *ops)
 int xen_be_bind_evtchn(struct XenDevice *xendev)
 {
     if (xendev->local_port != -1)
-	return 0;
+        return 0;
     xendev->local_port = xc_evtchn_bind_interdomain
-	(xendev->evtchndev, xendev->dom, xendev->remote_port);
+        (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, 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),
-			xen_be_evtchn_event, NULL, xendev);
+                        xen_be_evtchn_event, NULL, xendev);
     return 0;
 }
 
 void xen_be_unbind_evtchn(struct XenDevice *xendev)
 {
     if (xendev->local_port == -1)
-	return;
+        return;
     qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
     xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
     xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index ed9e5eb..7f6aaca 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -120,17 +120,17 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
     struct ioreq *ioreq = NULL;
 
     if (QLIST_EMPTY(&blkdev->freelist)) {
-	if (blkdev->requests_total >= max_requests)
-	    goto out;
-	/* allocate new struct */
-	ioreq = qemu_mallocz(sizeof(*ioreq));
-	ioreq->blkdev = blkdev;
-	blkdev->requests_total++;
+        if (blkdev->requests_total >= max_requests)
+            goto out;
+        /* allocate new struct */
+        ioreq = qemu_mallocz(sizeof(*ioreq));
+        ioreq->blkdev = blkdev;
+        blkdev->requests_total++;
         qemu_iovec_init(&ioreq->v, BLKIF_MAX_SEGMENTS_PER_REQUEST);
     } else {
-	/* get one from freelist */
-	ioreq = QLIST_FIRST(&blkdev->freelist);
-	QLIST_REMOVE(ioreq, list);
+        /* get one from freelist */
+        ioreq = QLIST_FIRST(&blkdev->freelist);
+        QLIST_REMOVE(ioreq, list);
         qemu_iovec_reset(&ioreq->v);
     }
     QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
@@ -173,30 +173,30 @@ static int ioreq_parse(struct ioreq *ioreq)
     int i;
 
     xen_be_printf(&blkdev->xendev, 3,
-		  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
-		  ioreq->req.operation, ioreq->req.nr_segments,
-		  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
+                  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
+                  ioreq->req.operation, ioreq->req.nr_segments,
+                  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
-	ioreq->prot = PROT_WRITE; /* to memory */
-	break;
+        ioreq->prot = PROT_WRITE; /* to memory */
+        break;
     case BLKIF_OP_WRITE_BARRIER:
         if (!ioreq->req.nr_segments) {
             ioreq->presync = 1;
             return 0;
         }
-	if (!syncwrite)
-	    ioreq->presync = ioreq->postsync = 1;
-	/* fall through */
+        if (!syncwrite)
+            ioreq->presync = ioreq->postsync = 1;
+        /* fall through */
     case BLKIF_OP_WRITE:
-	ioreq->prot = PROT_READ; /* from memory */
-	if (syncwrite)
-	    ioreq->postsync = 1;
-	break;
+        ioreq->prot = PROT_READ; /* from memory */
+        if (syncwrite)
+            ioreq->postsync = 1;
+        break;
     default:
-	xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
-		      ioreq->req.operation);
-	goto err;
+        xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
+                      ioreq->req.operation);
+        goto err;
     };
 
     if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
@@ -206,29 +206,29 @@ static int ioreq_parse(struct ioreq *ioreq)
 
     ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
     for (i = 0; i < ioreq->req.nr_segments; i++) {
-	if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-	    xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
-	    goto err;
-	}
-	if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-	    xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n");
-	    goto err;
-	}
-	if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-	    xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
-	    goto err;
-	}
-
-	ioreq->domids[i] = blkdev->xendev.dom;
-	ioreq->refs[i]   = ioreq->req.seg[i].gref;
-
-	mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
-	len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
+        if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+            xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
+            xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
+            xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
+            goto err;
+        }
+
+        ioreq->domids[i] = blkdev->xendev.dom;
+        ioreq->refs[i]   = ioreq->req.seg[i].gref;
+
+        mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
+        len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
         qemu_iovec_add(&ioreq->v, (void*)mem, len);
     }
     if (ioreq->start + ioreq->v.size > blkdev->file_size) {
-	xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
-	goto err;
+        xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
+        goto err;
     }
     return 0;
 
@@ -245,23 +245,23 @@ static void ioreq_unmap(struct ioreq *ioreq)
     if (ioreq->v.niov == 0)
         return;
     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",
-			  strerror(errno));
-	ioreq->blkdev->cnt_map -= ioreq->v.niov;
-	ioreq->pages = NULL;
+        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",
+                          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",
-			      strerror(errno));
-	    ioreq->blkdev->cnt_map--;
-	    ioreq->page[i] = NULL;
-	}
+        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",
+                              strerror(errno));
+            ioreq->blkdev->cnt_map--;
+            ioreq->page[i] = NULL;
+        }
     }
 }
 
@@ -273,32 +273,32 @@ static int ioreq_map(struct ioreq *ioreq)
     if (ioreq->v.niov == 0)
         return 0;
     if (batch_maps) {
-	ioreq->pages = xc_gnttab_map_grant_refs
-	    (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
-	if (ioreq->pages == NULL) {
-	    xen_be_printf(&ioreq->blkdev->xendev, 0,
-			  "can't map %d grant refs (%s, %d maps)\n",
-			  ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
-	    return -1;
-	}
-	for (i = 0; i < ioreq->v.niov; i++)
-	    ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
-		(uintptr_t)ioreq->v.iov[i].iov_base;
-	ioreq->blkdev->cnt_map += ioreq->v.niov;
+        ioreq->pages = xc_gnttab_map_grant_refs
+            (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
+        if (ioreq->pages == NULL) {
+            xen_be_printf(&ioreq->blkdev->xendev, 0,
+                          "can't map %d grant refs (%s, %d maps)\n",
+                          ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
+            return -1;
+        }
+        for (i = 0; i < ioreq->v.niov; i++)
+            ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
+                (uintptr_t)ioreq->v.iov[i].iov_base;
+        ioreq->blkdev->cnt_map += ioreq->v.niov;
     } else  {
-	for (i = 0; i < ioreq->v.niov; i++) {
-	    ioreq->page[i] = xc_gnttab_map_grant_ref
-		(gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
-	    if (ioreq->page[i] == NULL) {
-		xen_be_printf(&ioreq->blkdev->xendev, 0,
-			      "can't map grant ref %d (%s, %d maps)\n",
-			      ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
-		ioreq_unmap(ioreq);
-		return -1;
-	    }
-	    ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
-	    ioreq->blkdev->cnt_map++;
-	}
+        for (i = 0; i < ioreq->v.niov; i++) {
+            ioreq->page[i] = xc_gnttab_map_grant_ref
+                (gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
+            if (ioreq->page[i] == NULL) {
+                xen_be_printf(&ioreq->blkdev->xendev, 0,
+                              "can't map grant ref %d (%s, %d maps)\n",
+                              ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
+                ioreq_unmap(ioreq);
+                return -1;
+            }
+            ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
+            ioreq->blkdev->cnt_map++;
+        }
     }
     return 0;
 }
@@ -310,53 +310,53 @@ static int ioreq_runio_qemu_sync(struct ioreq *ioreq)
     off_t pos;
 
     if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1)
-	goto err;
+        goto err;
     if (ioreq->presync)
-	bdrv_flush(blkdev->bs);
+        bdrv_flush(blkdev->bs);
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
-	pos = ioreq->start;
-	for (i = 0; i < ioreq->v.niov; i++) {
-	    rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,
-			   ioreq->v.iov[i].iov_base,
-			   ioreq->v.iov[i].iov_len / BLOCK_SIZE);
-	    if (rc != 0) {
-		xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",
-			      ioreq->v.iov[i].iov_base,
-			      ioreq->v.iov[i].iov_len);
-		goto err;
-	    }
-	    len += ioreq->v.iov[i].iov_len;
-	    pos += ioreq->v.iov[i].iov_len;
-	}
-	break;
+        pos = ioreq->start;
+        for (i = 0; i < ioreq->v.niov; i++) {
+            rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,
+                           ioreq->v.iov[i].iov_base,
+                           ioreq->v.iov[i].iov_len / BLOCK_SIZE);
+            if (rc != 0) {
+                xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",
+                              ioreq->v.iov[i].iov_base,
+                              ioreq->v.iov[i].iov_len);
+                goto err;
+            }
+            len += ioreq->v.iov[i].iov_len;
+            pos += ioreq->v.iov[i].iov_len;
+        }
+        break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_WRITE_BARRIER:
         if (!ioreq->req.nr_segments)
             break;
-	pos = ioreq->start;
-	for (i = 0; i < ioreq->v.niov; i++) {
-	    rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,
-			    ioreq->v.iov[i].iov_base,
-			    ioreq->v.iov[i].iov_len / BLOCK_SIZE);
-	    if (rc != 0) {
-		xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",
-			      ioreq->v.iov[i].iov_base,
-			      ioreq->v.iov[i].iov_len);
-		goto err;
-	    }
-	    len += ioreq->v.iov[i].iov_len;
-	    pos += ioreq->v.iov[i].iov_len;
-	}
-	break;
+        pos = ioreq->start;
+        for (i = 0; i < ioreq->v.niov; i++) {
+            rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,
+                            ioreq->v.iov[i].iov_base,
+                            ioreq->v.iov[i].iov_len / BLOCK_SIZE);
+            if (rc != 0) {
+                xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",
+                              ioreq->v.iov[i].iov_base,
+                              ioreq->v.iov[i].iov_len);
+                goto err;
+            }
+            len += ioreq->v.iov[i].iov_len;
+            pos += ioreq->v.iov[i].iov_len;
+        }
+        break;
     default:
-	/* unknown operation (shouldn't happen -- parse catches this) */
-	goto err;
+        /* unknown operation (shouldn't happen -- parse catches this) */
+        goto err;
     }
 
     if (ioreq->postsync)
-	bdrv_flush(blkdev->bs);
+        bdrv_flush(blkdev->bs);
     ioreq->status = BLKIF_RSP_OKAY;
 
     ioreq_unmap(ioreq);
@@ -393,11 +393,11 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
     struct XenBlkDev *blkdev = ioreq->blkdev;
 
     if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1)
-	goto err;
+        goto err;
 
     ioreq->aio_inflight++;
     if (ioreq->presync)
-	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
+        bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
@@ -405,7 +405,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                        qemu_aio_complete, ioreq);
-	break;
+        break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_WRITE_BARRIER:
         ioreq->aio_inflight++;
@@ -414,14 +414,14 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
                         &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                         qemu_aio_complete, ioreq);
-	break;
+        break;
     default:
-	/* unknown operation (shouldn't happen -- parse catches this) */
-	goto err;
+        /* unknown operation (shouldn't happen -- parse catches this) */
+        goto err;
     }
 
     if (ioreq->postsync)
-	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
+        bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
     qemu_aio_complete(ioreq, 0);
 
     return 0;
@@ -446,36 +446,36 @@ static int blk_send_response_one(struct ioreq *ioreq)
     /* Place on the response ring for the relevant domain. */
     switch (blkdev->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
-	dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
-	break;
+        dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
+        break;
     case BLKIF_PROTOCOL_X86_32:
         dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
                                 blkdev->rings.x86_32_part.rsp_prod_pvt);
-	break;
+        break;
     case BLKIF_PROTOCOL_X86_64:
         dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
                                 blkdev->rings.x86_64_part.rsp_prod_pvt);
-	break;
+        break;
     default:
-	dst = NULL;
+        dst = NULL;
     }
     memcpy(dst, &resp, sizeof(resp));
     blkdev->rings.common.rsp_prod_pvt++;
 
     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
     if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
-	/*
-	 * Tail check for pending requests. Allows frontend to avoid
-	 * notifications if requests are already in flight (lower
-	 * overheads and promotes batching).
-	 */
-	RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
+        /*
+         * Tail check for pending requests. Allows frontend to avoid
+         * notifications if requests are already in flight (lower
+         * overheads and promotes batching).
+         */
+        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
     } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
-	have_requests = 1;
+        have_requests = 1;
     }
 
     if (have_requests)
-	blkdev->more_work++;
+        blkdev->more_work++;
     return send_notify;
 }
 
@@ -487,28 +487,28 @@ static void blk_send_response_all(struct XenBlkDev *blkdev)
 
     while (!QLIST_EMPTY(&blkdev->finished)) {
         ioreq = QLIST_FIRST(&blkdev->finished);
-	send_notify += blk_send_response_one(ioreq);
-	ioreq_release(ioreq);
+        send_notify += blk_send_response_one(ioreq);
+        ioreq_release(ioreq);
     }
     if (send_notify)
-	xen_be_send_notify(&blkdev->xendev);
+        xen_be_send_notify(&blkdev->xendev);
 }
 
 static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_IDX rc)
 {
     switch (blkdev->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
-	memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
-	       sizeof(ioreq->req));
-	break;
+        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
+               sizeof(ioreq->req));
+        break;
     case BLKIF_PROTOCOL_X86_32:
         blkif_get_x86_32_req(&ioreq->req,
                              RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
-	break;
+        break;
     case BLKIF_PROTOCOL_X86_64:
         blkif_get_x86_64_req(&ioreq->req,
                              RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
-	break;
+        break;
     }
     return 0;
 }
@@ -589,44 +589,44 @@ static int blk_init(struct XenDevice *xendev)
 
     /* read xenstore entries */
     if (blkdev->params == NULL) {
-	blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
+        blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
         h = strchr(blkdev->params, ':');
-	if (h != NULL) {
-	    blkdev->fileproto = blkdev->params;
-	    blkdev->filename  = h+1;
-	    *h = 0;
-	} else {
-	    blkdev->fileproto = "<unset>";
-	    blkdev->filename  = blkdev->params;
-	}
+        if (h != NULL) {
+            blkdev->fileproto = blkdev->params;
+            blkdev->filename  = h+1;
+            *h = 0;
+        } else {
+            blkdev->fileproto = "<unset>";
+            blkdev->filename  = blkdev->params;
+        }
     }
     if (blkdev->mode == NULL)
-	blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
+        blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
     if (blkdev->type == NULL)
-	blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type");
+        blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type");
     if (blkdev->dev == NULL)
-	blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev");
+        blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev");
     if (blkdev->devtype == NULL)
-	blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type");
+        blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type");
 
     /* do we have all we need? */
     if (blkdev->params == NULL ||
-	blkdev->mode == NULL   ||
-	blkdev->type == NULL   ||
-	blkdev->dev == NULL)
-	return -1;
+        blkdev->mode == NULL   ||
+        blkdev->type == NULL   ||
+        blkdev->dev == NULL)
+        return -1;
 
     /* read-only ? */
     if (strcmp(blkdev->mode, "w") == 0) {
-	qflags = BDRV_O_RDWR;
+        qflags = BDRV_O_RDWR;
     } else {
-	qflags = 0;
-	info  |= VDISK_READONLY;
+        qflags = 0;
+        info  |= VDISK_READONLY;
     }
 
     /* cdrom ? */
     if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom"))
-	info  |= VDISK_CDROM;
+        info  |= VDISK_CDROM;
 
     /* init qemu block driver */
     index = (blkdev->xendev.dev - 202 * 256) / 16;
@@ -643,7 +643,7 @@ static int blk_init(struct XenDevice *xendev)
     } else {
         /* setup via qemu cmdline -> already setup for us */
         xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
-	blkdev->bs = blkdev->dinfo->bdrv;
+        blkdev->bs = blkdev->dinfo->bdrv;
     }
     blkdev->file_blk  = BLOCK_SIZE;
     blkdev->file_size = bdrv_getlength(blkdev->bs);
@@ -651,21 +651,21 @@ static int blk_init(struct XenDevice *xendev)
         xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
                       (int)blkdev->file_size, strerror(-blkdev->file_size),
                       blkdev->bs->drv ? blkdev->bs->drv->format_name : "-");
-	blkdev->file_size = 0;
+        blkdev->file_size = 0;
     }
     have_barriers = blkdev->bs->drv && blkdev->bs->drv->bdrv_flush ? 1 : 0;
 
     xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
-		  " size %" PRId64 " (%" PRId64 " MB)\n",
-		  blkdev->type, blkdev->fileproto, blkdev->filename,
-		  blkdev->file_size, blkdev->file_size >> 20);
+                  " size %" PRId64 " (%" PRId64 " MB)\n",
+                  blkdev->type, blkdev->fileproto, blkdev->filename,
+                  blkdev->file_size, blkdev->file_size >> 20);
 
     /* fill info */
     xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers);
     xenstore_write_be_int(&blkdev->xendev, "info",            info);
     xenstore_write_be_int(&blkdev->xendev, "sector-size",     blkdev->file_blk);
     xenstore_write_be_int(&blkdev->xendev, "sectors",
-			  blkdev->file_size / blkdev->file_blk);
+                          blkdev->file_size / blkdev->file_blk);
     return 0;
 }
 
@@ -674,10 +674,10 @@ static int blk_connect(struct XenDevice *xendev)
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
     if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1)
-	return -1;
+        return -1;
     if (xenstore_read_fe_int(&blkdev->xendev, "event-channel",
                              &blkdev->xendev.remote_port) == -1)
-	return -1;
+        return -1;
 
     blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
     if (blkdev->xendev.protocol) {
@@ -688,42 +688,42 @@ static int blk_connect(struct XenDevice *xendev)
     }
 
     blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev,
-					    blkdev->xendev.dom,
-					    blkdev->ring_ref,
-					    PROT_READ | PROT_WRITE);
+                                            blkdev->xendev.dom,
+                                            blkdev->ring_ref,
+                                            PROT_READ | PROT_WRITE);
     if (!blkdev->sring)
-	return -1;
+        return -1;
     blkdev->cnt_map++;
 
     switch (blkdev->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
     {
-	blkif_sring_t *sring_native = blkdev->sring;
-	BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);
-	break;
+        blkif_sring_t *sring_native = blkdev->sring;
+        BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);
+        break;
     }
     case BLKIF_PROTOCOL_X86_32:
     {
-	blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
 
         BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, XC_PAGE_SIZE);
-	break;
+        break;
     }
     case BLKIF_PROTOCOL_X86_64:
     {
-	blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
 
         BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, XC_PAGE_SIZE);
-	break;
+        break;
     }
     }
 
     xen_be_bind_evtchn(&blkdev->xendev);
 
     xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
-		  "remote port %d, local port %d\n",
-		  blkdev->xendev.protocol, blkdev->ring_ref,
-		  blkdev->xendev.remote_port, blkdev->xendev.local_port);
+                  "remote port %d, local port %d\n",
+                  blkdev->xendev.protocol, blkdev->ring_ref,
+                  blkdev->xendev.remote_port, blkdev->xendev.local_port);
     return 0;
 }
 
@@ -737,14 +737,14 @@ static void blk_disconnect(struct XenDevice *xendev)
             bdrv_close(blkdev->bs);
             bdrv_delete(blkdev->bs);
         }
-	blkdev->bs = NULL;
+        blkdev->bs = NULL;
     }
     xen_be_unbind_evtchn(&blkdev->xendev);
 
     if (blkdev->sring) {
-	xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
-	blkdev->cnt_map--;
-	blkdev->sring = NULL;
+        xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
+        blkdev->cnt_map--;
+        blkdev->sring = NULL;
     }
 }
 
@@ -754,10 +754,10 @@ static int blk_free(struct XenDevice *xendev)
     struct ioreq *ioreq;
 
     while (!QLIST_EMPTY(&blkdev->freelist)) {
-	ioreq = QLIST_FIRST(&blkdev->freelist);
+        ioreq = QLIST_FIRST(&blkdev->freelist);
         QLIST_REMOVE(ioreq, list);
         qemu_iovec_destroy(&ioreq->v);
-	qemu_free(ioreq);
+        qemu_free(ioreq);
     }
 
     qemu_free(blkdev->params);
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 08055b8..8fcf856 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -75,19 +75,19 @@ static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, i
 
 #if 0
     if (txp->flags & NETTXF_extra_info)
-	RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
+        RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
 #endif
 
     netdev->tx_ring.rsp_prod_pvt = ++i;
     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
     if (notify)
-	xen_be_send_notify(&netdev->xendev);
+        xen_be_send_notify(&netdev->xendev);
 
     if (i == netdev->tx_ring.req_cons) {
-	int more_to_do;
-	RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
-	if (more_to_do)
-	    netdev->tx_work++;
+        int more_to_do;
+        RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
+        if (more_to_do)
+            netdev->tx_work++;
     }
 }
 
@@ -101,10 +101,10 @@ static void net_tx_error(struct XenNetDev *netdev, netif_tx_request_t *txp, RING
     RING_IDX cons = netdev->tx_ring.req_cons;
 
     do {
-	make_tx_response(netif, txp, NETIF_RSP_ERROR);
-	if (cons >= end)
-	    break;
-	txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
+        make_tx_response(netif, txp, NETIF_RSP_ERROR);
+        if (cons >= end)
+            break;
+        txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
     } while (1);
     netdev->tx_ring.req_cons = cons;
     netif_schedule_work(netif);
@@ -122,75 +122,75 @@ static void net_tx_packets(struct XenNetDev *netdev)
     void *tmpbuf = NULL;
 
     for (;;) {
-	rc = netdev->tx_ring.req_cons;
-	rp = netdev->tx_ring.sring->req_prod;
-	xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
+        rc = netdev->tx_ring.req_cons;
+        rp = netdev->tx_ring.sring->req_prod;
+        xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-	while ((rc != rp)) {
-	    if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc))
-		break;
-	    memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
-	    netdev->tx_ring.req_cons = ++rc;
+        while ((rc != rp)) {
+            if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc))
+                break;
+            memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
+            netdev->tx_ring.req_cons = ++rc;
 
 #if 1
-	    /* should not happen in theory, we don't announce the *
-	     * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
-	    if (txreq.flags & NETTXF_extra_info) {
-		xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-	    if (txreq.flags & NETTXF_more_data) {
-		xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
+            /* should not happen in theory, we don't announce the *
+             * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
+            if (txreq.flags & NETTXF_extra_info) {
+                xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+            if (txreq.flags & NETTXF_more_data) {
+                xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
 #endif
 
-	    if (txreq.size < 14) {
-		xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-
-	    if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
-		xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-
-	    xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
-			  txreq.gref, txreq.offset, txreq.size, txreq.flags,
-			  (txreq.flags & NETTXF_csum_blank)     ? " csum_blank"     : "",
-			  (txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
-			  (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);
-	    if (page == NULL) {
-		xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
+            if (txreq.size < 14) {
+                xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+
+            if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
+                xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+
+            xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
+                          txreq.gref, txreq.offset, txreq.size, txreq.flags,
+                          (txreq.flags & NETTXF_csum_blank)     ? " csum_blank"     : "",
+                          (txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
+                          (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);
+            if (page == NULL) {
+                xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
                               txreq.gref);
-		net_tx_error(netdev, &txreq, rc);
-		continue;
-	    }
-	    if (txreq.flags & NETTXF_csum_blank) {
+                net_tx_error(netdev, &txreq, rc);
+                continue;
+            }
+            if (txreq.flags & NETTXF_csum_blank) {
                 /* have read-only mapping -> can't fill checksum in-place */
                 if (!tmpbuf)
                     tmpbuf = qemu_malloc(XC_PAGE_SIZE);
                 memcpy(tmpbuf, page + txreq.offset, txreq.size);
-		net_checksum_calculate(tmpbuf, txreq.size);
+                net_checksum_calculate(tmpbuf, txreq.size);
                 qemu_send_packet(&netdev->nic->nc, tmpbuf, txreq.size);
             } else {
                 qemu_send_packet(&netdev->nic->nc, page + txreq.offset, txreq.size);
             }
-	    xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
-	    net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
-	}
-	if (!netdev->tx_work)
-	    break;
-	netdev->tx_work = 0;
+            xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
+            net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
+        }
+        if (!netdev->tx_work)
+            break;
+        netdev->tx_work = 0;
     }
     qemu_free(tmpbuf);
 }
@@ -198,9 +198,9 @@ static void net_tx_packets(struct XenNetDev *netdev)
 /* ------------------------------------------------------------- */
 
 static void net_rx_response(struct XenNetDev *netdev,
-			    netif_rx_request_t *req, int8_t st,
-			    uint16_t offset, uint16_t size,
-			    uint16_t flags)
+                            netif_rx_request_t *req, int8_t st,
+                            uint16_t offset, uint16_t size,
+                            uint16_t flags)
 {
     RING_IDX i = netdev->rx_ring.rsp_prod_pvt;
     netif_rx_response_t *resp;
@@ -212,15 +212,15 @@ static void net_rx_response(struct XenNetDev *netdev,
     resp->id         = req->id;
     resp->status     = (int16_t)size;
     if (st < 0)
-	resp->status = (int16_t)st;
+        resp->status = (int16_t)st;
 
     xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n",
-		  i, resp->status, resp->flags);
+                  i, resp->status, resp->flags);
 
     netdev->rx_ring.rsp_prod_pvt = ++i;
     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
     if (notify)
-	xen_be_send_notify(&netdev->xendev);
+        xen_be_send_notify(&netdev->xendev);
 }
 
 #define NET_IP_ALIGN 2
@@ -231,16 +231,16 @@ static int net_rx_ok(VLANClientState *nc)
     RING_IDX rc, rp;
 
     if (netdev->xendev.be_state != XenbusStateConnected)
-	return 0;
+        return 0;
 
     rc = netdev->rx_ring.req_cons;
     rp = netdev->rx_ring.sring->req_prod;
     xen_rmb();
 
     if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
-	xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
-		      __FUNCTION__, rc, rp);
-	return 0;
+        xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
+                      __FUNCTION__, rc, rp);
+        return 0;
     }
     return 1;
 }
@@ -253,33 +253,33 @@ static ssize_t net_rx_packet(VLANClientState *nc, const uint8_t *buf, size_t siz
     void *page;
 
     if (netdev->xendev.be_state != XenbusStateConnected)
-	return -1;
+        return -1;
 
     rc = netdev->rx_ring.req_cons;
     rp = netdev->rx_ring.sring->req_prod;
     xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
     if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
-	xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
-	return -1;
+        xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
+        return -1;
     }
     if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
-	xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
-		      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
-	return -1;
+        xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
+                      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
+        return -1;
     }
 
     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);
+                                   netdev->xendev.dom,
+                                   rxreq.gref, PROT_WRITE);
     if (page == NULL) {
-	xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
+        xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
                       rxreq.gref);
-	net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
-	return -1;
+        net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
+        return -1;
     }
     memcpy(page + NET_IP_ALIGN, buf, size);
     xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
@@ -303,11 +303,11 @@ static int net_init(struct XenDevice *xendev)
 
     /* read xenstore entries */
     if (netdev->mac == NULL)
-	netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac");
+        netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac");
 
     /* do we have all we need? */
     if (netdev->mac == NULL)
-	return -1;
+        return -1;
 
     if (net_parse_macaddr(netdev->conf.macaddr.a, netdev->mac) < 0)
         return -1;
@@ -334,41 +334,41 @@ static int net_connect(struct XenDevice *xendev)
     int rx_copy;
 
     if (xenstore_read_fe_int(&netdev->xendev, "tx-ring-ref",
-				   &netdev->tx_ring_ref) == -1)
-	return -1;
+                             &netdev->tx_ring_ref) == -1)
+        return -1;
     if (xenstore_read_fe_int(&netdev->xendev, "rx-ring-ref",
-				   &netdev->rx_ring_ref) == -1)
-	return 1;
+                             &netdev->rx_ring_ref) == -1)
+        return 1;
     if (xenstore_read_fe_int(&netdev->xendev, "event-channel",
-				   &netdev->xendev.remote_port) == -1)
-	return -1;
+                             &netdev->xendev.remote_port) == -1)
+        return -1;
 
     if (xenstore_read_fe_int(&netdev->xendev, "request-rx-copy", &rx_copy) == -1)
-	rx_copy = 0;
+        rx_copy = 0;
     if (rx_copy == 0) {
-	xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
-	return -1;
+        xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
+        return -1;
     }
 
     netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
-					  netdev->xendev.dom,
-					  netdev->tx_ring_ref,
-					  PROT_READ | PROT_WRITE);
+                                          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->xendev.dom,
+                                          netdev->rx_ring_ref,
+                                          PROT_READ | PROT_WRITE);
     if (!netdev->txs || !netdev->rxs)
-	return -1;
+        return -1;
     BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XC_PAGE_SIZE);
     BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XC_PAGE_SIZE);
 
     xen_be_bind_evtchn(&netdev->xendev);
 
     xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
-		  "remote port %d, local port %d\n",
-		  netdev->tx_ring_ref, netdev->rx_ring_ref,
-		  netdev->xendev.remote_port, netdev->xendev.local_port);
+                  "remote port %d, local port %d\n",
+                  netdev->tx_ring_ref, netdev->rx_ring_ref,
+                  netdev->xendev.remote_port, netdev->xendev.local_port);
 
     net_tx_packets(netdev);
     return 0;
@@ -381,12 +381,12 @@ 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);
-	netdev->txs = NULL;
+        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
+        netdev->txs = NULL;
     }
     if (netdev->rxs) {
-	xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
-	netdev->rxs = NULL;
+        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
+        netdev->rxs = NULL;
     }
     if (netdev->nic) {
         qemu_del_vlan_client(&netdev->nic->nc);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 Makefile.objs   |    4 ----
 Makefile.target |    4 +++-
 configure       |    5 +----
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 93406ff..d91b9bc 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -150,10 +150,6 @@ slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
 slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
 common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
 
-# xen backend driver support
-common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
-common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
-
 ######################################################################
 # libuser
 
diff --git a/Makefile.target b/Makefile.target
index b0ba95f..db29e96 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
 # xen backend driver support
-obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
+obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
+obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
+obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
 
 # Inter-VM PCI shared memory
 obj-$(CONFIG_KVM) += ivshmem.o
diff --git a/configure b/configure
index 210670c..5a9121d 100755
--- a/configure
+++ b/configure
@@ -1151,7 +1151,6 @@ int main(void) { xs_daemon_open(); xc_interface_open(); return 0; }
 EOF
   if compile_prog "" "$xen_libs" ; then
     xen=yes
-    libs_softmmu="$xen_libs $libs_softmmu"
   else
     if test "$xen" = "yes" ; then
       feature_not_found "xen"
@@ -2674,9 +2673,6 @@ if test "$bluez" = "yes" ; then
   echo "CONFIG_BLUEZ=y" >> $config_host_mak
   echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak
 fi
-if test "$xen" = "yes" ; then
-  echo "CONFIG_XEN=y" >> $config_host_mak
-fi
 if test "$io_thread" = "yes" ; then
   echo "CONFIG_IOTHREAD=y" >> $config_host_mak
   echo "CONFIG_THREAD=y" >> $config_host_mak
@@ -3012,6 +3008,7 @@ case "$target_arch2" in
   i386|x86_64)
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
       echo "CONFIG_XEN=y" >> $config_target_mak
+      echo "LIBS+=$xen_libs" >> $config_target_mak
     fi
 esac
 case "$target_arch2" in
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 02/15] xen: Make xen build only on x86 target.
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 Makefile.objs   |    4 ----
 Makefile.target |    4 +++-
 configure       |    5 +----
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 93406ff..d91b9bc 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -150,10 +150,6 @@ slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
 slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
 common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
 
-# xen backend driver support
-common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
-common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
-
 ######################################################################
 # libuser
 
diff --git a/Makefile.target b/Makefile.target
index b0ba95f..db29e96 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
 # xen backend driver support
-obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
+obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
+obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
+obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
 
 # Inter-VM PCI shared memory
 obj-$(CONFIG_KVM) += ivshmem.o
diff --git a/configure b/configure
index 210670c..5a9121d 100755
--- a/configure
+++ b/configure
@@ -1151,7 +1151,6 @@ int main(void) { xs_daemon_open(); xc_interface_open(); return 0; }
 EOF
   if compile_prog "" "$xen_libs" ; then
     xen=yes
-    libs_softmmu="$xen_libs $libs_softmmu"
   else
     if test "$xen" = "yes" ; then
       feature_not_found "xen"
@@ -2674,9 +2673,6 @@ if test "$bluez" = "yes" ; then
   echo "CONFIG_BLUEZ=y" >> $config_host_mak
   echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak
 fi
-if test "$xen" = "yes" ; then
-  echo "CONFIG_XEN=y" >> $config_host_mak
-fi
 if test "$io_thread" = "yes" ; then
   echo "CONFIG_IOTHREAD=y" >> $config_host_mak
   echo "CONFIG_THREAD=y" >> $config_host_mak
@@ -3012,6 +3008,7 @@ case "$target_arch2" in
   i386|x86_64)
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
       echo "CONFIG_XEN=y" >> $config_target_mak
+      echo "LIBS+=$xen_libs" >> $config_target_mak
     fi
 esac
 case "$target_arch2" in
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This patch adds a generic layer for xc calls, allowing us to choose between the
xenner and xen implementations at runtime.

It also 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 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>
Acked-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target      |    3 +
 configure            |   62 +++++++++++++++-
 hw/xen_backend.c     |   74 ++++++++++---------
 hw/xen_backend.h     |    7 +-
 hw/xen_common.h      |   38 ++++++----
 hw/xen_console.c     |   10 +-
 hw/xen_devconfig.c   |   10 +-
 hw/xen_disk.c        |   28 ++++---
 hw/xen_domainbuild.c |   29 ++++----
 hw/xen_interfaces.c  |  191 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/xen_interfaces.h  |  198 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/xen_nic.c         |   36 +++++-----
 hw/xenfb.c           |   14 ++--
 13 files changed, 584 insertions(+), 116 deletions(-)
 create mode 100644 hw/xen_interfaces.c
 create mode 100644 hw/xen_interfaces.h

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..cf081e1 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -43,7 +43,8 @@
 /* ------------------------------------------------------------- */
 
 /* public */
-int xen_xc;
+XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
+XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
 struct xs_handle *xenstore = NULL;
 const char *xen_protocol;
 
@@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val)
     char abspath[XEN_BUFSIZE];
 
     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
-    if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
+    if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val)))
         return -1;
     return 0;
 }
@@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char *node)
     char *str, *ret = NULL;
 
     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
-    str = xs_read(xenstore, 0, abspath, &len);
+    str = xs_ops.read(xenstore, 0, abspath, &len);
     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;
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This patch adds a generic layer for xc calls, allowing us to choose between the
xenner and xen implementations at runtime.

It also 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 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>
Acked-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target      |    3 +
 configure            |   62 +++++++++++++++-
 hw/xen_backend.c     |   74 ++++++++++---------
 hw/xen_backend.h     |    7 +-
 hw/xen_common.h      |   38 ++++++----
 hw/xen_console.c     |   10 +-
 hw/xen_devconfig.c   |   10 +-
 hw/xen_disk.c        |   28 ++++---
 hw/xen_domainbuild.c |   29 ++++----
 hw/xen_interfaces.c  |  191 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/xen_interfaces.h  |  198 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/xen_nic.c         |   36 +++++-----
 hw/xenfb.c           |   14 ++--
 13 files changed, 584 insertions(+), 116 deletions(-)
 create mode 100644 hw/xen_interfaces.c
 create mode 100644 hw/xen_interfaces.h

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..cf081e1 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -43,7 +43,8 @@
 /* ------------------------------------------------------------- */
 
 /* public */
-int xen_xc;
+XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
+XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
 struct xs_handle *xenstore = NULL;
 const char *xen_protocol;
 
@@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val)
     char abspath[XEN_BUFSIZE];
 
     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
-    if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
+    if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val)))
         return -1;
     return 0;
 }
@@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char *node)
     char *str, *ret = NULL;
 
     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
-    str = xs_read(xenstore, 0, abspath, &len);
+    str = xs_ops.read(xenstore, 0, abspath, &len);
     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;
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 04/15] xen: Add initialisation of Xen
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target |    3 +++
 hw/xen.h        |   13 +++++++++++++
 vl.c            |    2 ++
 xen-all.c       |   29 +++++++++++++++++++++++++++++
 xen-stub.c      |   17 +++++++++++++++++
 5 files changed, 64 insertions(+), 0 deletions(-)
 create mode 100644 xen-all.c
 create mode 100644 xen-stub.c

diff --git a/Makefile.target b/Makefile.target
index d09719f..00bb690 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -3,6 +3,7 @@
 GENERATED_HEADERS = config-target.h
 CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
 CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
+CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
 
 include ../config-host.mak
 include config-devices.mak
@@ -207,6 +208,8 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
 # xen support
 obj-$(CONFIG_XEN) += xen_interfaces.o
+obj-$(CONFIG_XEN) += xen-all.o
+obj-$(CONFIG_NO_XEN) += xen-stub.o
 
 # xen backend driver support
 obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
diff --git a/hw/xen.h b/hw/xen.h
index 780dcf7..183cbb5 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -18,4 +18,17 @@ enum xen_mode {
 extern uint32_t xen_domid;
 extern enum xen_mode xen_mode;
 
+extern int xen_allowed;
+
+static inline int xen_enabled(void)
+{
+#ifdef CONFIG_XEN
+    return xen_allowed;
+#else
+    return 0;
+#endif
+}
+
+int xen_init(int smp_cpus);
+
 #endif /* QEMU_HW_XEN_H */
diff --git a/vl.c b/vl.c
index 626f4e1..38fa281 100644
--- a/vl.c
+++ b/vl.c
@@ -259,6 +259,7 @@ static NotifierList machine_init_done_notifiers =
 
 static int tcg_allowed = 1;
 int kvm_allowed = 0;
+int xen_allowed = 0;
 uint32_t xen_domid;
 enum xen_mode xen_mode = XEN_EMULATE;
 
@@ -1836,6 +1837,7 @@ static struct {
     int *allowed;
 } accel_list[] = {
     { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
+    { "xen", "Xen", xen_available, xen_init, &xen_allowed },
     { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
 };
 
diff --git a/xen-all.c b/xen-all.c
new file mode 100644
index 0000000..8d77d42
--- /dev/null
+++ b/xen-all.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010       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.h"
+
+#include "hw/xen_common.h"
+#include "hw/xen_backend.h"
+
+/* Initialise Xen */
+
+int xen_init(int smp_cpus)
+{
+    if (xen_mode == XEN_EMULATE) {
+        xen_mode = XEN_ATTACH;
+    }
+    xen_interfaces_init();
+    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");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/xen-stub.c b/xen-stub.c
new file mode 100644
index 0000000..0fa9c51
--- /dev/null
+++ b/xen-stub.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2010       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.h"
+
+#include "qemu-common.h"
+#include "hw/xen.h"
+
+int xen_init(int smp_cpus)
+{
+    return -ENOSYS;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 04/15] xen: Add initialisation of Xen
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target |    3 +++
 hw/xen.h        |   13 +++++++++++++
 vl.c            |    2 ++
 xen-all.c       |   29 +++++++++++++++++++++++++++++
 xen-stub.c      |   17 +++++++++++++++++
 5 files changed, 64 insertions(+), 0 deletions(-)
 create mode 100644 xen-all.c
 create mode 100644 xen-stub.c

diff --git a/Makefile.target b/Makefile.target
index d09719f..00bb690 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -3,6 +3,7 @@
 GENERATED_HEADERS = config-target.h
 CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
 CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
+CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
 
 include ../config-host.mak
 include config-devices.mak
@@ -207,6 +208,8 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
 # xen support
 obj-$(CONFIG_XEN) += xen_interfaces.o
+obj-$(CONFIG_XEN) += xen-all.o
+obj-$(CONFIG_NO_XEN) += xen-stub.o
 
 # xen backend driver support
 obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
diff --git a/hw/xen.h b/hw/xen.h
index 780dcf7..183cbb5 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -18,4 +18,17 @@ enum xen_mode {
 extern uint32_t xen_domid;
 extern enum xen_mode xen_mode;
 
+extern int xen_allowed;
+
+static inline int xen_enabled(void)
+{
+#ifdef CONFIG_XEN
+    return xen_allowed;
+#else
+    return 0;
+#endif
+}
+
+int xen_init(int smp_cpus);
+
 #endif /* QEMU_HW_XEN_H */
diff --git a/vl.c b/vl.c
index 626f4e1..38fa281 100644
--- a/vl.c
+++ b/vl.c
@@ -259,6 +259,7 @@ static NotifierList machine_init_done_notifiers =
 
 static int tcg_allowed = 1;
 int kvm_allowed = 0;
+int xen_allowed = 0;
 uint32_t xen_domid;
 enum xen_mode xen_mode = XEN_EMULATE;
 
@@ -1836,6 +1837,7 @@ static struct {
     int *allowed;
 } accel_list[] = {
     { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
+    { "xen", "Xen", xen_available, xen_init, &xen_allowed },
     { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
 };
 
diff --git a/xen-all.c b/xen-all.c
new file mode 100644
index 0000000..8d77d42
--- /dev/null
+++ b/xen-all.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010       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.h"
+
+#include "hw/xen_common.h"
+#include "hw/xen_backend.h"
+
+/* Initialise Xen */
+
+int xen_init(int smp_cpus)
+{
+    if (xen_mode == XEN_EMULATE) {
+        xen_mode = XEN_ATTACH;
+    }
+    xen_interfaces_init();
+    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");
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/xen-stub.c b/xen-stub.c
new file mode 100644
index 0000000..0fa9c51
--- /dev/null
+++ b/xen-stub.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2010       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.h"
+
+#include "qemu-common.h"
+#include "hw/xen.h"
+
+int xen_init(int smp_cpus)
+{
+    return -ENOSYS;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Introduce the Xen FV (Fully Virtualized) machine to Qemu, some more Xen
specific call will be added in further patches.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 hw/pc.c      |   19 +++++++++++++++++--
 hw/pc_piix.c |   21 ++++++++++++++++++++-
 hw/xen.h     |    4 ++++
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 4dfdc0b..ab9d365 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -41,6 +41,7 @@
 #include "sysemu.h"
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
+#include "xen.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -906,7 +907,11 @@ static void pc_cpu_reset(void *opaque)
     CPUState *env = opaque;
 
     cpu_reset(env);
-    env->halted = !cpu_is_bsp(env);
+    if (!xen_enabled()) {
+        env->halted = !cpu_is_bsp(env);
+    } else {
+        env->halted = 1;
+    }
 }
 
 static CPUState *pc_new_cpu(const char *cpu_model)
@@ -940,7 +945,12 @@ void pc_cpus_init(const char *cpu_model)
 #endif
     }
 
-    for(i = 0; i < smp_cpus; i++) {
+    if (!xen_enabled()) {
+        for(i = 0; i < smp_cpus; i++) {
+            pc_new_cpu(cpu_model);
+        }
+    } else {
+        /* Xen require only one Qemu VCPU */
         pc_new_cpu(cpu_model);
     }
 }
@@ -968,6 +978,11 @@ void pc_memory_init(ram_addr_t ram_size,
     *above_4g_mem_size_p = above_4g_mem_size;
     *below_4g_mem_size_p = below_4g_mem_size;
 
+    if (xen_enabled()) {
+        /* Nothing to do for Xen */
+        return;
+    }
+
 #if TARGET_PHYS_ADDR_BITS == 32
     if (above_4g_mem_size > 0) {
         hw_error("To much RAM for 32-bit physical address");
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 7b74473..0ab8907 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -36,6 +36,10 @@
 #include "sysbus.h"
 #include "arch_init.h"
 #include "blockdev.h"
+#include "xen.h"
+#ifdef CONFIG_XEN
+#  include "xen/hvm/hvm_info_table.h"
+#endif
 
 #define MAX_IDE_BUS 2
 
@@ -86,7 +90,9 @@ static void pc_init1(ram_addr_t ram_size,
 
     pc_cpus_init(cpu_model);
 
-    vmport_init();
+    if (!xen_enabled()) {
+        vmport_init();
+    }
 
     /* allocate ram and load rom/bios */
     pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename,
@@ -376,6 +382,16 @@ static QEMUMachine isapc_machine = {
     .max_cpus = 1,
 };
 
+#ifdef CONFIG_XEN
+static QEMUMachine xenfv_machine = {
+    .name = "xenfv",
+    .desc = "Xen Fully-virtualized PC",
+    .init = pc_init_pci,
+    .max_cpus = HVM_MAX_VCPUS,
+    .default_machine_opts = "accel=xen",
+};
+#endif
+
 static void pc_machine_init(void)
 {
     qemu_register_machine(&pc_machine);
@@ -384,6 +400,9 @@ static void pc_machine_init(void)
     qemu_register_machine(&pc_machine_v0_11);
     qemu_register_machine(&pc_machine_v0_10);
     qemu_register_machine(&isapc_machine);
+#ifdef CONFIG_XEN
+    qemu_register_machine(&xenfv_machine);
+#endif
 }
 
 machine_init(pc_machine_init);
diff --git a/hw/xen.h b/hw/xen.h
index 183cbb5..3984069 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -31,4 +31,8 @@ static inline int xen_enabled(void)
 
 int xen_init(int smp_cpus);
 
+#if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
+#  define HVM_MAX_VCPUS 32
+#endif
+
 #endif /* QEMU_HW_XEN_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 05/15] xen: Add xenfv machine
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Introduce the Xen FV (Fully Virtualized) machine to Qemu, some more Xen
specific call will be added in further patches.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 hw/pc.c      |   19 +++++++++++++++++--
 hw/pc_piix.c |   21 ++++++++++++++++++++-
 hw/xen.h     |    4 ++++
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 4dfdc0b..ab9d365 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -41,6 +41,7 @@
 #include "sysemu.h"
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
+#include "xen.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -906,7 +907,11 @@ static void pc_cpu_reset(void *opaque)
     CPUState *env = opaque;
 
     cpu_reset(env);
-    env->halted = !cpu_is_bsp(env);
+    if (!xen_enabled()) {
+        env->halted = !cpu_is_bsp(env);
+    } else {
+        env->halted = 1;
+    }
 }
 
 static CPUState *pc_new_cpu(const char *cpu_model)
@@ -940,7 +945,12 @@ void pc_cpus_init(const char *cpu_model)
 #endif
     }
 
-    for(i = 0; i < smp_cpus; i++) {
+    if (!xen_enabled()) {
+        for(i = 0; i < smp_cpus; i++) {
+            pc_new_cpu(cpu_model);
+        }
+    } else {
+        /* Xen require only one Qemu VCPU */
         pc_new_cpu(cpu_model);
     }
 }
@@ -968,6 +978,11 @@ void pc_memory_init(ram_addr_t ram_size,
     *above_4g_mem_size_p = above_4g_mem_size;
     *below_4g_mem_size_p = below_4g_mem_size;
 
+    if (xen_enabled()) {
+        /* Nothing to do for Xen */
+        return;
+    }
+
 #if TARGET_PHYS_ADDR_BITS == 32
     if (above_4g_mem_size > 0) {
         hw_error("To much RAM for 32-bit physical address");
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 7b74473..0ab8907 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -36,6 +36,10 @@
 #include "sysbus.h"
 #include "arch_init.h"
 #include "blockdev.h"
+#include "xen.h"
+#ifdef CONFIG_XEN
+#  include "xen/hvm/hvm_info_table.h"
+#endif
 
 #define MAX_IDE_BUS 2
 
@@ -86,7 +90,9 @@ static void pc_init1(ram_addr_t ram_size,
 
     pc_cpus_init(cpu_model);
 
-    vmport_init();
+    if (!xen_enabled()) {
+        vmport_init();
+    }
 
     /* allocate ram and load rom/bios */
     pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename,
@@ -376,6 +382,16 @@ static QEMUMachine isapc_machine = {
     .max_cpus = 1,
 };
 
+#ifdef CONFIG_XEN
+static QEMUMachine xenfv_machine = {
+    .name = "xenfv",
+    .desc = "Xen Fully-virtualized PC",
+    .init = pc_init_pci,
+    .max_cpus = HVM_MAX_VCPUS,
+    .default_machine_opts = "accel=xen",
+};
+#endif
+
 static void pc_machine_init(void)
 {
     qemu_register_machine(&pc_machine);
@@ -384,6 +400,9 @@ static void pc_machine_init(void)
     qemu_register_machine(&pc_machine_v0_11);
     qemu_register_machine(&pc_machine_v0_10);
     qemu_register_machine(&isapc_machine);
+#ifdef CONFIG_XEN
+    qemu_register_machine(&xenfv_machine);
+#endif
 }
 
 machine_init(pc_machine_init);
diff --git a/hw/xen.h b/hw/xen.h
index 183cbb5..3984069 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -31,4 +31,8 @@ static inline int xen_enabled(void)
 
 int xen_init(int smp_cpus);
 
+#if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
+#  define HVM_MAX_VCPUS 32
+#endif
+
 #endif /* QEMU_HW_XEN_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Steven Smith, Anthony PERARD, Xen Devel, Stefano Stabellini

From: Steven Smith <ssmith@xensource.com>

Introduce a new emulated PCI device, specific to fully virtualized Xen
guests.  The device is necessary for PV on HVM drivers to work.

Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 Makefile.target   |    1 +
 hw/hw.h           |    3 +
 hw/pc_piix.c      |    4 +
 hw/pci_ids.h      |    2 +
 hw/xen.h          |    2 +
 hw/xen_platform.c |  348 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 xen-stub.c        |    4 +
 7 files changed, 364 insertions(+), 0 deletions(-)
 create mode 100644 hw/xen_platform.c

diff --git a/Makefile.target b/Makefile.target
index 00bb690..7a4fd72 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -215,6 +215,7 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o
 obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
 obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
 obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
+obj-i386-$(CONFIG_XEN) += xen_platform.o
 
 # Inter-VM PCI shared memory
 obj-$(CONFIG_KVM) += ivshmem.o
diff --git a/hw/hw.h b/hw/hw.h
index dd993de..298df31 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -672,6 +672,9 @@ extern const VMStateDescription vmstate_i2c_slave;
 #define VMSTATE_INT32_LE(_f, _s)                                   \
     VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
 
+#define VMSTATE_UINT8_TEST(_f, _s, _t)                               \
+    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
+
 #define VMSTATE_UINT16_TEST(_f, _s, _t)                               \
     VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 0ab8907..765877c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -120,6 +120,10 @@ static void pc_init1(ram_addr_t ram_size,
 
     pc_vga_init(pci_enabled? pci_bus: NULL);
 
+    if (xen_enabled()) {
+        pci_xen_platform_init(pci_bus);
+    }
+
     /* init basic PC hardware */
     pc_basic_device_init(isa_irq, &floppy_controller, &rtc_state);
 
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index ea3418c..6e9eabc 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -108,3 +108,5 @@
 #define PCI_DEVICE_ID_INTEL_82371AB      0x7111
 #define PCI_DEVICE_ID_INTEL_82371AB_2    0x7112
 #define PCI_DEVICE_ID_INTEL_82371AB_3    0x7113
+
+#define PCI_VENDOR_ID_XENSOURCE          0x5853
diff --git a/hw/xen.h b/hw/xen.h
index 3984069..53a2ca4 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -29,6 +29,8 @@ static inline int xen_enabled(void)
 #endif
 }
 
+void pci_xen_platform_init(PCIBus *bus);
+
 int xen_init(int smp_cpus);
 
 #if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
new file mode 100644
index 0000000..383cfcf
--- /dev/null
+++ b/hw/xen_platform.c
@@ -0,0 +1,348 @@
+/*
+ * XEN platform pci device, formerly known as the event channel device
+ *
+ * Copyright (c) 2003-2004 Intel Corp.
+ * Copyright (c) 2006 XenSource
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "pci.h"
+#include "irq.h"
+#include "xen_common.h"
+#include "net.h"
+#include "xen_backend.h"
+#include "qemu-log.h"
+#include "rwhandler.h"
+
+#include <assert.h>
+#include <xenguest.h>
+
+//#define DEBUG_PLATFORM
+
+#ifdef DEBUG_PLATFORM
+#define DPRINTF(fmt, ...) do { \
+    fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
+
+typedef struct PCIXenPlatformState {
+    PCIDevice  pci_dev;
+    uint8_t flags; /* used only for version_id == 2 */
+    int drivers_blacklisted;
+    uint16_t driver_product_version;
+
+    /* Log from guest drivers */
+    char log_buffer[4096];
+    int log_buffer_off;
+} PCIXenPlatformState;
+
+#define XEN_PLATFORM_IOPORT 0x10
+
+/* Send bytes to syslog */
+static void log_writeb(PCIXenPlatformState *s, char val)
+{
+    if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) {
+        /* Flush buffer */
+        s->log_buffer[s->log_buffer_off] = 0;
+        DPRINTF("%s\n", s->log_buffer);
+        s->log_buffer_off = 0;
+    } else {
+        s->log_buffer[s->log_buffer_off++] = val;
+    }
+}
+
+/* Xen Platform, Fixed IOPort */
+
+static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* TODO: */
+        /* Unplug devices.  Value is a bitmask of which devices to
+           unplug, with bit 0 the IDE devices, bit 1 the network
+           devices, and bit 2 the non-primary-master IDE devices. */
+        break;
+    case 2:
+        switch (val) {
+        case 1:
+            DPRINTF("Citrix Windows PV drivers loaded in guest\n");
+            break;
+        case 0:
+            DPRINTF("Guest claimed to be running PV product 0?\n");
+            break;
+        default:
+            DPRINTF("Unknown PV product %d loaded in guest\n", val);
+            break;
+        }
+        s->driver_product_version = val;
+        break;
+    }
+}
+
+static void platform_fixed_ioport_writel(void *opaque, uint32_t addr,
+                                         uint32_t val)
+{
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* PV driver version */
+        break;
+    }
+}
+
+static void platform_fixed_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0: /* Platform flags */ {
+        hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
+            HVMMEM_ram_ro : HVMMEM_ram_rw;
+        if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type, 0xc0, 0x40)) {
+            DPRINTF("unable to change ro/rw state of ROM memory area!\n");
+        } else {
+            s->flags = val & PFFLAG_ROM_LOCK;
+            DPRINTF("changed ro/rw state of ROM memory area. now is %s state.\n",
+                    (mem_type == HVMMEM_ram_ro ? "ro":"rw"));
+        }
+        break;
+    }
+    case 2:
+        log_writeb(s, val);
+        break;
+    }
+}
+
+static uint32_t platform_fixed_ioport_readw(void *opaque, uint32_t addr)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        if (s->drivers_blacklisted) {
+            /* The drivers will recognise this magic number and refuse
+             * to do anything. */
+            return 0xd249;
+        } else {
+            /* Magic value so that you can identify the interface. */
+            return 0x49d2;
+        }
+    default:
+        return 0xffff;
+    }
+}
+
+static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* Platform flags */
+        return s->flags;
+    case 2:
+        /* Version number */
+        return 1;
+    default:
+        return 0xff;
+    }
+}
+
+static void platform_fixed_ioport_reset(void *opaque)
+{
+    PCIXenPlatformState *s = opaque;
+
+    platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0);
+}
+
+static void platform_fixed_ioport_init(PCIXenPlatformState* s)
+{
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);
+    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);
+    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);
+}
+
+/* Xen Platform PCI Device */
+
+static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+{
+    addr &= 0xff;
+
+    if (addr == 0) {
+        return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT);
+    } else {
+        return ~0u;
+    }
+}
+
+static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    addr &= 0xff;
+    val  &= 0xff;
+
+    switch (addr) {
+    case 0: /* Platform flags */
+        platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);
+        break;
+    case 8:
+        log_writeb(s, val);
+        break;
+    default:
+        break;
+    }
+}
+
+static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type)
+{
+    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev);
+
+    register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
+    register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+}
+
+static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)
+{
+    DPRINTF("Warning: attempted read from physical address "
+            "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);
+
+    return 0;
+}
+
+static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,
+                                uint32_t val, int len)
+{
+    DPRINTF("Warning: attempted write of 0x%x to physical "
+            "address 0x" TARGET_FMT_plx " in xen platform mmio space\n",
+            val, addr);
+}
+
+static ReadWriteHandler platform_mmio_handler = {
+    .read = &platform_mmio_read,
+    .write = &platform_mmio_write,
+};
+
+static void platform_mmio_map(PCIDevice *d, int region_num,
+                              pcibus_t addr, pcibus_t size, int type)
+{
+    int mmio_io_addr;
+
+    mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,
+                                                 DEVICE_NATIVE_ENDIAN);
+
+    cpu_register_physical_memory(addr, size, mmio_io_addr);
+}
+
+static int xen_platform_post_load(void *opaque, int version_id)
+{
+    PCIXenPlatformState *s = opaque;
+
+    platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, s->flags);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_xen_platform = {
+    .name = "platform",
+    .version_id = 4,
+    .minimum_version_id = 4,
+    .minimum_version_id_old = 4,
+    .post_load = xen_platform_post_load,
+    .fields = (VMStateField []) {
+        VMSTATE_PCI_DEVICE(pci_dev, PCIXenPlatformState),
+        VMSTATE_UINT8(flags, PCIXenPlatformState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static int xen_platform_initfn(PCIDevice *dev)
+{
+    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, dev);
+    uint8_t *pci_conf;
+
+    pci_conf = d->pci_dev.config;
+
+    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XENSOURCE);
+    pci_config_set_device_id(pci_conf, 0x0001);
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XENSOURCE);
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0001);
+
+    pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+    pci_config_set_revision(pci_conf, 1);
+    pci_config_set_prog_interface(pci_conf, 0);
+
+    pci_config_set_class(pci_conf, PCI_CLASS_OTHERS << 8 | 0x80);
+
+    pci_conf[PCI_INTERRUPT_PIN] = 1;
+
+    pci_register_bar(&d->pci_dev, 0, 0x100,
+            PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map);
+
+    /* reserve 16MB mmio address for share memory*/
+    pci_register_bar(&d->pci_dev, 1, 0x1000000,
+            PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map);
+
+    platform_fixed_ioport_init(d);
+
+    return 0;
+}
+
+static void platform_reset(DeviceState *dev)
+{
+    PCIXenPlatformState *s = DO_UPCAST(PCIXenPlatformState, pci_dev.qdev, dev);
+
+    platform_fixed_ioport_reset(s);
+}
+
+void pci_xen_platform_init(PCIBus *bus)
+{
+    PCIDevice *dev;
+
+    dev = pci_create(bus, -1, "xen-platform");
+
+    qdev_init_nofail(&dev->qdev);
+}
+
+static PCIDeviceInfo xen_platform_info = {
+    .init = xen_platform_initfn,
+    .qdev.name = "xen-platform",
+    .qdev.desc = "XEN platform pci device",
+    .qdev.size = sizeof(PCIXenPlatformState),
+    .qdev.vmsd = &vmstate_xen_platform,
+    .qdev.reset = platform_reset,
+};
+
+static void xen_platform_register(void)
+{
+    pci_qdev_register(&xen_platform_info);
+}
+
+device_init(xen_platform_register);
diff --git a/xen-stub.c b/xen-stub.c
index 0fa9c51..a6d5850 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -11,6 +11,10 @@
 #include "qemu-common.h"
 #include "hw/xen.h"
 
+void pci_xen_platform_init(PCIBus *bus)
+{
+}
+
 int xen_init(int smp_cpus)
 {
     return -ENOSYS;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 06/15] xen: Add the Xen platform pci device
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel
  Cc: Steven Smith, Anthony PERARD, Xen Devel, Anthony Liguori,
	Stefano Stabellini

From: Steven Smith <ssmith@xensource.com>

Introduce a new emulated PCI device, specific to fully virtualized Xen
guests.  The device is necessary for PV on HVM drivers to work.

Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 Makefile.target   |    1 +
 hw/hw.h           |    3 +
 hw/pc_piix.c      |    4 +
 hw/pci_ids.h      |    2 +
 hw/xen.h          |    2 +
 hw/xen_platform.c |  348 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 xen-stub.c        |    4 +
 7 files changed, 364 insertions(+), 0 deletions(-)
 create mode 100644 hw/xen_platform.c

diff --git a/Makefile.target b/Makefile.target
index 00bb690..7a4fd72 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -215,6 +215,7 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o
 obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
 obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
 obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
+obj-i386-$(CONFIG_XEN) += xen_platform.o
 
 # Inter-VM PCI shared memory
 obj-$(CONFIG_KVM) += ivshmem.o
diff --git a/hw/hw.h b/hw/hw.h
index dd993de..298df31 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -672,6 +672,9 @@ extern const VMStateDescription vmstate_i2c_slave;
 #define VMSTATE_INT32_LE(_f, _s)                                   \
     VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
 
+#define VMSTATE_UINT8_TEST(_f, _s, _t)                               \
+    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
+
 #define VMSTATE_UINT16_TEST(_f, _s, _t)                               \
     VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 0ab8907..765877c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -120,6 +120,10 @@ static void pc_init1(ram_addr_t ram_size,
 
     pc_vga_init(pci_enabled? pci_bus: NULL);
 
+    if (xen_enabled()) {
+        pci_xen_platform_init(pci_bus);
+    }
+
     /* init basic PC hardware */
     pc_basic_device_init(isa_irq, &floppy_controller, &rtc_state);
 
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index ea3418c..6e9eabc 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -108,3 +108,5 @@
 #define PCI_DEVICE_ID_INTEL_82371AB      0x7111
 #define PCI_DEVICE_ID_INTEL_82371AB_2    0x7112
 #define PCI_DEVICE_ID_INTEL_82371AB_3    0x7113
+
+#define PCI_VENDOR_ID_XENSOURCE          0x5853
diff --git a/hw/xen.h b/hw/xen.h
index 3984069..53a2ca4 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -29,6 +29,8 @@ static inline int xen_enabled(void)
 #endif
 }
 
+void pci_xen_platform_init(PCIBus *bus);
+
 int xen_init(int smp_cpus);
 
 #if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
new file mode 100644
index 0000000..383cfcf
--- /dev/null
+++ b/hw/xen_platform.c
@@ -0,0 +1,348 @@
+/*
+ * XEN platform pci device, formerly known as the event channel device
+ *
+ * Copyright (c) 2003-2004 Intel Corp.
+ * Copyright (c) 2006 XenSource
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "pci.h"
+#include "irq.h"
+#include "xen_common.h"
+#include "net.h"
+#include "xen_backend.h"
+#include "qemu-log.h"
+#include "rwhandler.h"
+
+#include <assert.h>
+#include <xenguest.h>
+
+//#define DEBUG_PLATFORM
+
+#ifdef DEBUG_PLATFORM
+#define DPRINTF(fmt, ...) do { \
+    fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
+
+typedef struct PCIXenPlatformState {
+    PCIDevice  pci_dev;
+    uint8_t flags; /* used only for version_id == 2 */
+    int drivers_blacklisted;
+    uint16_t driver_product_version;
+
+    /* Log from guest drivers */
+    char log_buffer[4096];
+    int log_buffer_off;
+} PCIXenPlatformState;
+
+#define XEN_PLATFORM_IOPORT 0x10
+
+/* Send bytes to syslog */
+static void log_writeb(PCIXenPlatformState *s, char val)
+{
+    if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) {
+        /* Flush buffer */
+        s->log_buffer[s->log_buffer_off] = 0;
+        DPRINTF("%s\n", s->log_buffer);
+        s->log_buffer_off = 0;
+    } else {
+        s->log_buffer[s->log_buffer_off++] = val;
+    }
+}
+
+/* Xen Platform, Fixed IOPort */
+
+static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* TODO: */
+        /* Unplug devices.  Value is a bitmask of which devices to
+           unplug, with bit 0 the IDE devices, bit 1 the network
+           devices, and bit 2 the non-primary-master IDE devices. */
+        break;
+    case 2:
+        switch (val) {
+        case 1:
+            DPRINTF("Citrix Windows PV drivers loaded in guest\n");
+            break;
+        case 0:
+            DPRINTF("Guest claimed to be running PV product 0?\n");
+            break;
+        default:
+            DPRINTF("Unknown PV product %d loaded in guest\n", val);
+            break;
+        }
+        s->driver_product_version = val;
+        break;
+    }
+}
+
+static void platform_fixed_ioport_writel(void *opaque, uint32_t addr,
+                                         uint32_t val)
+{
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* PV driver version */
+        break;
+    }
+}
+
+static void platform_fixed_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0: /* Platform flags */ {
+        hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
+            HVMMEM_ram_ro : HVMMEM_ram_rw;
+        if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type, 0xc0, 0x40)) {
+            DPRINTF("unable to change ro/rw state of ROM memory area!\n");
+        } else {
+            s->flags = val & PFFLAG_ROM_LOCK;
+            DPRINTF("changed ro/rw state of ROM memory area. now is %s state.\n",
+                    (mem_type == HVMMEM_ram_ro ? "ro":"rw"));
+        }
+        break;
+    }
+    case 2:
+        log_writeb(s, val);
+        break;
+    }
+}
+
+static uint32_t platform_fixed_ioport_readw(void *opaque, uint32_t addr)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        if (s->drivers_blacklisted) {
+            /* The drivers will recognise this magic number and refuse
+             * to do anything. */
+            return 0xd249;
+        } else {
+            /* Magic value so that you can identify the interface. */
+            return 0x49d2;
+        }
+    default:
+        return 0xffff;
+    }
+}
+
+static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* Platform flags */
+        return s->flags;
+    case 2:
+        /* Version number */
+        return 1;
+    default:
+        return 0xff;
+    }
+}
+
+static void platform_fixed_ioport_reset(void *opaque)
+{
+    PCIXenPlatformState *s = opaque;
+
+    platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0);
+}
+
+static void platform_fixed_ioport_init(PCIXenPlatformState* s)
+{
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);
+    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);
+    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);
+}
+
+/* Xen Platform PCI Device */
+
+static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+{
+    addr &= 0xff;
+
+    if (addr == 0) {
+        return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT);
+    } else {
+        return ~0u;
+    }
+}
+
+static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    addr &= 0xff;
+    val  &= 0xff;
+
+    switch (addr) {
+    case 0: /* Platform flags */
+        platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);
+        break;
+    case 8:
+        log_writeb(s, val);
+        break;
+    default:
+        break;
+    }
+}
+
+static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type)
+{
+    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev);
+
+    register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
+    register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+}
+
+static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)
+{
+    DPRINTF("Warning: attempted read from physical address "
+            "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);
+
+    return 0;
+}
+
+static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,
+                                uint32_t val, int len)
+{
+    DPRINTF("Warning: attempted write of 0x%x to physical "
+            "address 0x" TARGET_FMT_plx " in xen platform mmio space\n",
+            val, addr);
+}
+
+static ReadWriteHandler platform_mmio_handler = {
+    .read = &platform_mmio_read,
+    .write = &platform_mmio_write,
+};
+
+static void platform_mmio_map(PCIDevice *d, int region_num,
+                              pcibus_t addr, pcibus_t size, int type)
+{
+    int mmio_io_addr;
+
+    mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,
+                                                 DEVICE_NATIVE_ENDIAN);
+
+    cpu_register_physical_memory(addr, size, mmio_io_addr);
+}
+
+static int xen_platform_post_load(void *opaque, int version_id)
+{
+    PCIXenPlatformState *s = opaque;
+
+    platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, s->flags);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_xen_platform = {
+    .name = "platform",
+    .version_id = 4,
+    .minimum_version_id = 4,
+    .minimum_version_id_old = 4,
+    .post_load = xen_platform_post_load,
+    .fields = (VMStateField []) {
+        VMSTATE_PCI_DEVICE(pci_dev, PCIXenPlatformState),
+        VMSTATE_UINT8(flags, PCIXenPlatformState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static int xen_platform_initfn(PCIDevice *dev)
+{
+    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, dev);
+    uint8_t *pci_conf;
+
+    pci_conf = d->pci_dev.config;
+
+    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XENSOURCE);
+    pci_config_set_device_id(pci_conf, 0x0001);
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XENSOURCE);
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0001);
+
+    pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+    pci_config_set_revision(pci_conf, 1);
+    pci_config_set_prog_interface(pci_conf, 0);
+
+    pci_config_set_class(pci_conf, PCI_CLASS_OTHERS << 8 | 0x80);
+
+    pci_conf[PCI_INTERRUPT_PIN] = 1;
+
+    pci_register_bar(&d->pci_dev, 0, 0x100,
+            PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map);
+
+    /* reserve 16MB mmio address for share memory*/
+    pci_register_bar(&d->pci_dev, 1, 0x1000000,
+            PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map);
+
+    platform_fixed_ioport_init(d);
+
+    return 0;
+}
+
+static void platform_reset(DeviceState *dev)
+{
+    PCIXenPlatformState *s = DO_UPCAST(PCIXenPlatformState, pci_dev.qdev, dev);
+
+    platform_fixed_ioport_reset(s);
+}
+
+void pci_xen_platform_init(PCIBus *bus)
+{
+    PCIDevice *dev;
+
+    dev = pci_create(bus, -1, "xen-platform");
+
+    qdev_init_nofail(&dev->qdev);
+}
+
+static PCIDeviceInfo xen_platform_info = {
+    .init = xen_platform_initfn,
+    .qdev.name = "xen-platform",
+    .qdev.desc = "XEN platform pci device",
+    .qdev.size = sizeof(PCIXenPlatformState),
+    .qdev.vmsd = &vmstate_xen_platform,
+    .qdev.reset = platform_reset,
+};
+
+static void xen_platform_register(void)
+{
+    pci_qdev_register(&xen_platform_info);
+}
+
+device_init(xen_platform_register);
diff --git a/xen-stub.c b/xen-stub.c
index 0fa9c51..a6d5850 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -11,6 +11,10 @@
 #include "qemu-common.h"
 #include "hw/xen.h"
 
+void pci_xen_platform_init(PCIBus *bus)
+{
+}
+
 int xen_init(int smp_cpus)
 {
     return -ENOSYS;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 07/15] piix_pci: Introduces Xen specific call for irq.
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This patch introduces Xen specific call in piix_pci.

The specific part for Xen is in write_config, set_irq and get_pirq.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 hw/piix_pci.c |   28 ++++++++++++++++++++++++++--
 hw/xen.h      |    6 ++++++
 xen-all.c     |   31 +++++++++++++++++++++++++++++++
 xen-stub.c    |   13 +++++++++++++
 4 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 358da58..152fcc0 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -29,6 +29,7 @@
 #include "isa.h"
 #include "sysbus.h"
 #include "range.h"
+#include "xen.h"
 
 /*
  * I440FX chipset data sheet.
@@ -151,6 +152,13 @@ static void i440fx_write_config(PCIDevice *dev,
     }
 }
 
+static void i440fx_write_config_xen(PCIDevice *dev,
+                                    uint32_t address, uint32_t val, int len)
+{
+    xen_piix_pci_write_config_client(address, val, len);
+    i440fx_write_config(dev, address, val, len);
+}
+
 static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 {
     PCII440FXState *d = opaque;
@@ -230,13 +238,21 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
     s->bus = b;
     qdev_init_nofail(dev);
 
-    d = pci_create_simple(b, 0, "i440FX");
+    if (xen_enabled()) {
+        d = pci_create_simple(b, 0, "i440FX-xen");
+    } else {
+        d = pci_create_simple(b, 0, "i440FX");
+    }
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
 
     piix3 = DO_UPCAST(PIIX3State, dev,
                       pci_create_simple_multifunction(b, -1, true, "PIIX3"));
     piix3->pic = pic;
-    pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
+    if (xen_enabled()) {
+        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, 4);
+    } else {
+        pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
+    }
     (*pi440fx_state)->piix3 = piix3;
 
     *piix3_devfn = piix3->dev.devfn;
@@ -352,6 +368,14 @@ static PCIDeviceInfo i440fx_info[] = {
         .init         = i440fx_initfn,
         .config_write = i440fx_write_config,
     },{
+        .qdev.name    = "i440FX-xen",
+        .qdev.desc    = "Host bridge",
+        .qdev.size    = sizeof(PCII440FXState),
+        .qdev.vmsd    = &vmstate_i440fx,
+        .qdev.no_user = 1,
+        .init         = i440fx_initfn,
+        .config_write = i440fx_write_config_xen,
+    },{
         .qdev.name    = "PIIX3",
         .qdev.desc    = "ISA bridge",
         .qdev.size    = sizeof(PIIX3State),
diff --git a/hw/xen.h b/hw/xen.h
index 53a2ca4..2a53f8b 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -8,6 +8,8 @@
  */
 #include <inttypes.h>
 
+#include "qemu-common.h"
+
 /* xen-machine.c */
 enum xen_mode {
     XEN_EMULATE = 0,  // xen emulation, using xenner (default)
@@ -29,6 +31,10 @@ static inline int xen_enabled(void)
 #endif
 }
 
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
+void xen_piix3_set_irq(void *opaque, int irq_num, int level);
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
+
 void pci_xen_platform_init(PCIBus *bus);
 
 int xen_init(int smp_cpus);
diff --git a/xen-all.c b/xen-all.c
index 8d77d42..123decb 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -8,9 +8,40 @@
 
 #include "config.h"
 
+#include "hw/pci.h"
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
+/* Xen specific function for piix pci */
+
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+    return irq_num + ((pci_dev->devfn >> 3) << 2);
+}
+
+void xen_piix3_set_irq(void *opaque, int irq_num, int level)
+{
+    xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num >> 2,
+                              irq_num & 3, level);
+}
+
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
+{
+    int i;
+
+    /* Scan for updates to PCI link routes (0x60-0x63). */
+    for (i = 0; i < len; i++) {
+        uint8_t v = (val >> (8 * i)) & 0xff;
+        if (v & 0x80) {
+            v = 0;
+        }
+        v &= 0xf;
+        if (((address + i) >= 0x60) && ((address + i) <= 0x63)) {
+            xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
+        }
+    }
+}
+
 /* Initialise Xen */
 
 int xen_init(int smp_cpus)
diff --git a/xen-stub.c b/xen-stub.c
index a6d5850..ba95537 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -11,6 +11,19 @@
 #include "qemu-common.h"
 #include "hw/xen.h"
 
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+    return -1;
+}
+
+void xen_piix3_set_irq(void *opaque, int irq_num, int level)
+{
+}
+
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
+{
+}
+
 void pci_xen_platform_init(PCIBus *bus)
 {
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 07/15] piix_pci: Introduces Xen specific call for irq.
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This patch introduces Xen specific call in piix_pci.

The specific part for Xen is in write_config, set_irq and get_pirq.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 hw/piix_pci.c |   28 ++++++++++++++++++++++++++--
 hw/xen.h      |    6 ++++++
 xen-all.c     |   31 +++++++++++++++++++++++++++++++
 xen-stub.c    |   13 +++++++++++++
 4 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 358da58..152fcc0 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -29,6 +29,7 @@
 #include "isa.h"
 #include "sysbus.h"
 #include "range.h"
+#include "xen.h"
 
 /*
  * I440FX chipset data sheet.
@@ -151,6 +152,13 @@ static void i440fx_write_config(PCIDevice *dev,
     }
 }
 
+static void i440fx_write_config_xen(PCIDevice *dev,
+                                    uint32_t address, uint32_t val, int len)
+{
+    xen_piix_pci_write_config_client(address, val, len);
+    i440fx_write_config(dev, address, val, len);
+}
+
 static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 {
     PCII440FXState *d = opaque;
@@ -230,13 +238,21 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
     s->bus = b;
     qdev_init_nofail(dev);
 
-    d = pci_create_simple(b, 0, "i440FX");
+    if (xen_enabled()) {
+        d = pci_create_simple(b, 0, "i440FX-xen");
+    } else {
+        d = pci_create_simple(b, 0, "i440FX");
+    }
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
 
     piix3 = DO_UPCAST(PIIX3State, dev,
                       pci_create_simple_multifunction(b, -1, true, "PIIX3"));
     piix3->pic = pic;
-    pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
+    if (xen_enabled()) {
+        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, 4);
+    } else {
+        pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
+    }
     (*pi440fx_state)->piix3 = piix3;
 
     *piix3_devfn = piix3->dev.devfn;
@@ -352,6 +368,14 @@ static PCIDeviceInfo i440fx_info[] = {
         .init         = i440fx_initfn,
         .config_write = i440fx_write_config,
     },{
+        .qdev.name    = "i440FX-xen",
+        .qdev.desc    = "Host bridge",
+        .qdev.size    = sizeof(PCII440FXState),
+        .qdev.vmsd    = &vmstate_i440fx,
+        .qdev.no_user = 1,
+        .init         = i440fx_initfn,
+        .config_write = i440fx_write_config_xen,
+    },{
         .qdev.name    = "PIIX3",
         .qdev.desc    = "ISA bridge",
         .qdev.size    = sizeof(PIIX3State),
diff --git a/hw/xen.h b/hw/xen.h
index 53a2ca4..2a53f8b 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -8,6 +8,8 @@
  */
 #include <inttypes.h>
 
+#include "qemu-common.h"
+
 /* xen-machine.c */
 enum xen_mode {
     XEN_EMULATE = 0,  // xen emulation, using xenner (default)
@@ -29,6 +31,10 @@ static inline int xen_enabled(void)
 #endif
 }
 
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
+void xen_piix3_set_irq(void *opaque, int irq_num, int level);
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
+
 void pci_xen_platform_init(PCIBus *bus);
 
 int xen_init(int smp_cpus);
diff --git a/xen-all.c b/xen-all.c
index 8d77d42..123decb 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -8,9 +8,40 @@
 
 #include "config.h"
 
+#include "hw/pci.h"
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
+/* Xen specific function for piix pci */
+
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+    return irq_num + ((pci_dev->devfn >> 3) << 2);
+}
+
+void xen_piix3_set_irq(void *opaque, int irq_num, int level)
+{
+    xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num >> 2,
+                              irq_num & 3, level);
+}
+
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
+{
+    int i;
+
+    /* Scan for updates to PCI link routes (0x60-0x63). */
+    for (i = 0; i < len; i++) {
+        uint8_t v = (val >> (8 * i)) & 0xff;
+        if (v & 0x80) {
+            v = 0;
+        }
+        v &= 0xf;
+        if (((address + i) >= 0x60) && ((address + i) <= 0x63)) {
+            xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
+        }
+    }
+}
+
 /* Initialise Xen */
 
 int xen_init(int smp_cpus)
diff --git a/xen-stub.c b/xen-stub.c
index a6d5850..ba95537 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -11,6 +11,19 @@
 #include "qemu-common.h"
 #include "hw/xen.h"
 
+int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+    return -1;
+}
+
+void xen_piix3_set_irq(void *opaque, int irq_num, int level)
+{
+}
+
+void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
+{
+}
+
 void pci_xen_platform_init(PCIBus *bus)
 {
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 08/15] xen: Introduce Xen Interrupt Controller
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Every set_irq call makes a Xen hypercall.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/pc_piix.c |    8 ++++++--
 hw/xen.h     |    2 ++
 xen-all.c    |   12 ++++++++++++
 xen-stub.c   |    5 +++++
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 765877c..27d9030 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -98,8 +98,12 @@ static void pc_init1(ram_addr_t ram_size,
     pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename,
                    &below_4g_mem_size, &above_4g_mem_size);
 
-    cpu_irq = pc_allocate_cpu_irq();
-    i8259 = i8259_init(cpu_irq[0]);
+    if (!xen_enabled()) {
+        cpu_irq = pc_allocate_cpu_irq();
+        i8259 = i8259_init(cpu_irq[0]);
+    } else {
+        i8259 = xen_interrupt_controller_init();
+    }
     isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
     isa_irq_state->i8259 = i8259;
     if (pci_enabled) {
diff --git a/hw/xen.h b/hw/xen.h
index 2a53f8b..37d7b99 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -35,6 +35,8 @@ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
 
+qemu_irq *xen_interrupt_controller_init(void);
+
 void pci_xen_platform_init(PCIBus *bus);
 
 int xen_init(int smp_cpus);
diff --git a/xen-all.c b/xen-all.c
index 123decb..73149f2 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -42,6 +42,18 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+/* Xen Interrupt Controller */
+
+static void xen_set_irq(void *opaque, int irq, int level)
+{
+    xc_hvm_set_isa_irq_level(xen_xc, xen_domid, irq, level);
+}
+
+qemu_irq *xen_interrupt_controller_init(void)
+{
+    return qemu_allocate_irqs(xen_set_irq, NULL, 16);
+}
+
 /* Initialise Xen */
 
 int xen_init(int smp_cpus)
diff --git a/xen-stub.c b/xen-stub.c
index ba95537..bc2ae12 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -24,6 +24,11 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
 {
 }
 
+qemu_irq *xen_interrupt_controller_init(void)
+{
+    return NULL;
+}
+
 void pci_xen_platform_init(PCIBus *bus)
 {
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 08/15] xen: Introduce Xen Interrupt Controller
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Every set_irq call makes a Xen hypercall.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/pc_piix.c |    8 ++++++--
 hw/xen.h     |    2 ++
 xen-all.c    |   12 ++++++++++++
 xen-stub.c   |    5 +++++
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 765877c..27d9030 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -98,8 +98,12 @@ static void pc_init1(ram_addr_t ram_size,
     pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename,
                    &below_4g_mem_size, &above_4g_mem_size);
 
-    cpu_irq = pc_allocate_cpu_irq();
-    i8259 = i8259_init(cpu_irq[0]);
+    if (!xen_enabled()) {
+        cpu_irq = pc_allocate_cpu_irq();
+        i8259 = i8259_init(cpu_irq[0]);
+    } else {
+        i8259 = xen_interrupt_controller_init();
+    }
     isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
     isa_irq_state->i8259 = i8259;
     if (pci_enabled) {
diff --git a/hw/xen.h b/hw/xen.h
index 2a53f8b..37d7b99 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -35,6 +35,8 @@ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
 
+qemu_irq *xen_interrupt_controller_init(void);
+
 void pci_xen_platform_init(PCIBus *bus);
 
 int xen_init(int smp_cpus);
diff --git a/xen-all.c b/xen-all.c
index 123decb..73149f2 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -42,6 +42,18 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+/* Xen Interrupt Controller */
+
+static void xen_set_irq(void *opaque, int irq, int level)
+{
+    xc_hvm_set_isa_irq_level(xen_xc, xen_domid, irq, level);
+}
+
+qemu_irq *xen_interrupt_controller_init(void)
+{
+    return qemu_allocate_irqs(xen_set_irq, NULL, 16);
+}
+
 /* Initialise Xen */
 
 int xen_init(int smp_cpus)
diff --git a/xen-stub.c b/xen-stub.c
index ba95537..bc2ae12 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -24,6 +24,11 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
 {
 }
 
+qemu_irq *xen_interrupt_controller_init(void)
+{
+    return NULL;
+}
+
 void pci_xen_platform_init(PCIBus *bus)
 {
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 09/15] xen: Introduce the Xen mapcache
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Jun Nakajima, Stefano Stabellini

From: Jun Nakajima <jun.nakajima@intel.com>

On IA32 host or IA32 PAE host, at present, generally, we can't create
an HVM guest with more than 2G memory, because generally it's almost
impossible for Qemu to find a large enough and consecutive virtual
address space to map an HVM guest's whole physical address space.
The attached patch fixes this issue using dynamic mapping based on
little blocks of memory.

Each call to qemu_get_ram_ptr makes a call to qemu_map_cache with the
lock option, so mapcache will not unmap these ram_ptr.

Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 Makefile.target     |    3 +
 configure           |    3 +
 exec.c              |   40 ++++++-
 hw/xen.h            |   13 ++
 xen-all.c           |   64 +++++++++++
 xen-mapcache-stub.c |   40 +++++++
 xen-mapcache.c      |  310 +++++++++++++++++++++++++++++++++++++++++++++++++++
 xen-mapcache.h      |   22 ++++
 xen-stub.c          |    4 +
 9 files changed, 495 insertions(+), 4 deletions(-)
 create mode 100644 xen-mapcache-stub.c
 create mode 100644 xen-mapcache.c
 create mode 100644 xen-mapcache.h

diff --git a/Makefile.target b/Makefile.target
index 7a4fd72..b2edcd4 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -207,9 +207,12 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
 # xen support
+CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y)
 obj-$(CONFIG_XEN) += xen_interfaces.o
 obj-$(CONFIG_XEN) += xen-all.o
 obj-$(CONFIG_NO_XEN) += xen-stub.o
+obj-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o
+obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o
 
 # xen backend driver support
 obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
diff --git a/configure b/configure
index fde9bad..c9a13e1 100755
--- a/configure
+++ b/configure
@@ -3069,6 +3069,9 @@ case "$target_arch2" in
       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
+      if test "$cpu" = "i386" -o "$cpu" = "x86_64"; then
+          echo "CONFIG_XEN_MAPCACHE=y" >> $config_target_mak
+      fi
     fi
 esac
 case "$target_arch2" in
diff --git a/exec.c b/exec.c
index e950df2..3b137dc 100644
--- a/exec.c
+++ b/exec.c
@@ -32,6 +32,7 @@
 #include "hw/qdev.h"
 #include "osdep.h"
 #include "kvm.h"
+#include "hw/xen.h"
 #include "qemu-timer.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
@@ -51,6 +52,8 @@
 #include <libutil.h>
 #endif
 #endif
+#else /* !CONFIG_USER_ONLY */
+#include "xen-mapcache.h"
 #endif
 
 //#define DEBUG_TB_INVALIDATE
@@ -2835,6 +2838,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
         }
     }
 
+    new_block->offset = find_ram_offset(size);
     if (host) {
         new_block->host = host;
     } else {
@@ -2856,13 +2860,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
                                    PROT_EXEC|PROT_READ|PROT_WRITE,
                                    MAP_SHARED | MAP_ANONYMOUS, -1, 0);
 #else
-            new_block->host = qemu_vmalloc(size);
+            if (xen_mapcache_enabled()) {
+                xen_ram_alloc(new_block->offset, size);
+            } else {
+                new_block->host = qemu_vmalloc(size);
+            }
 #endif
             qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
         }
     }
-
-    new_block->offset = find_ram_offset(size);
     new_block->length = size;
 
     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
@@ -2903,7 +2909,11 @@ void qemu_ram_free(ram_addr_t addr)
 #if defined(TARGET_S390X) && defined(CONFIG_KVM)
                 munmap(block->host, block->length);
 #else
-                qemu_vfree(block->host);
+                if (xen_mapcache_enabled()) {
+                    qemu_invalidate_entry(block->host);
+                } else {
+                    qemu_vfree(block->host);
+                }
 #endif
             }
             qemu_free(block);
@@ -2929,6 +2939,15 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
         if (addr - block->offset < block->length) {
             QLIST_REMOVE(block, next);
             QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
+            if (xen_mapcache_enabled()) {
+                /* We need to check if the requested address is in the RAM
+                 * because we don't want to map the entire memory in QEMU.
+                 */
+                if (block->offset == 0) {
+                    return qemu_map_cache(addr, 0, 1);
+                }
+                block->host = qemu_map_cache(block->offset, block->length, 1);
+            }
             return block->host + (addr - block->offset);
         }
     }
@@ -2964,11 +2983,21 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
     uint8_t *host = ptr;
 
     QLIST_FOREACH(block, &ram_list.blocks, next) {
+        /* This case append when the block is not mapped. */
+        if (block->host == NULL) {
+            continue;
+        }
         if (host - block->host < block->length) {
             *ram_addr = block->offset + (host - block->host);
             return 0;
         }
     }
+
+    if (xen_mapcache_enabled()) {
+        *ram_addr = qemu_ram_addr_from_mapcache(ptr);
+        return 0;
+    }
+
     return -1;
 }
 
@@ -3879,6 +3908,9 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
     if (is_write) {
         cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len);
     }
+    if (xen_enabled()) {
+        qemu_invalidate_entry(buffer);
+    }
     qemu_vfree(bounce.buffer);
     bounce.buffer = NULL;
     cpu_notify_map_clients();
diff --git a/hw/xen.h b/hw/xen.h
index 37d7b99..a67b5bd 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -31,6 +31,15 @@ static inline int xen_enabled(void)
 #endif
 }
 
+static inline int xen_mapcache_enabled(void)
+{
+#ifdef CONFIG_XEN_MAPCACHE
+    return xen_enabled();
+#else
+    return 0;
+#endif
+}
+
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
@@ -41,6 +50,10 @@ void pci_xen_platform_init(PCIBus *bus);
 
 int xen_init(int smp_cpus);
 
+#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size);
+#endif
+
 #if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
 #  define HVM_MAX_VCPUS 32
 #endif
diff --git a/xen-all.c b/xen-all.c
index 73149f2..84ed333 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -12,6 +12,8 @@
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
+#include "xen-mapcache.h"
+
 /* Xen specific function for piix pci */
 
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
@@ -54,6 +56,64 @@ qemu_irq *xen_interrupt_controller_init(void)
     return qemu_allocate_irqs(xen_set_irq, NULL, 16);
 }
 
+
+/* Memory Ops */
+
+static void xen_ram_init(ram_addr_t ram_size)
+{
+    RAMBlock *new_block;
+    ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
+
+    new_block = qemu_mallocz(sizeof (*new_block));
+    pstrcpy(new_block->idstr, sizeof (new_block->idstr), "xen.ram");
+    new_block->host = NULL;
+    new_block->offset = 0;
+    new_block->length = ram_size;
+
+    QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
+
+    ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
+                                       new_block->length >> TARGET_PAGE_BITS);
+    memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
+           0xff, new_block->length >> TARGET_PAGE_BITS);
+
+    if (ram_size >= 0xe0000000 ) {
+        above_4g_mem_size = ram_size - 0xe0000000;
+        below_4g_mem_size = 0xe0000000;
+    } else {
+        below_4g_mem_size = ram_size;
+    }
+
+    cpu_register_physical_memory(0, below_4g_mem_size, new_block->offset);
+#if TARGET_PHYS_ADDR_BITS > 32
+    if (above_4g_mem_size > 0) {
+        cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
+                                     new_block->offset + below_4g_mem_size);
+    }
+#endif
+}
+
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
+{
+    unsigned long nr_pfn;
+    xen_pfn_t *pfn_list;
+    int i;
+
+    nr_pfn = size >> TARGET_PAGE_BITS;
+    pfn_list = qemu_malloc(sizeof (*pfn_list) * nr_pfn);
+
+    for (i = 0; i < nr_pfn; i++) {
+        pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
+    }
+
+    if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
+        hw_error("xen: failed to populate ram at %lx", ram_addr);
+    }
+
+    qemu_free(pfn_list);
+}
+
+
 /* Initialise Xen */
 
 int xen_init(int smp_cpus)
@@ -68,5 +128,9 @@ int xen_init(int smp_cpus)
         return -1;
     }
 
+    /* Init RAM management */
+    qemu_map_cache_init();
+    xen_ram_init(ram_size);
+
     return 0;
 }
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
new file mode 100644
index 0000000..541bee6
--- /dev/null
+++ b/xen-mapcache-stub.c
@@ -0,0 +1,40 @@
+/*
+ * 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.h"
+
+#include "exec-all.h"
+#include "qemu-common.h"
+#include "cpu-common.h"
+#include "xen-mapcache.h"
+
+void qemu_map_cache_init(void)
+{
+}
+
+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock)
+{
+    return qemu_get_ram_ptr(phys_addr);
+}
+
+void qemu_map_cache_unlock(void *buffer)
+{
+}
+
+ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
+{
+    return -1;
+}
+
+void qemu_invalidate_map_cache(void)
+{
+}
+
+void qemu_invalidate_entry(uint8_t *buffer)
+{
+}
diff --git a/xen-mapcache.c b/xen-mapcache.c
new file mode 100644
index 0000000..43a5ed9
--- /dev/null
+++ b/xen-mapcache.c
@@ -0,0 +1,310 @@
+/*
+ * 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.h"
+
+#include <sys/resource.h>
+
+#include "hw/xen_backend.h"
+#include "blockdev.h"
+
+#include <xen/hvm/params.h>
+#include <sys/mman.h>
+
+#include "xen-mapcache.h"
+
+
+//#define MAPCACHE_DEBUG
+
+#ifdef MAPCACHE_DEBUG
+#  define DPRINTF(fmt, ...) do { \
+    fprintf(stderr, "xen_mapcache: " fmt, ## __VA_ARGS__); \
+} while (0)
+#else
+#  define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+#if defined(__i386__)
+#  define MCACHE_BUCKET_SHIFT 16
+#elif defined(__x86_64__)
+#  define MCACHE_BUCKET_SHIFT 20
+#endif
+#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define BITS_TO_LONGS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG)
+#define DECLARE_BITMAP(name, bits) unsigned long name[BITS_TO_LONGS(bits)]
+
+typedef struct MapCacheEntry {
+    target_phys_addr_t paddr_index;
+    uint8_t *vaddr_base;
+    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT);
+    uint8_t lock;
+    struct MapCacheEntry *next;
+} MapCacheEntry;
+
+typedef struct MapCacheRev {
+    uint8_t *vaddr_req;
+    target_phys_addr_t paddr_index;
+    QTAILQ_ENTRY(MapCacheRev) next;
+} MapCacheRev;
+
+typedef struct MapCache {
+    MapCacheEntry *entry;
+    unsigned long nr_buckets;
+    QTAILQ_HEAD(map_cache_head, MapCacheRev) locked_entries;
+
+    /* For most cases (>99.9%), the page address is the same. */
+    target_phys_addr_t last_address_index;
+    uint8_t *last_address_vaddr;
+    unsigned long max_mcache_size;
+    unsigned int mcache_bucket_shift;
+} MapCache;
+
+static MapCache *mapcache;
+
+static inline int test_bit(unsigned int bit, const unsigned long *map)
+{
+    return !!((map)[(bit) / BITS_PER_LONG] & (1UL << ((bit) % BITS_PER_LONG)));
+}
+
+void qemu_map_cache_init(void)
+{
+    unsigned long size;
+    struct rlimit rlimit_as;
+
+    mapcache = qemu_mallocz(sizeof (MapCache));
+
+    QTAILQ_INIT(&mapcache->locked_entries);
+    mapcache->last_address_index = -1;
+
+    getrlimit(RLIMIT_AS, &rlimit_as);
+    rlimit_as.rlim_cur = rlimit_as.rlim_max;
+    setrlimit(RLIMIT_AS, &rlimit_as);
+    mapcache->max_mcache_size = rlimit_as.rlim_max;
+
+    mapcache->nr_buckets =
+        (((mapcache->max_mcache_size >> XC_PAGE_SHIFT) +
+          (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
+         (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
+
+    size = mapcache->nr_buckets * sizeof (MapCacheEntry);
+    size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
+    DPRINTF("qemu_map_cache_init, nr_buckets = %lx size %lu\n", mapcache->nr_buckets, size);
+    mapcache->entry = qemu_mallocz(size);
+}
+
+static void qemu_remap_bucket(MapCacheEntry *entry,
+                              target_phys_addr_t size,
+                              target_phys_addr_t address_index)
+{
+    uint8_t *vaddr_base;
+    xen_pfn_t *pfns;
+    int *err;
+    unsigned int i, j;
+    target_phys_addr_t nb_pfn = size >> XC_PAGE_SHIFT;
+
+    pfns = qemu_mallocz(nb_pfn * sizeof (xen_pfn_t));
+    err = qemu_mallocz(nb_pfn * sizeof (int));
+
+    if (entry->vaddr_base != NULL) {
+        if (munmap(entry->vaddr_base, size) != 0) {
+            perror("unmap fails");
+            exit(-1);
+        }
+    }
+
+    for (i = 0; i < nb_pfn; i++) {
+        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
+    }
+
+    vaddr_base = xc_ops.map_foreign_bulk(xen_xc, xen_domid, PROT_READ|PROT_WRITE,
+                                         pfns, err, nb_pfn);
+    if (vaddr_base == NULL) {
+        perror("xc_map_foreign_bulk");
+        exit(-1);
+    }
+
+    entry->vaddr_base = vaddr_base;
+    entry->paddr_index = address_index;
+
+    for (i = 0; i < nb_pfn; i += BITS_PER_LONG) {
+        unsigned long word = 0;
+        if ((i + BITS_PER_LONG) > nb_pfn) {
+            j = nb_pfn % BITS_PER_LONG;
+        } else {
+            j = BITS_PER_LONG;
+        }
+        while (j > 0) {
+            word = (word << 1) | !err[i + --j];
+        }
+        entry->valid_mapping[i / BITS_PER_LONG] = word;
+    }
+
+    qemu_free(pfns);
+    qemu_free(err);
+}
+
+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock)
+{
+    MapCacheEntry *entry, *pentry = NULL;
+    target_phys_addr_t address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    if (address_index == mapcache->last_address_index && !lock) {
+        return mapcache->last_address_vaddr + address_offset;
+    }
+
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+
+    while (entry && entry->lock && entry->paddr_index != address_index && entry->vaddr_base) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        entry = qemu_mallocz(sizeof (MapCacheEntry));
+        pentry->next = entry;
+        qemu_remap_bucket(entry, size ? : MCACHE_BUCKET_SIZE, address_index);
+    } else if (!entry->lock) {
+        if (!entry->vaddr_base || entry->paddr_index != address_index ||
+            !test_bit(address_offset >> XC_PAGE_SHIFT, entry->valid_mapping)) {
+            qemu_remap_bucket(entry, size ? : MCACHE_BUCKET_SIZE, address_index);
+        }
+    }
+
+    if (!test_bit(address_offset >> XC_PAGE_SHIFT, entry->valid_mapping)) {
+        mapcache->last_address_index = -1;
+        return NULL;
+    }
+
+    mapcache->last_address_index = address_index;
+    mapcache->last_address_vaddr = entry->vaddr_base;
+    if (lock) {
+        MapCacheRev *reventry = qemu_mallocz(sizeof(MapCacheRev));
+        entry->lock++;
+        reventry->vaddr_req = mapcache->last_address_vaddr + address_offset;
+        reventry->paddr_index = mapcache->last_address_index;
+        QTAILQ_INSERT_TAIL(&mapcache->locked_entries, reventry, next);
+    }
+
+    return mapcache->last_address_vaddr + address_offset;
+}
+
+ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
+{
+    MapCacheRev *reventry;
+    target_phys_addr_t paddr_index;
+    int found = 0;
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        if (reventry->vaddr_req == ptr) {
+            paddr_index = reventry->paddr_index;
+            found = 1;
+            break;
+        }
+    }
+    if (!found) {
+        fprintf(stderr, "qemu_ram_addr_from_mapcache, could not find %p\n", ptr);
+        QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+            DPRINTF("   "TARGET_FMT_plx" -> %p is present\n", reventry->paddr_index,
+                    reventry->vaddr_req);
+        }
+        abort();
+        return 0;
+    }
+
+    return paddr_index << MCACHE_BUCKET_SHIFT;
+}
+
+void qemu_invalidate_entry(uint8_t *buffer)
+{
+    MapCacheEntry *entry = NULL, *pentry = NULL;
+    MapCacheRev *reventry;
+    target_phys_addr_t paddr_index;
+    int found = 0;
+
+    if (mapcache->last_address_vaddr == buffer) {
+        mapcache->last_address_index = -1;
+    }
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        if (reventry->vaddr_req == buffer) {
+            paddr_index = reventry->paddr_index;
+            found = 1;
+            break;
+        }
+    }
+    if (!found) {
+        DPRINTF("qemu_invalidate_entry, could not find %p\n", buffer);
+        QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+            DPRINTF("   "TARGET_FMT_plx" -> %p is present\n", reventry->paddr_index, reventry->vaddr_req);
+        }
+        return;
+    }
+    QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next);
+    qemu_free(reventry);
+
+    entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
+    while (entry && entry->paddr_index != paddr_index) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        DPRINTF("Trying to unmap address %p that is not in the mapcache!\n", buffer);
+        return;
+    }
+    entry->lock--;
+    if (entry->lock > 0 || pentry == NULL) {
+        return;
+    }
+
+    pentry->next = entry->next;
+    if (munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE) != 0) {
+        perror("unmap fails");
+        exit(-1);
+    }
+    qemu_free(entry);
+}
+
+void qemu_invalidate_map_cache(void)
+{
+    unsigned long i;
+    MapCacheRev *reventry;
+
+    /* Flush pending AIO before destroying the mapcache */
+    qemu_aio_flush();
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        DPRINTF("There should be no locked mappings at this time, "
+                "but "TARGET_FMT_plx" -> %p is present\n",
+                reventry->paddr_index, reventry->vaddr_req);
+    }
+
+    mapcache_lock();
+
+    for (i = 0; i < mapcache->nr_buckets; i++) {
+        MapCacheEntry *entry = &mapcache->entry[i];
+
+        if (entry->vaddr_base == NULL) {
+            continue;
+        }
+
+        if (munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE) != 0) {
+            perror("unmap fails");
+            exit(-1);
+        }
+
+        entry->paddr_index = 0;
+        entry->vaddr_base = NULL;
+    }
+
+    mapcache->last_address_index = -1;
+    mapcache->last_address_vaddr = NULL;
+
+    mapcache_unlock();
+}
diff --git a/xen-mapcache.h b/xen-mapcache.h
new file mode 100644
index 0000000..ef3717f
--- /dev/null
+++ b/xen-mapcache.h
@@ -0,0 +1,22 @@
+/*
+ * 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 XEN_MAPCACHE_H
+#define XEN_MAPCACHE_H
+
+void     qemu_map_cache_init(void);
+uint8_t  *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock);
+void     qemu_map_cache_unlock(void *phys_addr);
+ram_addr_t qemu_ram_addr_from_mapcache(void *ptr);
+void     qemu_invalidate_entry(uint8_t *buffer);
+void     qemu_invalidate_map_cache(void);
+
+#define mapcache_lock()   ((void)0)
+#define mapcache_unlock() ((void)0)
+
+#endif /* !XEN_MAPCACHE_H */
diff --git a/xen-stub.c b/xen-stub.c
index bc2ae12..86486f8 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -24,6 +24,10 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
 {
 }
 
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
+{
+}
+
 qemu_irq *xen_interrupt_controller_init(void)
 {
     return NULL;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 09/15] xen: Introduce the Xen mapcache
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel
  Cc: Anthony PERARD, Xen Devel, Jun Nakajima, Anthony Liguori,
	Stefano Stabellini

From: Jun Nakajima <jun.nakajima@intel.com>

On IA32 host or IA32 PAE host, at present, generally, we can't create
an HVM guest with more than 2G memory, because generally it's almost
impossible for Qemu to find a large enough and consecutive virtual
address space to map an HVM guest's whole physical address space.
The attached patch fixes this issue using dynamic mapping based on
little blocks of memory.

Each call to qemu_get_ram_ptr makes a call to qemu_map_cache with the
lock option, so mapcache will not unmap these ram_ptr.

Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 Makefile.target     |    3 +
 configure           |    3 +
 exec.c              |   40 ++++++-
 hw/xen.h            |   13 ++
 xen-all.c           |   64 +++++++++++
 xen-mapcache-stub.c |   40 +++++++
 xen-mapcache.c      |  310 +++++++++++++++++++++++++++++++++++++++++++++++++++
 xen-mapcache.h      |   22 ++++
 xen-stub.c          |    4 +
 9 files changed, 495 insertions(+), 4 deletions(-)
 create mode 100644 xen-mapcache-stub.c
 create mode 100644 xen-mapcache.c
 create mode 100644 xen-mapcache.h

diff --git a/Makefile.target b/Makefile.target
index 7a4fd72..b2edcd4 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -207,9 +207,12 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
 # xen support
+CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y)
 obj-$(CONFIG_XEN) += xen_interfaces.o
 obj-$(CONFIG_XEN) += xen-all.o
 obj-$(CONFIG_NO_XEN) += xen-stub.o
+obj-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o
+obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o
 
 # xen backend driver support
 obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
diff --git a/configure b/configure
index fde9bad..c9a13e1 100755
--- a/configure
+++ b/configure
@@ -3069,6 +3069,9 @@ case "$target_arch2" in
       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
+      if test "$cpu" = "i386" -o "$cpu" = "x86_64"; then
+          echo "CONFIG_XEN_MAPCACHE=y" >> $config_target_mak
+      fi
     fi
 esac
 case "$target_arch2" in
diff --git a/exec.c b/exec.c
index e950df2..3b137dc 100644
--- a/exec.c
+++ b/exec.c
@@ -32,6 +32,7 @@
 #include "hw/qdev.h"
 #include "osdep.h"
 #include "kvm.h"
+#include "hw/xen.h"
 #include "qemu-timer.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
@@ -51,6 +52,8 @@
 #include <libutil.h>
 #endif
 #endif
+#else /* !CONFIG_USER_ONLY */
+#include "xen-mapcache.h"
 #endif
 
 //#define DEBUG_TB_INVALIDATE
@@ -2835,6 +2838,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
         }
     }
 
+    new_block->offset = find_ram_offset(size);
     if (host) {
         new_block->host = host;
     } else {
@@ -2856,13 +2860,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
                                    PROT_EXEC|PROT_READ|PROT_WRITE,
                                    MAP_SHARED | MAP_ANONYMOUS, -1, 0);
 #else
-            new_block->host = qemu_vmalloc(size);
+            if (xen_mapcache_enabled()) {
+                xen_ram_alloc(new_block->offset, size);
+            } else {
+                new_block->host = qemu_vmalloc(size);
+            }
 #endif
             qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
         }
     }
-
-    new_block->offset = find_ram_offset(size);
     new_block->length = size;
 
     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
@@ -2903,7 +2909,11 @@ void qemu_ram_free(ram_addr_t addr)
 #if defined(TARGET_S390X) && defined(CONFIG_KVM)
                 munmap(block->host, block->length);
 #else
-                qemu_vfree(block->host);
+                if (xen_mapcache_enabled()) {
+                    qemu_invalidate_entry(block->host);
+                } else {
+                    qemu_vfree(block->host);
+                }
 #endif
             }
             qemu_free(block);
@@ -2929,6 +2939,15 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
         if (addr - block->offset < block->length) {
             QLIST_REMOVE(block, next);
             QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
+            if (xen_mapcache_enabled()) {
+                /* We need to check if the requested address is in the RAM
+                 * because we don't want to map the entire memory in QEMU.
+                 */
+                if (block->offset == 0) {
+                    return qemu_map_cache(addr, 0, 1);
+                }
+                block->host = qemu_map_cache(block->offset, block->length, 1);
+            }
             return block->host + (addr - block->offset);
         }
     }
@@ -2964,11 +2983,21 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
     uint8_t *host = ptr;
 
     QLIST_FOREACH(block, &ram_list.blocks, next) {
+        /* This case append when the block is not mapped. */
+        if (block->host == NULL) {
+            continue;
+        }
         if (host - block->host < block->length) {
             *ram_addr = block->offset + (host - block->host);
             return 0;
         }
     }
+
+    if (xen_mapcache_enabled()) {
+        *ram_addr = qemu_ram_addr_from_mapcache(ptr);
+        return 0;
+    }
+
     return -1;
 }
 
@@ -3879,6 +3908,9 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
     if (is_write) {
         cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len);
     }
+    if (xen_enabled()) {
+        qemu_invalidate_entry(buffer);
+    }
     qemu_vfree(bounce.buffer);
     bounce.buffer = NULL;
     cpu_notify_map_clients();
diff --git a/hw/xen.h b/hw/xen.h
index 37d7b99..a67b5bd 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -31,6 +31,15 @@ static inline int xen_enabled(void)
 #endif
 }
 
+static inline int xen_mapcache_enabled(void)
+{
+#ifdef CONFIG_XEN_MAPCACHE
+    return xen_enabled();
+#else
+    return 0;
+#endif
+}
+
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
@@ -41,6 +50,10 @@ void pci_xen_platform_init(PCIBus *bus);
 
 int xen_init(int smp_cpus);
 
+#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size);
+#endif
+
 #if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
 #  define HVM_MAX_VCPUS 32
 #endif
diff --git a/xen-all.c b/xen-all.c
index 73149f2..84ed333 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -12,6 +12,8 @@
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
+#include "xen-mapcache.h"
+
 /* Xen specific function for piix pci */
 
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
@@ -54,6 +56,64 @@ qemu_irq *xen_interrupt_controller_init(void)
     return qemu_allocate_irqs(xen_set_irq, NULL, 16);
 }
 
+
+/* Memory Ops */
+
+static void xen_ram_init(ram_addr_t ram_size)
+{
+    RAMBlock *new_block;
+    ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
+
+    new_block = qemu_mallocz(sizeof (*new_block));
+    pstrcpy(new_block->idstr, sizeof (new_block->idstr), "xen.ram");
+    new_block->host = NULL;
+    new_block->offset = 0;
+    new_block->length = ram_size;
+
+    QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
+
+    ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
+                                       new_block->length >> TARGET_PAGE_BITS);
+    memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
+           0xff, new_block->length >> TARGET_PAGE_BITS);
+
+    if (ram_size >= 0xe0000000 ) {
+        above_4g_mem_size = ram_size - 0xe0000000;
+        below_4g_mem_size = 0xe0000000;
+    } else {
+        below_4g_mem_size = ram_size;
+    }
+
+    cpu_register_physical_memory(0, below_4g_mem_size, new_block->offset);
+#if TARGET_PHYS_ADDR_BITS > 32
+    if (above_4g_mem_size > 0) {
+        cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
+                                     new_block->offset + below_4g_mem_size);
+    }
+#endif
+}
+
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
+{
+    unsigned long nr_pfn;
+    xen_pfn_t *pfn_list;
+    int i;
+
+    nr_pfn = size >> TARGET_PAGE_BITS;
+    pfn_list = qemu_malloc(sizeof (*pfn_list) * nr_pfn);
+
+    for (i = 0; i < nr_pfn; i++) {
+        pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
+    }
+
+    if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
+        hw_error("xen: failed to populate ram at %lx", ram_addr);
+    }
+
+    qemu_free(pfn_list);
+}
+
+
 /* Initialise Xen */
 
 int xen_init(int smp_cpus)
@@ -68,5 +128,9 @@ int xen_init(int smp_cpus)
         return -1;
     }
 
+    /* Init RAM management */
+    qemu_map_cache_init();
+    xen_ram_init(ram_size);
+
     return 0;
 }
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
new file mode 100644
index 0000000..541bee6
--- /dev/null
+++ b/xen-mapcache-stub.c
@@ -0,0 +1,40 @@
+/*
+ * 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.h"
+
+#include "exec-all.h"
+#include "qemu-common.h"
+#include "cpu-common.h"
+#include "xen-mapcache.h"
+
+void qemu_map_cache_init(void)
+{
+}
+
+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock)
+{
+    return qemu_get_ram_ptr(phys_addr);
+}
+
+void qemu_map_cache_unlock(void *buffer)
+{
+}
+
+ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
+{
+    return -1;
+}
+
+void qemu_invalidate_map_cache(void)
+{
+}
+
+void qemu_invalidate_entry(uint8_t *buffer)
+{
+}
diff --git a/xen-mapcache.c b/xen-mapcache.c
new file mode 100644
index 0000000..43a5ed9
--- /dev/null
+++ b/xen-mapcache.c
@@ -0,0 +1,310 @@
+/*
+ * 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.h"
+
+#include <sys/resource.h>
+
+#include "hw/xen_backend.h"
+#include "blockdev.h"
+
+#include <xen/hvm/params.h>
+#include <sys/mman.h>
+
+#include "xen-mapcache.h"
+
+
+//#define MAPCACHE_DEBUG
+
+#ifdef MAPCACHE_DEBUG
+#  define DPRINTF(fmt, ...) do { \
+    fprintf(stderr, "xen_mapcache: " fmt, ## __VA_ARGS__); \
+} while (0)
+#else
+#  define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+#if defined(__i386__)
+#  define MCACHE_BUCKET_SHIFT 16
+#elif defined(__x86_64__)
+#  define MCACHE_BUCKET_SHIFT 20
+#endif
+#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define BITS_TO_LONGS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG)
+#define DECLARE_BITMAP(name, bits) unsigned long name[BITS_TO_LONGS(bits)]
+
+typedef struct MapCacheEntry {
+    target_phys_addr_t paddr_index;
+    uint8_t *vaddr_base;
+    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT);
+    uint8_t lock;
+    struct MapCacheEntry *next;
+} MapCacheEntry;
+
+typedef struct MapCacheRev {
+    uint8_t *vaddr_req;
+    target_phys_addr_t paddr_index;
+    QTAILQ_ENTRY(MapCacheRev) next;
+} MapCacheRev;
+
+typedef struct MapCache {
+    MapCacheEntry *entry;
+    unsigned long nr_buckets;
+    QTAILQ_HEAD(map_cache_head, MapCacheRev) locked_entries;
+
+    /* For most cases (>99.9%), the page address is the same. */
+    target_phys_addr_t last_address_index;
+    uint8_t *last_address_vaddr;
+    unsigned long max_mcache_size;
+    unsigned int mcache_bucket_shift;
+} MapCache;
+
+static MapCache *mapcache;
+
+static inline int test_bit(unsigned int bit, const unsigned long *map)
+{
+    return !!((map)[(bit) / BITS_PER_LONG] & (1UL << ((bit) % BITS_PER_LONG)));
+}
+
+void qemu_map_cache_init(void)
+{
+    unsigned long size;
+    struct rlimit rlimit_as;
+
+    mapcache = qemu_mallocz(sizeof (MapCache));
+
+    QTAILQ_INIT(&mapcache->locked_entries);
+    mapcache->last_address_index = -1;
+
+    getrlimit(RLIMIT_AS, &rlimit_as);
+    rlimit_as.rlim_cur = rlimit_as.rlim_max;
+    setrlimit(RLIMIT_AS, &rlimit_as);
+    mapcache->max_mcache_size = rlimit_as.rlim_max;
+
+    mapcache->nr_buckets =
+        (((mapcache->max_mcache_size >> XC_PAGE_SHIFT) +
+          (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
+         (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
+
+    size = mapcache->nr_buckets * sizeof (MapCacheEntry);
+    size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
+    DPRINTF("qemu_map_cache_init, nr_buckets = %lx size %lu\n", mapcache->nr_buckets, size);
+    mapcache->entry = qemu_mallocz(size);
+}
+
+static void qemu_remap_bucket(MapCacheEntry *entry,
+                              target_phys_addr_t size,
+                              target_phys_addr_t address_index)
+{
+    uint8_t *vaddr_base;
+    xen_pfn_t *pfns;
+    int *err;
+    unsigned int i, j;
+    target_phys_addr_t nb_pfn = size >> XC_PAGE_SHIFT;
+
+    pfns = qemu_mallocz(nb_pfn * sizeof (xen_pfn_t));
+    err = qemu_mallocz(nb_pfn * sizeof (int));
+
+    if (entry->vaddr_base != NULL) {
+        if (munmap(entry->vaddr_base, size) != 0) {
+            perror("unmap fails");
+            exit(-1);
+        }
+    }
+
+    for (i = 0; i < nb_pfn; i++) {
+        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
+    }
+
+    vaddr_base = xc_ops.map_foreign_bulk(xen_xc, xen_domid, PROT_READ|PROT_WRITE,
+                                         pfns, err, nb_pfn);
+    if (vaddr_base == NULL) {
+        perror("xc_map_foreign_bulk");
+        exit(-1);
+    }
+
+    entry->vaddr_base = vaddr_base;
+    entry->paddr_index = address_index;
+
+    for (i = 0; i < nb_pfn; i += BITS_PER_LONG) {
+        unsigned long word = 0;
+        if ((i + BITS_PER_LONG) > nb_pfn) {
+            j = nb_pfn % BITS_PER_LONG;
+        } else {
+            j = BITS_PER_LONG;
+        }
+        while (j > 0) {
+            word = (word << 1) | !err[i + --j];
+        }
+        entry->valid_mapping[i / BITS_PER_LONG] = word;
+    }
+
+    qemu_free(pfns);
+    qemu_free(err);
+}
+
+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock)
+{
+    MapCacheEntry *entry, *pentry = NULL;
+    target_phys_addr_t address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+
+    if (address_index == mapcache->last_address_index && !lock) {
+        return mapcache->last_address_vaddr + address_offset;
+    }
+
+    entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+
+    while (entry && entry->lock && entry->paddr_index != address_index && entry->vaddr_base) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        entry = qemu_mallocz(sizeof (MapCacheEntry));
+        pentry->next = entry;
+        qemu_remap_bucket(entry, size ? : MCACHE_BUCKET_SIZE, address_index);
+    } else if (!entry->lock) {
+        if (!entry->vaddr_base || entry->paddr_index != address_index ||
+            !test_bit(address_offset >> XC_PAGE_SHIFT, entry->valid_mapping)) {
+            qemu_remap_bucket(entry, size ? : MCACHE_BUCKET_SIZE, address_index);
+        }
+    }
+
+    if (!test_bit(address_offset >> XC_PAGE_SHIFT, entry->valid_mapping)) {
+        mapcache->last_address_index = -1;
+        return NULL;
+    }
+
+    mapcache->last_address_index = address_index;
+    mapcache->last_address_vaddr = entry->vaddr_base;
+    if (lock) {
+        MapCacheRev *reventry = qemu_mallocz(sizeof(MapCacheRev));
+        entry->lock++;
+        reventry->vaddr_req = mapcache->last_address_vaddr + address_offset;
+        reventry->paddr_index = mapcache->last_address_index;
+        QTAILQ_INSERT_TAIL(&mapcache->locked_entries, reventry, next);
+    }
+
+    return mapcache->last_address_vaddr + address_offset;
+}
+
+ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
+{
+    MapCacheRev *reventry;
+    target_phys_addr_t paddr_index;
+    int found = 0;
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        if (reventry->vaddr_req == ptr) {
+            paddr_index = reventry->paddr_index;
+            found = 1;
+            break;
+        }
+    }
+    if (!found) {
+        fprintf(stderr, "qemu_ram_addr_from_mapcache, could not find %p\n", ptr);
+        QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+            DPRINTF("   "TARGET_FMT_plx" -> %p is present\n", reventry->paddr_index,
+                    reventry->vaddr_req);
+        }
+        abort();
+        return 0;
+    }
+
+    return paddr_index << MCACHE_BUCKET_SHIFT;
+}
+
+void qemu_invalidate_entry(uint8_t *buffer)
+{
+    MapCacheEntry *entry = NULL, *pentry = NULL;
+    MapCacheRev *reventry;
+    target_phys_addr_t paddr_index;
+    int found = 0;
+
+    if (mapcache->last_address_vaddr == buffer) {
+        mapcache->last_address_index = -1;
+    }
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        if (reventry->vaddr_req == buffer) {
+            paddr_index = reventry->paddr_index;
+            found = 1;
+            break;
+        }
+    }
+    if (!found) {
+        DPRINTF("qemu_invalidate_entry, could not find %p\n", buffer);
+        QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+            DPRINTF("   "TARGET_FMT_plx" -> %p is present\n", reventry->paddr_index, reventry->vaddr_req);
+        }
+        return;
+    }
+    QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next);
+    qemu_free(reventry);
+
+    entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
+    while (entry && entry->paddr_index != paddr_index) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        DPRINTF("Trying to unmap address %p that is not in the mapcache!\n", buffer);
+        return;
+    }
+    entry->lock--;
+    if (entry->lock > 0 || pentry == NULL) {
+        return;
+    }
+
+    pentry->next = entry->next;
+    if (munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE) != 0) {
+        perror("unmap fails");
+        exit(-1);
+    }
+    qemu_free(entry);
+}
+
+void qemu_invalidate_map_cache(void)
+{
+    unsigned long i;
+    MapCacheRev *reventry;
+
+    /* Flush pending AIO before destroying the mapcache */
+    qemu_aio_flush();
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        DPRINTF("There should be no locked mappings at this time, "
+                "but "TARGET_FMT_plx" -> %p is present\n",
+                reventry->paddr_index, reventry->vaddr_req);
+    }
+
+    mapcache_lock();
+
+    for (i = 0; i < mapcache->nr_buckets; i++) {
+        MapCacheEntry *entry = &mapcache->entry[i];
+
+        if (entry->vaddr_base == NULL) {
+            continue;
+        }
+
+        if (munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE) != 0) {
+            perror("unmap fails");
+            exit(-1);
+        }
+
+        entry->paddr_index = 0;
+        entry->vaddr_base = NULL;
+    }
+
+    mapcache->last_address_index = -1;
+    mapcache->last_address_vaddr = NULL;
+
+    mapcache_unlock();
+}
diff --git a/xen-mapcache.h b/xen-mapcache.h
new file mode 100644
index 0000000..ef3717f
--- /dev/null
+++ b/xen-mapcache.h
@@ -0,0 +1,22 @@
+/*
+ * 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 XEN_MAPCACHE_H
+#define XEN_MAPCACHE_H
+
+void     qemu_map_cache_init(void);
+uint8_t  *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock);
+void     qemu_map_cache_unlock(void *phys_addr);
+ram_addr_t qemu_ram_addr_from_mapcache(void *ptr);
+void     qemu_invalidate_entry(uint8_t *buffer);
+void     qemu_invalidate_map_cache(void);
+
+#define mapcache_lock()   ((void)0)
+#define mapcache_unlock() ((void)0)
+
+#endif /* !XEN_MAPCACHE_H */
diff --git a/xen-stub.c b/xen-stub.c
index bc2ae12..86486f8 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -24,6 +24,10 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
 {
 }
 
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
+{
+}
+
 qemu_irq *xen_interrupt_controller_init(void)
 {
     return NULL;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 10/15] configure: Always use 64bits target physical addresses with xen enabled.
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

With MapCache, we can handle a 64b target, even with a 32b host/qemu.
So, we need to have target_phys_addr_t to 64bits.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 configure |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index c9a13e1..76177d8 100755
--- a/configure
+++ b/configure
@@ -3066,6 +3066,7 @@ echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
 case "$target_arch2" in
   i386|x86_64)
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
+      target_phys_bits=64
       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
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 10/15] configure: Always use 64bits target physical addresses with xen enabled.
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

With MapCache, we can handle a 64b target, even with a 32b host/qemu.
So, we need to have target_phys_addr_t to 64bits.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 configure |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index c9a13e1..76177d8 100755
--- a/configure
+++ b/configure
@@ -3066,6 +3066,7 @@ echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
 case "$target_arch2" in
   i386|x86_64)
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
+      target_phys_bits=64
       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
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 11/15] Introduce qemu_put_ram_ptr
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This function allows to unlock a ram_ptr give by qemu_get_ram_ptr. After
a call to qemu_put_ram_ptr, the pointer may be unmap from QEMU when
used with Xen.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 cpu-common.h   |    1 +
 exec.c         |   10 ++++++++++
 xen-mapcache.c |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index 6d4a898..6f935cc 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -55,6 +55,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr);
 /* Same but slower, to use for migration, where the order of
  * RAMBlocks must not change. */
 void *qemu_safe_ram_ptr(ram_addr_t addr);
+void qemu_put_ram_ptr(void *addr);
 /* This should not be used by devices.  */
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
diff --git a/exec.c b/exec.c
index 3b137dc..2f8773f 100644
--- a/exec.c
+++ b/exec.c
@@ -2977,6 +2977,13 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
     return NULL;
 }
 
+void qemu_put_ram_ptr(void *addr)
+{
+    if (xen_mapcache_enabled()) {
+        qemu_map_cache_unlock(addr);
+    }
+}
+
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
     RAMBlock *block;
@@ -3692,6 +3699,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                     cpu_physical_memory_set_dirty_flags(
                         addr1, (0xff & ~CODE_DIRTY_FLAG));
                 }
+                qemu_put_ram_ptr(ptr);
             }
         } else {
             if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
@@ -3722,6 +3730,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                 ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
                     (addr & ~TARGET_PAGE_MASK);
                 memcpy(buf, ptr, l);
+                qemu_put_ram_ptr(ptr);
             }
         }
         len -= l;
@@ -3762,6 +3771,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
             /* ROM/RAM case */
             ptr = qemu_get_ram_ptr(addr1);
             memcpy(ptr, buf, l);
+            qemu_put_ram_ptr(ptr);
         }
         len -= l;
         buf += l;
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 43a5ed9..abf9bb2 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -195,6 +195,40 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
     return mapcache->last_address_vaddr + address_offset;
 }
 
+void qemu_map_cache_unlock(void *buffer)
+{
+    MapCacheEntry *entry = NULL, *pentry = NULL;
+    MapCacheRev *reventry;
+    target_phys_addr_t paddr_index;
+    int found = 0;
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        if (reventry->vaddr_req == buffer) {
+            paddr_index = reventry->paddr_index;
+            found = 1;
+            break;
+        }
+    }
+    if (!found) {
+        return;
+    }
+    QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next);
+    qemu_free(reventry);
+
+    entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
+    while (entry && entry->paddr_index != paddr_index) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        return;
+    }
+    entry->lock--;
+    if (entry->lock > 0) {
+        entry->lock--;
+    }
+}
+
 ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
 {
     MapCacheRev *reventry;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 11/15] Introduce qemu_put_ram_ptr
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This function allows to unlock a ram_ptr give by qemu_get_ram_ptr. After
a call to qemu_put_ram_ptr, the pointer may be unmap from QEMU when
used with Xen.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 cpu-common.h   |    1 +
 exec.c         |   10 ++++++++++
 xen-mapcache.c |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index 6d4a898..6f935cc 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -55,6 +55,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr);
 /* Same but slower, to use for migration, where the order of
  * RAMBlocks must not change. */
 void *qemu_safe_ram_ptr(ram_addr_t addr);
+void qemu_put_ram_ptr(void *addr);
 /* This should not be used by devices.  */
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
diff --git a/exec.c b/exec.c
index 3b137dc..2f8773f 100644
--- a/exec.c
+++ b/exec.c
@@ -2977,6 +2977,13 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
     return NULL;
 }
 
+void qemu_put_ram_ptr(void *addr)
+{
+    if (xen_mapcache_enabled()) {
+        qemu_map_cache_unlock(addr);
+    }
+}
+
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
     RAMBlock *block;
@@ -3692,6 +3699,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                     cpu_physical_memory_set_dirty_flags(
                         addr1, (0xff & ~CODE_DIRTY_FLAG));
                 }
+                qemu_put_ram_ptr(ptr);
             }
         } else {
             if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
@@ -3722,6 +3730,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                 ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
                     (addr & ~TARGET_PAGE_MASK);
                 memcpy(buf, ptr, l);
+                qemu_put_ram_ptr(ptr);
             }
         }
         len -= l;
@@ -3762,6 +3771,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
             /* ROM/RAM case */
             ptr = qemu_get_ram_ptr(addr1);
             memcpy(ptr, buf, l);
+            qemu_put_ram_ptr(ptr);
         }
         len -= l;
         buf += l;
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 43a5ed9..abf9bb2 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -195,6 +195,40 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
     return mapcache->last_address_vaddr + address_offset;
 }
 
+void qemu_map_cache_unlock(void *buffer)
+{
+    MapCacheEntry *entry = NULL, *pentry = NULL;
+    MapCacheRev *reventry;
+    target_phys_addr_t paddr_index;
+    int found = 0;
+
+    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+        if (reventry->vaddr_req == buffer) {
+            paddr_index = reventry->paddr_index;
+            found = 1;
+            break;
+        }
+    }
+    if (!found) {
+        return;
+    }
+    QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next);
+    qemu_free(reventry);
+
+    entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
+    while (entry && entry->paddr_index != paddr_index) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        return;
+    }
+    entry->lock--;
+    if (entry->lock > 0) {
+        entry->lock--;
+    }
+}
+
 ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
 {
     MapCacheRev *reventry;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 12/15] vl.c: Introduce getter for shutdown_requested and reset_requested.
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Introduce two functions qemu_shutdown_requested_get and
qemu_reset_requested_get to get the value of shutdown/reset_requested
without reset it.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 sysemu.h |    2 ++
 vl.c     |   10 ++++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/sysemu.h b/sysemu.h
index 23ae17e..ada9692 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -51,6 +51,8 @@ void cpu_disable_ticks(void);
 void qemu_system_reset_request(void);
 void qemu_system_shutdown_request(void);
 void qemu_system_powerdown_request(void);
+int qemu_shutdown_requested_get(void);
+int qemu_reset_requested_get(void);
 int qemu_shutdown_requested(void);
 int qemu_reset_requested(void);
 int qemu_powerdown_requested(void);
diff --git a/vl.c b/vl.c
index 38fa281..14e5bd6 100644
--- a/vl.c
+++ b/vl.c
@@ -1204,6 +1204,16 @@ static int powerdown_requested;
 int debug_requested;
 int vmstop_requested;
 
+int qemu_shutdown_requested_get(void)
+{
+    return shutdown_requested;
+}
+
+int qemu_reset_requested_get(void)
+{
+    return reset_requested;
+}
+
 int qemu_shutdown_requested(void)
 {
     int r = shutdown_requested;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 12/15] vl.c: Introduce getter for shutdown_requested and reset_requested.
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Introduce two functions qemu_shutdown_requested_get and
qemu_reset_requested_get to get the value of shutdown/reset_requested
without reset it.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 sysemu.h |    2 ++
 vl.c     |   10 ++++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/sysemu.h b/sysemu.h
index 23ae17e..ada9692 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -51,6 +51,8 @@ void cpu_disable_ticks(void);
 void qemu_system_reset_request(void);
 void qemu_system_shutdown_request(void);
 void qemu_system_powerdown_request(void);
+int qemu_shutdown_requested_get(void);
+int qemu_reset_requested_get(void);
 int qemu_shutdown_requested(void);
 int qemu_reset_requested(void);
 int qemu_powerdown_requested(void);
diff --git a/vl.c b/vl.c
index 38fa281..14e5bd6 100644
--- a/vl.c
+++ b/vl.c
@@ -1204,6 +1204,16 @@ static int powerdown_requested;
 int debug_requested;
 int vmstop_requested;
 
+int qemu_shutdown_requested_get(void)
+{
+    return shutdown_requested;
+}
+
+int qemu_reset_requested_get(void)
+{
+    return reset_requested;
+}
+
 int qemu_shutdown_requested(void)
 {
     int r = shutdown_requested;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 13/15] xen: Initialize event channels and io rings
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Arun Sharma, Anthony PERARD, Xen Devel, Stefano Stabellini

From: Arun Sharma <arun.sharma@intel.com>

Open and bind event channels; map ioreq and buffered ioreq rings.

Signed-off-by: Arun Sharma <arun.sharma@intel.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 hw/xen_common.h |    2 +
 xen-all.c       |  413 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 414 insertions(+), 1 deletions(-)

diff --git a/hw/xen_common.h b/hw/xen_common.h
index 3a08f6a..d0b1a92 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -39,4 +39,6 @@ static inline int xc_fd(xc_interface *xen_xc)
 }
 #endif
 
+void destroy_hvm_domain(void);
+
 #endif /* QEMU_HW_XEN_COMMON_H */
diff --git a/xen-all.c b/xen-all.c
index 84ed333..592bcaf 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -8,12 +8,58 @@
 
 #include "config.h"
 
+#include <sys/mman.h>
+
 #include "hw/pci.h"
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
 #include "xen-mapcache.h"
 
+#include <xen/hvm/ioreq.h>
+#include <xen/hvm/params.h>
+
+//#define DEBUG_XEN
+
+#ifdef DEBUG_XEN
+#define DPRINTF(fmt, ...) \
+    do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
+
+/* Compatibility with older version */
+#if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a
+#  define xen_vcpu_eport(shared_page, i) \
+    (shared_page->vcpu_iodata[i].vp_eport)
+#  define xen_vcpu_ioreq(shared_page, vcpu) \
+    (shared_page->vcpu_iodata[vcpu].vp_ioreq)
+#  define FMT_ioreq_size PRIx64
+#else
+#  define xen_vcpu_eport(shared_page, i) \
+    (shared_page->vcpu_ioreq[i].vp_eport)
+#  define xen_vcpu_ioreq(shared_page, vcpu) \
+    (shared_page->vcpu_ioreq[vcpu])
+#  define FMT_ioreq_size "u"
+#endif
+
+#define BUFFER_IO_MAX_DELAY  100
+
+typedef struct XenIOState {
+    shared_iopage_t *shared_page;
+    buffered_iopage_t *buffered_io_page;
+    QEMUTimer *buffered_io_timer;
+    /* the evtchn port for polling the notification, */
+    evtchn_port_t *ioreq_local_port;
+    /* the evtchn fd for polling */
+    XenEvtchn xce_handle;
+    /* which vcpu we are serving */
+    int send_vcpu;
+
+    Notifier exit;
+} XenIOState;
+
 /* Xen specific function for piix pci */
 
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
@@ -106,7 +152,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
         pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
     }
 
-    if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
+    if (xc_ops.domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
         hw_error("xen: failed to populate ram at %lx", ram_addr);
     }
 
@@ -114,10 +160,312 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
 }
 
 
+/* VCPU Operations, MMIO, IO ring ... */
+
+/* get the ioreq packets from share mem */
+static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
+{
+    ioreq_t *req = xen_vcpu_ioreq(&state->shared_page, vcpu);
+
+    if (req->state != STATE_IOREQ_READY) {
+        DPRINTF("I/O request not ready: "
+                "%x, ptr: %x, port: %"PRIx64", "
+                "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
+                req->state, req->data_is_ptr, req->addr,
+                req->data, req->count, req->size);
+        return NULL;
+    }
+
+    xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
+
+    req->state = STATE_IOREQ_INPROCESS;
+    return req;
+}
+
+/* use poll to get the port notification */
+/* ioreq_vec--out,the */
+/* retval--the number of ioreq packet */
+static ioreq_t *cpu_get_ioreq(XenIOState *state)
+{
+    int i;
+    evtchn_port_t port;
+
+    port = xc_evtchn_ops.pending(state->xce_handle);
+    if (port != -1) {
+        for (i = 0; i < smp_cpus; i++) {
+            if (state->ioreq_local_port[i] == port) {
+                break;
+            }
+        }
+
+        if (i == smp_cpus) {
+            hw_error("Fatal error while trying to get io event!\n");
+        }
+
+        /* unmask the wanted port again */
+        xc_evtchn_ops.unmask(state->xce_handle, port);
+
+        /* get the io packet from shared memory */
+        state->send_vcpu = i;
+        return cpu_get_ioreq_from_shared_memory(state, i);
+    }
+
+    /* read error or read nothing */
+    return NULL;
+}
+
+static uint32_t do_inp(pio_addr_t addr, unsigned long size)
+{
+    switch (size) {
+        case 1:
+            return cpu_inb(addr);
+        case 2:
+            return cpu_inw(addr);
+        case 4:
+            return cpu_inl(addr);
+        default:
+            hw_error("inp: bad size: %04"FMT_pioaddr" %lx", addr, size);
+    }
+}
+
+static void do_outp(pio_addr_t addr,
+        unsigned long size, uint32_t val)
+{
+    switch (size) {
+        case 1:
+            return cpu_outb(addr, val);
+        case 2:
+            return cpu_outw(addr, val);
+        case 4:
+            return cpu_outl(addr, val);
+        default:
+            hw_error("outp: bad size: %04"FMT_pioaddr" %lx", addr, size);
+    }
+}
+
+static void cpu_ioreq_pio(ioreq_t *req)
+{
+    int i, sign;
+
+    sign = req->df ? -1 : 1;
+
+    if (req->dir == IOREQ_READ) {
+        if (!req->data_is_ptr) {
+            req->data = do_inp(req->addr, req->size);
+        } else {
+            uint32_t tmp;
+
+            for (i = 0; i < req->count; i++) {
+                tmp = do_inp(req->addr, req->size);
+                cpu_physical_memory_write(req->data + (sign * i * req->size),
+                        (uint8_t *) &tmp, req->size);
+            }
+        }
+    } else if (req->dir == IOREQ_WRITE) {
+        if (!req->data_is_ptr) {
+            do_outp(req->addr, req->size, req->data);
+        } else {
+            for (i = 0; i < req->count; i++) {
+                uint32_t tmp = 0;
+
+                cpu_physical_memory_read(req->data + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+                do_outp(req->addr, req->size, tmp);
+            }
+        }
+    }
+}
+
+static void cpu_ioreq_move(ioreq_t *req)
+{
+    int i, sign;
+
+    sign = req->df ? -1 : 1;
+
+    if (!req->data_is_ptr) {
+        if (req->dir == IOREQ_READ) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_read(req->addr + (sign * i * req->size),
+                        (uint8_t *) &req->data, req->size);
+            }
+        } else if (req->dir == IOREQ_WRITE) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_write(req->addr + (sign * i * req->size),
+                        (uint8_t *) &req->data, req->size);
+            }
+        }
+    } else {
+        target_ulong tmp;
+
+        if (req->dir == IOREQ_READ) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_read(req->addr + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+                cpu_physical_memory_write(req->data + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+            }
+        } else if (req->dir == IOREQ_WRITE) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_read(req->data + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+                cpu_physical_memory_write(req->addr + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+            }
+        }
+    }
+}
+
+static void handle_ioreq(ioreq_t *req)
+{
+    if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
+            (req->size < sizeof (target_ulong))) {
+        req->data &= ((target_ulong) 1 << (8 * req->size)) - 1;
+    }
+
+    switch (req->type) {
+        case IOREQ_TYPE_PIO:
+            cpu_ioreq_pio(req);
+            break;
+        case IOREQ_TYPE_COPY:
+            cpu_ioreq_move(req);
+            break;
+        case IOREQ_TYPE_TIMEOFFSET:
+            break;
+        case IOREQ_TYPE_INVALIDATE:
+            qemu_invalidate_map_cache();
+            break;
+        default:
+            hw_error("Invalid ioreq type 0x%x\n", req->type);
+    }
+}
+
+static void handle_buffered_iopage(XenIOState *state)
+{
+    buf_ioreq_t *buf_req = NULL;
+    ioreq_t req;
+    int qw;
+
+    if (!state->buffered_io_page) {
+        return;
+    }
+
+    while (state->buffered_io_page->read_pointer != state->buffered_io_page->write_pointer) {
+        buf_req = &state->buffered_io_page->buf_ioreq[
+            state->buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
+        req.size = 1UL << buf_req->size;
+        req.count = 1;
+        req.addr = buf_req->addr;
+        req.data = buf_req->data;
+        req.state = STATE_IOREQ_READY;
+        req.dir = buf_req->dir;
+        req.df = 1;
+        req.type = buf_req->type;
+        req.data_is_ptr = 0;
+        qw = (req.size == 8);
+        if (qw) {
+            buf_req = &state->buffered_io_page->buf_ioreq[
+                (state->buffered_io_page->read_pointer + 1) % IOREQ_BUFFER_SLOT_NUM];
+            req.data |= ((uint64_t)buf_req->data) << 32;
+        }
+
+        handle_ioreq(&req);
+
+        xen_mb();
+        state->buffered_io_page->read_pointer += qw ? 2 : 1;
+    }
+}
+
+static void handle_buffered_io(void *opaque)
+{
+    XenIOState *state = opaque;
+
+    handle_buffered_iopage(state);
+    qemu_mod_timer(state->buffered_io_timer,
+                   BUFFER_IO_MAX_DELAY + qemu_get_clock(rt_clock));
+}
+
+static void cpu_handle_ioreq(void *opaque)
+{
+    XenIOState *state = opaque;
+    ioreq_t *req = cpu_get_ioreq(state);
+
+    handle_buffered_iopage(state);
+    if (req) {
+        handle_ioreq(req);
+
+        if (req->state != STATE_IOREQ_INPROCESS) {
+            fprintf(stderr, "Badness in I/O request ... not in service?!: "
+                    "%x, ptr: %x, port: %"PRIx64", "
+                    "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
+                    req->state, req->data_is_ptr, req->addr,
+                    req->data, req->count, req->size);
+            destroy_hvm_domain();
+            return;
+        }
+
+        xen_wmb(); /* Update ioreq contents /then/ update state. */
+
+        /*
+         * We do this before we send the response so that the tools
+         * have the opportunity to pick up on the reset before the
+         * guest resumes and does a hlt with interrupts disabled which
+         * causes Xen to powerdown the domain.
+         */
+        if (vm_running) {
+            if (qemu_shutdown_requested_get()) {
+                destroy_hvm_domain();
+            }
+            if (qemu_reset_requested_get()) {
+                qemu_system_reset();
+            }
+        }
+
+        req->state = STATE_IORESP_READY;
+        xc_evtchn_ops.notify(state->xce_handle, state->ioreq_local_port[state->send_vcpu]);
+    }
+}
+
+static void xen_main_loop_prepare(XenIOState *state)
+{
+    int evtchn_fd = -1;
+
+    if (state->xce_handle != XC_HANDLER_INITIAL_VALUE) {
+        evtchn_fd = xc_evtchn_ops.fd(state->xce_handle);
+    }
+
+    state->buffered_io_timer = qemu_new_timer(rt_clock, handle_buffered_io,
+                                       state);
+    qemu_mod_timer(state->buffered_io_timer, qemu_get_clock(rt_clock));
+
+    if (evtchn_fd != -1) {
+        qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
+    }
+}
+
+
 /* Initialise Xen */
 
+static void xen_vm_change_state_handler(void *opaque, int running, int reason)
+{
+    XenIOState *state = opaque;
+    if (running) {
+        xen_main_loop_prepare(state);
+    }
+}
+
+static void xen_exit_notifier(Notifier *n)
+{
+    XenIOState *state = container_of(n, XenIOState, exit);
+
+    xc_evtchn_ops.close(state->xce_handle);
+}
+
 int xen_init(int smp_cpus)
 {
+    int i, rc;
+    unsigned long ioreq_pfn;
+    XenIOState *state;
+
     if (xen_mode == XEN_EMULATE) {
         xen_mode = XEN_ATTACH;
     }
@@ -128,9 +476,72 @@ int xen_init(int smp_cpus)
         return -1;
     }
 
+    state = qemu_mallocz(sizeof (XenIOState));
+
+    state->xce_handle = xc_evtchn_ops.open(NULL, 0);
+    if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) {
+        perror("xen: event channel open");
+        return -errno;
+    }
+
+    state->exit.notify = xen_exit_notifier;
+    qemu_add_exit_notifier(&state->exit);
+
+    xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
+    DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
+    state->shared_page = xc_ops.map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
+                                                  PROT_READ|PROT_WRITE, ioreq_pfn);
+    if (state->shared_page == NULL) {
+        hw_error("map shared IO page returned error %d handle=" XC_INTERFACE_FMT,
+                 errno, xen_xc);
+    }
+
+    xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
+    DPRINTF("buffered io page at pfn %lx\n", ioreq_pfn);
+    state->buffered_io_page = xc_ops.map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
+                                                       PROT_READ|PROT_WRITE, ioreq_pfn);
+    if (state->buffered_io_page == NULL) {
+        hw_error("map buffered IO page returned error %d", errno);
+    }
+
+    state->ioreq_local_port = qemu_mallocz(smp_cpus * sizeof (evtchn_port_t));
+
+    /* FIXME: how about if we overflow the page here? */
+    for (i = 0; i < smp_cpus; i++) {
+        rc = xc_evtchn_ops.bind_interdomain(state->xce_handle, xen_domid,
+                                            xen_vcpu_eport(state->shared_page, i));
+        if (rc == -1) {
+            fprintf(stderr, "bind interdomain ioctl error %d\n", errno);
+            return -1;
+        }
+        state->ioreq_local_port[i] = rc;
+    }
+
     /* Init RAM management */
     qemu_map_cache_init();
     xen_ram_init(ram_size);
 
+    qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state);
+
     return 0;
 }
+
+void destroy_hvm_domain(void)
+{
+    XenXC xc_handle;
+    int sts;
+
+    xc_handle = xc_ops.interface_open(0, 0, 0);
+    if (xc_handle == XC_HANDLER_INITIAL_VALUE) {
+        fprintf(stderr, "Cannot acquire xenctrl handle\n");
+    } else {
+        sts = xc_domain_shutdown(xc_handle, xen_domid, SHUTDOWN_poweroff);
+        if (sts != 0) {
+            fprintf(stderr, "? xc_domain_shutdown failed to issue poweroff, "
+                    "sts %d, %s\n", sts, strerror(errno));
+        } else {
+            fprintf(stderr, "Issued domain %d poweroff\n", xen_domid);
+        }
+        xc_ops.interface_close(xc_handle);
+    }
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 13/15] xen: Initialize event channels and io rings
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel
  Cc: Arun Sharma, Anthony PERARD, Xen Devel, Anthony Liguori,
	Stefano Stabellini

From: Arun Sharma <arun.sharma@intel.com>

Open and bind event channels; map ioreq and buffered ioreq rings.

Signed-off-by: Arun Sharma <arun.sharma@intel.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 hw/xen_common.h |    2 +
 xen-all.c       |  413 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 414 insertions(+), 1 deletions(-)

diff --git a/hw/xen_common.h b/hw/xen_common.h
index 3a08f6a..d0b1a92 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -39,4 +39,6 @@ static inline int xc_fd(xc_interface *xen_xc)
 }
 #endif
 
+void destroy_hvm_domain(void);
+
 #endif /* QEMU_HW_XEN_COMMON_H */
diff --git a/xen-all.c b/xen-all.c
index 84ed333..592bcaf 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -8,12 +8,58 @@
 
 #include "config.h"
 
+#include <sys/mman.h>
+
 #include "hw/pci.h"
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
 #include "xen-mapcache.h"
 
+#include <xen/hvm/ioreq.h>
+#include <xen/hvm/params.h>
+
+//#define DEBUG_XEN
+
+#ifdef DEBUG_XEN
+#define DPRINTF(fmt, ...) \
+    do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
+
+/* Compatibility with older version */
+#if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a
+#  define xen_vcpu_eport(shared_page, i) \
+    (shared_page->vcpu_iodata[i].vp_eport)
+#  define xen_vcpu_ioreq(shared_page, vcpu) \
+    (shared_page->vcpu_iodata[vcpu].vp_ioreq)
+#  define FMT_ioreq_size PRIx64
+#else
+#  define xen_vcpu_eport(shared_page, i) \
+    (shared_page->vcpu_ioreq[i].vp_eport)
+#  define xen_vcpu_ioreq(shared_page, vcpu) \
+    (shared_page->vcpu_ioreq[vcpu])
+#  define FMT_ioreq_size "u"
+#endif
+
+#define BUFFER_IO_MAX_DELAY  100
+
+typedef struct XenIOState {
+    shared_iopage_t *shared_page;
+    buffered_iopage_t *buffered_io_page;
+    QEMUTimer *buffered_io_timer;
+    /* the evtchn port for polling the notification, */
+    evtchn_port_t *ioreq_local_port;
+    /* the evtchn fd for polling */
+    XenEvtchn xce_handle;
+    /* which vcpu we are serving */
+    int send_vcpu;
+
+    Notifier exit;
+} XenIOState;
+
 /* Xen specific function for piix pci */
 
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
@@ -106,7 +152,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
         pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
     }
 
-    if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
+    if (xc_ops.domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
         hw_error("xen: failed to populate ram at %lx", ram_addr);
     }
 
@@ -114,10 +160,312 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
 }
 
 
+/* VCPU Operations, MMIO, IO ring ... */
+
+/* get the ioreq packets from share mem */
+static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
+{
+    ioreq_t *req = xen_vcpu_ioreq(&state->shared_page, vcpu);
+
+    if (req->state != STATE_IOREQ_READY) {
+        DPRINTF("I/O request not ready: "
+                "%x, ptr: %x, port: %"PRIx64", "
+                "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
+                req->state, req->data_is_ptr, req->addr,
+                req->data, req->count, req->size);
+        return NULL;
+    }
+
+    xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
+
+    req->state = STATE_IOREQ_INPROCESS;
+    return req;
+}
+
+/* use poll to get the port notification */
+/* ioreq_vec--out,the */
+/* retval--the number of ioreq packet */
+static ioreq_t *cpu_get_ioreq(XenIOState *state)
+{
+    int i;
+    evtchn_port_t port;
+
+    port = xc_evtchn_ops.pending(state->xce_handle);
+    if (port != -1) {
+        for (i = 0; i < smp_cpus; i++) {
+            if (state->ioreq_local_port[i] == port) {
+                break;
+            }
+        }
+
+        if (i == smp_cpus) {
+            hw_error("Fatal error while trying to get io event!\n");
+        }
+
+        /* unmask the wanted port again */
+        xc_evtchn_ops.unmask(state->xce_handle, port);
+
+        /* get the io packet from shared memory */
+        state->send_vcpu = i;
+        return cpu_get_ioreq_from_shared_memory(state, i);
+    }
+
+    /* read error or read nothing */
+    return NULL;
+}
+
+static uint32_t do_inp(pio_addr_t addr, unsigned long size)
+{
+    switch (size) {
+        case 1:
+            return cpu_inb(addr);
+        case 2:
+            return cpu_inw(addr);
+        case 4:
+            return cpu_inl(addr);
+        default:
+            hw_error("inp: bad size: %04"FMT_pioaddr" %lx", addr, size);
+    }
+}
+
+static void do_outp(pio_addr_t addr,
+        unsigned long size, uint32_t val)
+{
+    switch (size) {
+        case 1:
+            return cpu_outb(addr, val);
+        case 2:
+            return cpu_outw(addr, val);
+        case 4:
+            return cpu_outl(addr, val);
+        default:
+            hw_error("outp: bad size: %04"FMT_pioaddr" %lx", addr, size);
+    }
+}
+
+static void cpu_ioreq_pio(ioreq_t *req)
+{
+    int i, sign;
+
+    sign = req->df ? -1 : 1;
+
+    if (req->dir == IOREQ_READ) {
+        if (!req->data_is_ptr) {
+            req->data = do_inp(req->addr, req->size);
+        } else {
+            uint32_t tmp;
+
+            for (i = 0; i < req->count; i++) {
+                tmp = do_inp(req->addr, req->size);
+                cpu_physical_memory_write(req->data + (sign * i * req->size),
+                        (uint8_t *) &tmp, req->size);
+            }
+        }
+    } else if (req->dir == IOREQ_WRITE) {
+        if (!req->data_is_ptr) {
+            do_outp(req->addr, req->size, req->data);
+        } else {
+            for (i = 0; i < req->count; i++) {
+                uint32_t tmp = 0;
+
+                cpu_physical_memory_read(req->data + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+                do_outp(req->addr, req->size, tmp);
+            }
+        }
+    }
+}
+
+static void cpu_ioreq_move(ioreq_t *req)
+{
+    int i, sign;
+
+    sign = req->df ? -1 : 1;
+
+    if (!req->data_is_ptr) {
+        if (req->dir == IOREQ_READ) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_read(req->addr + (sign * i * req->size),
+                        (uint8_t *) &req->data, req->size);
+            }
+        } else if (req->dir == IOREQ_WRITE) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_write(req->addr + (sign * i * req->size),
+                        (uint8_t *) &req->data, req->size);
+            }
+        }
+    } else {
+        target_ulong tmp;
+
+        if (req->dir == IOREQ_READ) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_read(req->addr + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+                cpu_physical_memory_write(req->data + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+            }
+        } else if (req->dir == IOREQ_WRITE) {
+            for (i = 0; i < req->count; i++) {
+                cpu_physical_memory_read(req->data + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+                cpu_physical_memory_write(req->addr + (sign * i * req->size),
+                        (uint8_t*) &tmp, req->size);
+            }
+        }
+    }
+}
+
+static void handle_ioreq(ioreq_t *req)
+{
+    if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
+            (req->size < sizeof (target_ulong))) {
+        req->data &= ((target_ulong) 1 << (8 * req->size)) - 1;
+    }
+
+    switch (req->type) {
+        case IOREQ_TYPE_PIO:
+            cpu_ioreq_pio(req);
+            break;
+        case IOREQ_TYPE_COPY:
+            cpu_ioreq_move(req);
+            break;
+        case IOREQ_TYPE_TIMEOFFSET:
+            break;
+        case IOREQ_TYPE_INVALIDATE:
+            qemu_invalidate_map_cache();
+            break;
+        default:
+            hw_error("Invalid ioreq type 0x%x\n", req->type);
+    }
+}
+
+static void handle_buffered_iopage(XenIOState *state)
+{
+    buf_ioreq_t *buf_req = NULL;
+    ioreq_t req;
+    int qw;
+
+    if (!state->buffered_io_page) {
+        return;
+    }
+
+    while (state->buffered_io_page->read_pointer != state->buffered_io_page->write_pointer) {
+        buf_req = &state->buffered_io_page->buf_ioreq[
+            state->buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
+        req.size = 1UL << buf_req->size;
+        req.count = 1;
+        req.addr = buf_req->addr;
+        req.data = buf_req->data;
+        req.state = STATE_IOREQ_READY;
+        req.dir = buf_req->dir;
+        req.df = 1;
+        req.type = buf_req->type;
+        req.data_is_ptr = 0;
+        qw = (req.size == 8);
+        if (qw) {
+            buf_req = &state->buffered_io_page->buf_ioreq[
+                (state->buffered_io_page->read_pointer + 1) % IOREQ_BUFFER_SLOT_NUM];
+            req.data |= ((uint64_t)buf_req->data) << 32;
+        }
+
+        handle_ioreq(&req);
+
+        xen_mb();
+        state->buffered_io_page->read_pointer += qw ? 2 : 1;
+    }
+}
+
+static void handle_buffered_io(void *opaque)
+{
+    XenIOState *state = opaque;
+
+    handle_buffered_iopage(state);
+    qemu_mod_timer(state->buffered_io_timer,
+                   BUFFER_IO_MAX_DELAY + qemu_get_clock(rt_clock));
+}
+
+static void cpu_handle_ioreq(void *opaque)
+{
+    XenIOState *state = opaque;
+    ioreq_t *req = cpu_get_ioreq(state);
+
+    handle_buffered_iopage(state);
+    if (req) {
+        handle_ioreq(req);
+
+        if (req->state != STATE_IOREQ_INPROCESS) {
+            fprintf(stderr, "Badness in I/O request ... not in service?!: "
+                    "%x, ptr: %x, port: %"PRIx64", "
+                    "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
+                    req->state, req->data_is_ptr, req->addr,
+                    req->data, req->count, req->size);
+            destroy_hvm_domain();
+            return;
+        }
+
+        xen_wmb(); /* Update ioreq contents /then/ update state. */
+
+        /*
+         * We do this before we send the response so that the tools
+         * have the opportunity to pick up on the reset before the
+         * guest resumes and does a hlt with interrupts disabled which
+         * causes Xen to powerdown the domain.
+         */
+        if (vm_running) {
+            if (qemu_shutdown_requested_get()) {
+                destroy_hvm_domain();
+            }
+            if (qemu_reset_requested_get()) {
+                qemu_system_reset();
+            }
+        }
+
+        req->state = STATE_IORESP_READY;
+        xc_evtchn_ops.notify(state->xce_handle, state->ioreq_local_port[state->send_vcpu]);
+    }
+}
+
+static void xen_main_loop_prepare(XenIOState *state)
+{
+    int evtchn_fd = -1;
+
+    if (state->xce_handle != XC_HANDLER_INITIAL_VALUE) {
+        evtchn_fd = xc_evtchn_ops.fd(state->xce_handle);
+    }
+
+    state->buffered_io_timer = qemu_new_timer(rt_clock, handle_buffered_io,
+                                       state);
+    qemu_mod_timer(state->buffered_io_timer, qemu_get_clock(rt_clock));
+
+    if (evtchn_fd != -1) {
+        qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
+    }
+}
+
+
 /* Initialise Xen */
 
+static void xen_vm_change_state_handler(void *opaque, int running, int reason)
+{
+    XenIOState *state = opaque;
+    if (running) {
+        xen_main_loop_prepare(state);
+    }
+}
+
+static void xen_exit_notifier(Notifier *n)
+{
+    XenIOState *state = container_of(n, XenIOState, exit);
+
+    xc_evtchn_ops.close(state->xce_handle);
+}
+
 int xen_init(int smp_cpus)
 {
+    int i, rc;
+    unsigned long ioreq_pfn;
+    XenIOState *state;
+
     if (xen_mode == XEN_EMULATE) {
         xen_mode = XEN_ATTACH;
     }
@@ -128,9 +476,72 @@ int xen_init(int smp_cpus)
         return -1;
     }
 
+    state = qemu_mallocz(sizeof (XenIOState));
+
+    state->xce_handle = xc_evtchn_ops.open(NULL, 0);
+    if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) {
+        perror("xen: event channel open");
+        return -errno;
+    }
+
+    state->exit.notify = xen_exit_notifier;
+    qemu_add_exit_notifier(&state->exit);
+
+    xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
+    DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
+    state->shared_page = xc_ops.map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
+                                                  PROT_READ|PROT_WRITE, ioreq_pfn);
+    if (state->shared_page == NULL) {
+        hw_error("map shared IO page returned error %d handle=" XC_INTERFACE_FMT,
+                 errno, xen_xc);
+    }
+
+    xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
+    DPRINTF("buffered io page at pfn %lx\n", ioreq_pfn);
+    state->buffered_io_page = xc_ops.map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
+                                                       PROT_READ|PROT_WRITE, ioreq_pfn);
+    if (state->buffered_io_page == NULL) {
+        hw_error("map buffered IO page returned error %d", errno);
+    }
+
+    state->ioreq_local_port = qemu_mallocz(smp_cpus * sizeof (evtchn_port_t));
+
+    /* FIXME: how about if we overflow the page here? */
+    for (i = 0; i < smp_cpus; i++) {
+        rc = xc_evtchn_ops.bind_interdomain(state->xce_handle, xen_domid,
+                                            xen_vcpu_eport(state->shared_page, i));
+        if (rc == -1) {
+            fprintf(stderr, "bind interdomain ioctl error %d\n", errno);
+            return -1;
+        }
+        state->ioreq_local_port[i] = rc;
+    }
+
     /* Init RAM management */
     qemu_map_cache_init();
     xen_ram_init(ram_size);
 
+    qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state);
+
     return 0;
 }
+
+void destroy_hvm_domain(void)
+{
+    XenXC xc_handle;
+    int sts;
+
+    xc_handle = xc_ops.interface_open(0, 0, 0);
+    if (xc_handle == XC_HANDLER_INITIAL_VALUE) {
+        fprintf(stderr, "Cannot acquire xenctrl handle\n");
+    } else {
+        sts = xc_domain_shutdown(xc_handle, xen_domid, SHUTDOWN_poweroff);
+        if (sts != 0) {
+            fprintf(stderr, "? xc_domain_shutdown failed to issue poweroff, "
+                    "sts %d, %s\n", sts, strerror(errno));
+        } else {
+            fprintf(stderr, "Issued domain %d poweroff\n", xen_domid);
+        }
+        xc_ops.interface_close(xc_handle);
+    }
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 14/15] xen: Set running state in xenstore.
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This tells to the xen management tool that the machine can begin run.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 xen-all.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 592bcaf..5892bd8 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -57,6 +57,8 @@ typedef struct XenIOState {
     /* which vcpu we are serving */
     int send_vcpu;
 
+    struct xs_handle *xenstore;
+
     Notifier exit;
 } XenIOState;
 
@@ -425,6 +427,17 @@ static void cpu_handle_ioreq(void *opaque)
     }
 }
 
+static void xenstore_record_dm_state(XenIOState *s, const char *state)
+{
+    char path[50];
+
+    snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", xen_domid);
+    if (!xs_ops.write(s->xenstore, XBT_NULL, path, state, strlen(state))) {
+        fprintf(stderr, "error recording dm state\n");
+        exit(1);
+    }
+}
+
 static void xen_main_loop_prepare(XenIOState *state)
 {
     int evtchn_fd = -1;
@@ -440,6 +453,9 @@ static void xen_main_loop_prepare(XenIOState *state)
     if (evtchn_fd != -1) {
         qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
     }
+
+    /* record state running */
+    xenstore_record_dm_state(state, "running");
 }
 
 
@@ -458,6 +474,7 @@ static void xen_exit_notifier(Notifier *n)
     XenIOState *state = container_of(n, XenIOState, exit);
 
     xc_evtchn_ops.close(state->xce_handle);
+    xs_ops.daemon_close(state->xenstore);
 }
 
 int xen_init(int smp_cpus)
@@ -484,6 +501,12 @@ int xen_init(int smp_cpus)
         return -errno;
     }
 
+    state->xenstore = xs_ops.daemon_open();
+    if (state->xenstore == NULL) {
+        perror("xen: xenstore open");
+        return -errno;
+    }
+
     state->exit.notify = xen_exit_notifier;
     qemu_add_exit_notifier(&state->exit);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 14/15] xen: Set running state in xenstore.
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

This tells to the xen management tool that the machine can begin run.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Alexander Graf <agraf@suse.de>
---
 xen-all.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 592bcaf..5892bd8 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -57,6 +57,8 @@ typedef struct XenIOState {
     /* which vcpu we are serving */
     int send_vcpu;
 
+    struct xs_handle *xenstore;
+
     Notifier exit;
 } XenIOState;
 
@@ -425,6 +427,17 @@ static void cpu_handle_ioreq(void *opaque)
     }
 }
 
+static void xenstore_record_dm_state(XenIOState *s, const char *state)
+{
+    char path[50];
+
+    snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", xen_domid);
+    if (!xs_ops.write(s->xenstore, XBT_NULL, path, state, strlen(state))) {
+        fprintf(stderr, "error recording dm state\n");
+        exit(1);
+    }
+}
+
 static void xen_main_loop_prepare(XenIOState *state)
 {
     int evtchn_fd = -1;
@@ -440,6 +453,9 @@ static void xen_main_loop_prepare(XenIOState *state)
     if (evtchn_fd != -1) {
         qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
     }
+
+    /* record state running */
+    xenstore_record_dm_state(state, "running");
 }
 
 
@@ -458,6 +474,7 @@ static void xen_exit_notifier(Notifier *n)
     XenIOState *state = container_of(n, XenIOState, exit);
 
     xc_evtchn_ops.close(state->xce_handle);
+    xs_ops.daemon_close(state->xenstore);
 }
 
 int xen_init(int smp_cpus)
@@ -484,6 +501,12 @@ int xen_init(int smp_cpus)
         return -errno;
     }
 
+    state->xenstore = xs_ops.daemon_open();
+    if (state->xenstore == NULL) {
+        perror("xen: xenstore open");
+        return -errno;
+    }
+
     state->exit.notify = xen_exit_notifier;
     qemu_add_exit_notifier(&state->exit);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH V10 15/15] xen: Add Xen hypercall for sleep state in the cmos_s3 callback.
  2011-02-02 14:49 ` anthony.perard
@ 2011-02-02 14:49   ` anthony.perard
  -1 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 hw/pc_piix.c |    6 +++++-
 hw/xen.h     |    1 +
 xen-all.c    |    9 +++++++++
 xen-stub.c   |    4 ++++
 4 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 27d9030..f86873d 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -176,7 +176,11 @@ static void pc_init1(ram_addr_t ram_size,
         uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
         i2c_bus *smbus;
 
-        cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
+        if (!xen_enabled()) {
+            cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
+        } else {
+            cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1);
+        }
         smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
diff --git a/hw/xen.h b/hw/xen.h
index a67b5bd..5bcbd6f 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -43,6 +43,7 @@ static inline int xen_mapcache_enabled(void)
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
+void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
 
 qemu_irq *xen_interrupt_controller_init(void);
 
diff --git a/xen-all.c b/xen-all.c
index 5892bd8..4eb53b3 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -11,6 +11,7 @@
 #include <sys/mman.h>
 
 #include "hw/pci.h"
+#include "hw/pc.h"
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
@@ -92,6 +93,14 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+void xen_cmos_set_s3_resume(void *opaque, int irq, int level)
+{
+    pc_cmos_set_s3_resume(opaque, irq, level);
+    if (level) {
+        xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
+    }
+}
+
 /* Xen Interrupt Controller */
 
 static void xen_set_irq(void *opaque, int irq, int level)
diff --git a/xen-stub.c b/xen-stub.c
index 86486f8..0d2a663 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -24,6 +24,10 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
 {
 }
 
+void xen_cmos_set_s3_resume(void *opaque, int irq, int level)
+{
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
 {
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH V10 15/15] xen: Add Xen hypercall for sleep state in the cmos_s3 callback.
@ 2011-02-02 14:49   ` anthony.perard
  0 siblings, 0 replies; 68+ messages in thread
From: anthony.perard @ 2011-02-02 14:49 UTC (permalink / raw)
  To: QEMU-devel; +Cc: Anthony PERARD, Xen Devel, Anthony Liguori, Stefano Stabellini

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 hw/pc_piix.c |    6 +++++-
 hw/xen.h     |    1 +
 xen-all.c    |    9 +++++++++
 xen-stub.c   |    4 ++++
 4 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 27d9030..f86873d 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -176,7 +176,11 @@ static void pc_init1(ram_addr_t ram_size,
         uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
         i2c_bus *smbus;
 
-        cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
+        if (!xen_enabled()) {
+            cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
+        } else {
+            cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1);
+        }
         smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
diff --git a/hw/xen.h b/hw/xen.h
index a67b5bd..5bcbd6f 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -43,6 +43,7 @@ static inline int xen_mapcache_enabled(void)
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
+void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
 
 qemu_irq *xen_interrupt_controller_init(void);
 
diff --git a/xen-all.c b/xen-all.c
index 5892bd8..4eb53b3 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -11,6 +11,7 @@
 #include <sys/mman.h>
 
 #include "hw/pci.h"
+#include "hw/pc.h"
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
@@ -92,6 +93,14 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+void xen_cmos_set_s3_resume(void *opaque, int irq, int level)
+{
+    pc_cmos_set_s3_resume(opaque, irq, level);
+    if (level) {
+        xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
+    }
+}
+
 /* Xen Interrupt Controller */
 
 static void xen_set_irq(void *opaque, int irq, int level)
diff --git a/xen-stub.c b/xen-stub.c
index 86486f8..0d2a663 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -24,6 +24,10 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
 {
 }
 
+void xen_cmos_set_s3_resume(void *opaque, int irq, int level)
+{
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
 {
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 01/15] xen: Replace some tab-indents with spaces (clean-up).
  2011-02-02 14:49   ` anthony.perard
  (?)
@ 2011-02-24 16:06   ` Anthony Liguori
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 16:06 UTC (permalink / raw)
  To: anthony.perard; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
> From: Anthony PERARD<anthony.perard@citrix.com>
>
> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> Acked-by: Alexander Graf<agraf@suse.de>
> ---
>   hw/xen_backend.c |  308 +++++++++++++++++++++---------------------
>   hw/xen_disk.c    |  394 +++++++++++++++++++++++++++---------------------------
>   hw/xen_nic.c     |  222 +++++++++++++++---------------
>   3 files changed, 462 insertions(+), 462 deletions(-)
>
> diff --git a/hw/xen_backend.c b/hw/xen_backend.c
> index a2e408f..860b038 100644
> --- a/hw/xen_backend.c
> +++ b/hw/xen_backend.c
> @@ -59,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val)
>
>       snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>       if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
> -	return -1;
> +        return -1;
>    


I know it's a bit of a pain, but we should add {}s here if we're going 
to do a change like this.  That way we're just breaking git blame once.  
The lack of {}s is also more visually offensive.

Regards,

Anthony Liguori

>       return 0;
>   }
>
> @@ -95,7 +95,7 @@ int xenstore_read_int(const char *base, const char *node, int *ival)
>
>       val = xenstore_read_str(base, node);
>       if (val&&  1 == sscanf(val, "%d", ival))
> -	rc = 0;
> +        rc = 0;
>       qemu_free(val);
>       return rc;
>   }
> @@ -134,16 +134,16 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
>
>   const char *xenbus_strstate(enum xenbus_state state)
>   {
> -	static const char *const name[] = {
> -		[ XenbusStateUnknown      ] = "Unknown",
> -		[ XenbusStateInitialising ] = "Initialising",
> -		[ XenbusStateInitWait     ] = "InitWait",
> -		[ XenbusStateInitialised  ] = "Initialised",
> -		[ XenbusStateConnected    ] = "Connected",
> -		[ XenbusStateClosing      ] = "Closing",
> -		[ XenbusStateClosed	  ] = "Closed",
> -	};
> -	return (state<  ARRAY_SIZE(name)) ? name[state] : "INVALID";
> +    static const char *const name[] = {
> +        [ XenbusStateUnknown      ] = "Unknown",
> +        [ XenbusStateInitialising ] = "Initialising",
> +        [ XenbusStateInitWait     ] = "InitWait",
> +        [ XenbusStateInitialised  ] = "Initialised",
> +        [ XenbusStateConnected    ] = "Connected",
> +        [ XenbusStateClosing      ] = "Closing",
> +        [ XenbusStateClosed       ] = "Closed",
> +    };
> +    return (state<  ARRAY_SIZE(name)) ? name[state] : "INVALID";
>   }
>
>   int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
> @@ -152,9 +152,9 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
>
>       rc = xenstore_write_be_int(xendev, "state", state);
>       if (rc<  0)
> -	return rc;
> +        return rc;
>       xen_be_printf(xendev, 1, "backend state: %s ->  %s\n",
> -		  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
> +                  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
>       xendev->be_state = state;
>       return 0;
>   }
> @@ -166,13 +166,13 @@ struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
>       struct XenDevice *xendev;
>
>       QTAILQ_FOREACH(xendev,&xendevs, next) {
> -	if (xendev->dom != dom)
> -	    continue;
> -	if (xendev->dev != dev)
> -	    continue;
> -	if (strcmp(xendev->type, type) != 0)
> -	    continue;
> -	return xendev;
> +        if (xendev->dom != dom)
> +            continue;
> +        if (xendev->dev != dev)
> +            continue;
> +        if (strcmp(xendev->type, type) != 0)
> +            continue;
> +        return xendev;
>       }
>       return NULL;
>   }
> @@ -188,7 +188,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
>
>       xendev = xen_be_find_xendev(type, dom, dev);
>       if (xendev)
> -	return xendev;
> +        return xendev;
>
>       /* init new xendev */
>       xendev = qemu_mallocz(ops->size);
> @@ -199,9 +199,9 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
>
>       dom0 = xs_get_domain_path(xenstore, 0);
>       snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
> -	     dom0, xendev->type, xendev->dom, xendev->dev);
> +             dom0, xendev->type, xendev->dom, xendev->dev);
>       snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
> -	     xendev->type, xendev->dev);
> +             xendev->type, xendev->dev);
>       free(dom0);
>
>       xendev->debug      = debug;
> @@ -209,28 +209,28 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
>
>       xendev->evtchndev = xc_evtchn_open();
>       if (xendev->evtchndev<  0) {
> -	xen_be_printf(NULL, 0, "can't open evtchn device\n");
> -	qemu_free(xendev);
> -	return NULL;
> +        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);
>
>       if (ops->flags&  DEVOPS_FLAG_NEED_GNTDEV) {
> -	xendev->gnttabdev = xc_gnttab_open();
> -	if (xendev->gnttabdev<  0) {
> -	    xen_be_printf(NULL, 0, "can't open gnttab device\n");
> -	    xc_evtchn_close(xendev->evtchndev);
> -	    qemu_free(xendev);
> -	    return NULL;
> -	}
> +        xendev->gnttabdev = xc_gnttab_open();
> +        if (xendev->gnttabdev<  0) {
> +            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 = -1;
>       }
>
>       QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
>
>       if (xendev->ops->alloc)
> -	xendev->ops->alloc(xendev);
> +        xendev->ops->alloc(xendev);
>
>       return xendev;
>   }
> @@ -251,28 +251,28 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
>           xendev = xnext;
>           xnext = xendev->next.tqe_next;
>
> -	if (xendev->dom != dom)
> -	    continue;
> -	if (xendev->dev != dev&&  dev != -1)
> -	    continue;
> +        if (xendev->dom != dom)
> +            continue;
> +        if (xendev->dev != dev&&  dev != -1)
> +            continue;
>
> -	if (xendev->ops->free)
> -	    xendev->ops->free(xendev);
> +        if (xendev->ops->free)
> +            xendev->ops->free(xendev);
>
> -	if (xendev->fe) {
> -	    char token[XEN_BUFSIZE];
> -	    snprintf(token, sizeof(token), "fe:%p", xendev);
> -	    xs_unwatch(xenstore, xendev->fe, token);
> -	    qemu_free(xendev->fe);
> -	}
> +        if (xendev->fe) {
> +            char token[XEN_BUFSIZE];
> +            snprintf(token, sizeof(token), "fe:%p", xendev);
> +            xs_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>= 0)
> +            xc_evtchn_close(xendev->evtchndev);
> +        if (xendev->gnttabdev>= 0)
> +            xc_gnttab_close(xendev->gnttabdev);
>
> -	QTAILQ_REMOVE(&xendevs, xendev, next);
> -	qemu_free(xendev);
> +        QTAILQ_REMOVE(&xendevs, xendev, next);
> +        qemu_free(xendev);
>       }
>       return NULL;
>   }
> @@ -285,14 +285,14 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
>   static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
>   {
>       if (node == NULL  ||  strcmp(node, "online") == 0) {
> -	if (xenstore_read_be_int(xendev, "online",&xendev->online) == -1)
> -	    xendev->online = 0;
> +        if (xenstore_read_be_int(xendev, "online",&xendev->online) == -1)
> +            xendev->online = 0;
>       }
>
>       if (node) {
> -	xen_be_printf(xendev, 2, "backend update: %s\n", node);
> -	if (xendev->ops->backend_changed)
> -	    xendev->ops->backend_changed(xendev, node);
> +        xen_be_printf(xendev, 2, "backend update: %s\n", node);
> +        if (xendev->ops->backend_changed)
> +            xendev->ops->backend_changed(xendev, node);
>       }
>   }
>
> @@ -301,25 +301,25 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
>       int fe_state;
>
>       if (node == NULL  ||  strcmp(node, "state") == 0) {
> -	if (xenstore_read_fe_int(xendev, "state",&fe_state) == -1)
> -	    fe_state = XenbusStateUnknown;
> -	if (xendev->fe_state != fe_state)
> -	    xen_be_printf(xendev, 1, "frontend state: %s ->  %s\n",
> -			  xenbus_strstate(xendev->fe_state),
> -			  xenbus_strstate(fe_state));
> -	xendev->fe_state = fe_state;
> +        if (xenstore_read_fe_int(xendev, "state",&fe_state) == -1)
> +            fe_state = XenbusStateUnknown;
> +        if (xendev->fe_state != fe_state)
> +            xen_be_printf(xendev, 1, "frontend state: %s ->  %s\n",
> +                          xenbus_strstate(xendev->fe_state),
> +                          xenbus_strstate(fe_state));
> +        xendev->fe_state = fe_state;
>       }
>       if (node == NULL  ||  strcmp(node, "protocol") == 0) {
> -	qemu_free(xendev->protocol);
> -	xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
> -	if (xendev->protocol)
> -	    xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
> +        qemu_free(xendev->protocol);
> +        xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
> +        if (xendev->protocol)
> +            xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
>       }
>
>       if (node) {
> -	xen_be_printf(xendev, 2, "frontend update: %s\n", node);
> -	if (xendev->ops->frontend_changed)
> -	    xendev->ops->frontend_changed(xendev, node);
> +        xen_be_printf(xendev, 2, "frontend update: %s\n", node);
> +        if (xendev->ops->frontend_changed)
> +            xendev->ops->frontend_changed(xendev, node);
>       }
>   }
>
> @@ -340,28 +340,28 @@ static int xen_be_try_setup(struct XenDevice *xendev)
>       int be_state;
>
>       if (xenstore_read_be_int(xendev, "state",&be_state) == -1) {
> -	xen_be_printf(xendev, 0, "reading backend state failed\n");
> -	return -1;
> +        xen_be_printf(xendev, 0, "reading backend state failed\n");
> +        return -1;
>       }
>
>       if (be_state != XenbusStateInitialising) {
> -	xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
> -		      xenbus_strstate(be_state));
> -	return -1;
> +        xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
> +                      xenbus_strstate(be_state));
> +        return -1;
>       }
>
>       xendev->fe = xenstore_read_be_str(xendev, "frontend");
>       if (xendev->fe == NULL) {
> -	xen_be_printf(xendev, 0, "reading frontend path failed\n");
> -	return -1;
> +        xen_be_printf(xendev, 0, "reading frontend path failed\n");
> +        return -1;
>       }
>
>       /* setup frontend watch */
>       snprintf(token, sizeof(token), "fe:%p", xendev);
>       if (!xs_watch(xenstore, xendev->fe, token)) {
> -	xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
> -		      xendev->fe);
> -	return -1;
> +        xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
> +                      xendev->fe);
> +        return -1;
>       }
>       xen_be_set_state(xendev, XenbusStateInitialising);
>
> @@ -383,15 +383,15 @@ static int xen_be_try_init(struct XenDevice *xendev)
>       int rc = 0;
>
>       if (!xendev->online) {
> -	xen_be_printf(xendev, 1, "not online\n");
> -	return -1;
> +        xen_be_printf(xendev, 1, "not online\n");
> +        return -1;
>       }
>
>       if (xendev->ops->init)
> -	rc = xendev->ops->init(xendev);
> +        rc = xendev->ops->init(xendev);
>       if (rc != 0) {
> -	xen_be_printf(xendev, 1, "init() failed\n");
> -	return rc;
> +        xen_be_printf(xendev, 1, "init() failed\n");
> +        return rc;
>       }
>
>       xenstore_write_be_str(xendev, "hotplug-status", "connected");
> @@ -411,20 +411,20 @@ static int xen_be_try_connect(struct XenDevice *xendev)
>       int rc = 0;
>
>       if (xendev->fe_state != XenbusStateInitialised&&
> -	xendev->fe_state != XenbusStateConnected) {
> -	if (xendev->ops->flags&  DEVOPS_FLAG_IGNORE_STATE) {
> -	    xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
> -	} else {
> -	    xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
> -	    return -1;
> -	}
> +        xendev->fe_state != XenbusStateConnected) {
> +        if (xendev->ops->flags&  DEVOPS_FLAG_IGNORE_STATE) {
> +            xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
> +        } else {
> +            xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
> +            return -1;
> +        }
>       }
>
>       if (xendev->ops->connect)
> -	rc = xendev->ops->connect(xendev);
> +        rc = xendev->ops->connect(xendev);
>       if (rc != 0) {
> -	xen_be_printf(xendev, 0, "connect() failed\n");
> -	return rc;
> +        xen_be_printf(xendev, 0, "connect() failed\n");
> +        return rc;
>       }
>
>       xen_be_set_state(xendev, XenbusStateConnected);
> @@ -441,7 +441,7 @@ static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
>       if (xendev->be_state != XenbusStateClosing&&
>           xendev->be_state != XenbusStateClosed&&
>           xendev->ops->disconnect)
> -	xendev->ops->disconnect(xendev);
> +        xendev->ops->disconnect(xendev);
>       if (xendev->be_state != state)
>           xen_be_set_state(xendev, state);
>   }
> @@ -468,31 +468,31 @@ void xen_be_check_state(struct XenDevice *xendev)
>
>       /* frontend may request shutdown from almost anywhere */
>       if (xendev->fe_state == XenbusStateClosing ||
> -	xendev->fe_state == XenbusStateClosed) {
> -	xen_be_disconnect(xendev, xendev->fe_state);
> -	return;
> +        xendev->fe_state == XenbusStateClosed) {
> +        xen_be_disconnect(xendev, xendev->fe_state);
> +        return;
>       }
>
>       /* check for possible backend state transitions */
>       for (;;) {
> -	switch (xendev->be_state) {
> -	case XenbusStateUnknown:
> -	    rc = xen_be_try_setup(xendev);
> -	    break;
> -	case XenbusStateInitialising:
> -	    rc = xen_be_try_init(xendev);
> -	    break;
> -	case XenbusStateInitWait:
> -	    rc = xen_be_try_connect(xendev);
> -	    break;
> +        switch (xendev->be_state) {
> +        case XenbusStateUnknown:
> +            rc = xen_be_try_setup(xendev);
> +            break;
> +        case XenbusStateInitialising:
> +            rc = xen_be_try_init(xendev);
> +            break;
> +        case XenbusStateInitWait:
> +            rc = xen_be_try_connect(xendev);
> +            break;
>           case XenbusStateClosed:
>               rc = xen_be_try_reset(xendev);
>               break;
> -	default:
> -	    rc = -1;
> -	}
> -	if (rc != 0)
> -	    break;
> +        default:
> +            rc = -1;
> +        }
> +        if (rc != 0)
> +            break;
>       }
>   }
>
> @@ -511,26 +511,26 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
>       snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
>       free(dom0);
>       if (!xs_watch(xenstore, path, token)) {
> -	xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
> -	return -1;
> +        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);
>       if (!dev)
> -	return 0;
> +        return 0;
>       for (j = 0; j<  cdev; j++) {
> -	xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
> -	if (xendev == NULL)
> -	    continue;
> -	xen_be_check_state(xendev);
> +        xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
> +        if (xendev == NULL)
> +            continue;
> +        xen_be_check_state(xendev);
>       }
>       free(dev);
>       return 0;
>   }
>
>   static void xenstore_update_be(char *watch, char *type, int dom,
> -			       struct XenDevOps *ops)
> +                               struct XenDevOps *ops)
>   {
>       struct XenDevice *xendev;
>       char path[XEN_BUFSIZE], *dom0;
> @@ -540,24 +540,24 @@ static void xenstore_update_be(char *watch, char *type, int dom,
>       len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
>       free(dom0);
>       if (strncmp(path, watch, len) != 0)
> -	return;
> +        return;
>       if (sscanf(watch+len, "/%u/%255s",&dev, path) != 2) {
> -	strcpy(path, "");
> -	if (sscanf(watch+len, "/%u",&dev) != 1)
> -	    dev = -1;
> +        strcpy(path, "");
> +        if (sscanf(watch+len, "/%u",&dev) != 1)
> +            dev = -1;
>       }
>       if (dev == -1)
> -	return;
> +        return;
>
>       if (0) {
> -	/* FIXME: detect devices being deleted from xenstore ... */
> -	xen_be_del_xendev(dom, dev);
> +        /* FIXME: detect devices being deleted from xenstore ... */
> +        xen_be_del_xendev(dom, dev);
>       }
>
>       xendev = xen_be_get_xendev(type, dom, dev, ops);
>       if (xendev != NULL) {
> -	xen_be_backend_changed(xendev, path);
> -	xen_be_check_state(xendev);
> +        xen_be_backend_changed(xendev, path);
> +        xen_be_check_state(xendev);
>       }
>   }
>
> @@ -568,9 +568,9 @@ static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
>
>       len = strlen(xendev->fe);
>       if (strncmp(xendev->fe, watch, len) != 0)
> -	return;
> +        return;
>       if (watch[len] != '/')
> -	return;
> +        return;
>       node = watch + len + 1;
>
>       xen_be_frontend_changed(xendev, node);
> @@ -585,13 +585,13 @@ static void xenstore_update(void *unused)
>
>       vec = xs_read_watch(xenstore,&count);
>       if (vec == NULL)
> -	goto cleanup;
> +        goto cleanup;
>
>       if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
>                  &type,&dom,&ops) == 3)
> -	xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
> +        xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
>       if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR,&ptr) == 1)
> -	xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
> +        xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
>
>   cleanup:
>       free(vec);
> @@ -604,14 +604,14 @@ static void xen_be_evtchn_event(void *opaque)
>
>       port = xc_evtchn_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;
> +        xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n",
> +                      port, xendev->local_port);
> +        return;
>       }
>       xc_evtchn_unmask(xendev->evtchndev, port);
>
>       if (xendev->ops->event)
> -	xendev->ops->event(xendev);
> +        xendev->ops->event(xendev);
>   }
>
>   /* -------------------------------------------------------------------- */
> @@ -620,17 +620,17 @@ int xen_be_init(void)
>   {
>       xenstore = xs_daemon_open();
>       if (!xenstore) {
> -	xen_be_printf(NULL, 0, "can't connect to xenstored\n");
> -	return -1;
> +        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)
> -	goto err;
> +        goto err;
>
>       xen_xc = xc_interface_open();
>       if (xen_xc == -1) {
> -	xen_be_printf(NULL, 0, "can't open xen interface\n");
> -	goto err;
> +        xen_be_printf(NULL, 0, "can't open xen interface\n");
> +        goto err;
>       }
>       return 0;
>
> @@ -650,23 +650,23 @@ int xen_be_register(const char *type, struct XenDevOps *ops)
>   int xen_be_bind_evtchn(struct XenDevice *xendev)
>   {
>       if (xendev->local_port != -1)
> -	return 0;
> +        return 0;
>       xendev->local_port = xc_evtchn_bind_interdomain
> -	(xendev->evtchndev, xendev->dom, xendev->remote_port);
> +        (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, 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),
> -			xen_be_evtchn_event, NULL, xendev);
> +                        xen_be_evtchn_event, NULL, xendev);
>       return 0;
>   }
>
>   void xen_be_unbind_evtchn(struct XenDevice *xendev)
>   {
>       if (xendev->local_port == -1)
> -	return;
> +        return;
>       qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
>       xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
>       xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
> diff --git a/hw/xen_disk.c b/hw/xen_disk.c
> index ed9e5eb..7f6aaca 100644
> --- a/hw/xen_disk.c
> +++ b/hw/xen_disk.c
> @@ -120,17 +120,17 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
>       struct ioreq *ioreq = NULL;
>
>       if (QLIST_EMPTY(&blkdev->freelist)) {
> -	if (blkdev->requests_total>= max_requests)
> -	    goto out;
> -	/* allocate new struct */
> -	ioreq = qemu_mallocz(sizeof(*ioreq));
> -	ioreq->blkdev = blkdev;
> -	blkdev->requests_total++;
> +        if (blkdev->requests_total>= max_requests)
> +            goto out;
> +        /* allocate new struct */
> +        ioreq = qemu_mallocz(sizeof(*ioreq));
> +        ioreq->blkdev = blkdev;
> +        blkdev->requests_total++;
>           qemu_iovec_init(&ioreq->v, BLKIF_MAX_SEGMENTS_PER_REQUEST);
>       } else {
> -	/* get one from freelist */
> -	ioreq = QLIST_FIRST(&blkdev->freelist);
> -	QLIST_REMOVE(ioreq, list);
> +        /* get one from freelist */
> +        ioreq = QLIST_FIRST(&blkdev->freelist);
> +        QLIST_REMOVE(ioreq, list);
>           qemu_iovec_reset(&ioreq->v);
>       }
>       QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
> @@ -173,30 +173,30 @@ static int ioreq_parse(struct ioreq *ioreq)
>       int i;
>
>       xen_be_printf(&blkdev->xendev, 3,
> -		  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
> -		  ioreq->req.operation, ioreq->req.nr_segments,
> -		  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
> +                  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
> +                  ioreq->req.operation, ioreq->req.nr_segments,
> +                  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
>       switch (ioreq->req.operation) {
>       case BLKIF_OP_READ:
> -	ioreq->prot = PROT_WRITE; /* to memory */
> -	break;
> +        ioreq->prot = PROT_WRITE; /* to memory */
> +        break;
>       case BLKIF_OP_WRITE_BARRIER:
>           if (!ioreq->req.nr_segments) {
>               ioreq->presync = 1;
>               return 0;
>           }
> -	if (!syncwrite)
> -	    ioreq->presync = ioreq->postsync = 1;
> -	/* fall through */
> +        if (!syncwrite)
> +            ioreq->presync = ioreq->postsync = 1;
> +        /* fall through */
>       case BLKIF_OP_WRITE:
> -	ioreq->prot = PROT_READ; /* from memory */
> -	if (syncwrite)
> -	    ioreq->postsync = 1;
> -	break;
> +        ioreq->prot = PROT_READ; /* from memory */
> +        if (syncwrite)
> +            ioreq->postsync = 1;
> +        break;
>       default:
> -	xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
> -		      ioreq->req.operation);
> -	goto err;
> +        xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
> +                      ioreq->req.operation);
> +        goto err;
>       };
>
>       if (ioreq->req.operation != BLKIF_OP_READ&&  blkdev->mode[0] != 'w') {
> @@ -206,29 +206,29 @@ static int ioreq_parse(struct ioreq *ioreq)
>
>       ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
>       for (i = 0; i<  ioreq->req.nr_segments; i++) {
> -	if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
> -	    xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
> -	    goto err;
> -	}
> -	if (ioreq->req.seg[i].first_sect>  ioreq->req.seg[i].last_sect) {
> -	    xen_be_printf(&blkdev->xendev, 0, "error: first>  last sector\n");
> -	    goto err;
> -	}
> -	if (ioreq->req.seg[i].last_sect * BLOCK_SIZE>= XC_PAGE_SIZE) {
> -	    xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
> -	    goto err;
> -	}
> -
> -	ioreq->domids[i] = blkdev->xendev.dom;
> -	ioreq->refs[i]   = ioreq->req.seg[i].gref;
> -
> -	mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
> -	len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
> +        if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
> +            xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
> +            goto err;
> +        }
> +        if (ioreq->req.seg[i].first_sect>  ioreq->req.seg[i].last_sect) {
> +            xen_be_printf(&blkdev->xendev, 0, "error: first>  last sector\n");
> +            goto err;
> +        }
> +        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE>= XC_PAGE_SIZE) {
> +            xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
> +            goto err;
> +        }
> +
> +        ioreq->domids[i] = blkdev->xendev.dom;
> +        ioreq->refs[i]   = ioreq->req.seg[i].gref;
> +
> +        mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
> +        len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
>           qemu_iovec_add(&ioreq->v, (void*)mem, len);
>       }
>       if (ioreq->start + ioreq->v.size>  blkdev->file_size) {
> -	xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
> -	goto err;
> +        xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
> +        goto err;
>       }
>       return 0;
>
> @@ -245,23 +245,23 @@ static void ioreq_unmap(struct ioreq *ioreq)
>       if (ioreq->v.niov == 0)
>           return;
>       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",
> -			  strerror(errno));
> -	ioreq->blkdev->cnt_map -= ioreq->v.niov;
> -	ioreq->pages = NULL;
> +        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",
> +                          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",
> -			      strerror(errno));
> -	    ioreq->blkdev->cnt_map--;
> -	    ioreq->page[i] = NULL;
> -	}
> +        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",
> +                              strerror(errno));
> +            ioreq->blkdev->cnt_map--;
> +            ioreq->page[i] = NULL;
> +        }
>       }
>   }
>
> @@ -273,32 +273,32 @@ static int ioreq_map(struct ioreq *ioreq)
>       if (ioreq->v.niov == 0)
>           return 0;
>       if (batch_maps) {
> -	ioreq->pages = xc_gnttab_map_grant_refs
> -	    (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
> -	if (ioreq->pages == NULL) {
> -	    xen_be_printf(&ioreq->blkdev->xendev, 0,
> -			  "can't map %d grant refs (%s, %d maps)\n",
> -			  ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
> -	    return -1;
> -	}
> -	for (i = 0; i<  ioreq->v.niov; i++)
> -	    ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
> -		(uintptr_t)ioreq->v.iov[i].iov_base;
> -	ioreq->blkdev->cnt_map += ioreq->v.niov;
> +        ioreq->pages = xc_gnttab_map_grant_refs
> +            (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
> +        if (ioreq->pages == NULL) {
> +            xen_be_printf(&ioreq->blkdev->xendev, 0,
> +                          "can't map %d grant refs (%s, %d maps)\n",
> +                          ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
> +            return -1;
> +        }
> +        for (i = 0; i<  ioreq->v.niov; i++)
> +            ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
> +                (uintptr_t)ioreq->v.iov[i].iov_base;
> +        ioreq->blkdev->cnt_map += ioreq->v.niov;
>       } else  {
> -	for (i = 0; i<  ioreq->v.niov; i++) {
> -	    ioreq->page[i] = xc_gnttab_map_grant_ref
> -		(gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
> -	    if (ioreq->page[i] == NULL) {
> -		xen_be_printf(&ioreq->blkdev->xendev, 0,
> -			      "can't map grant ref %d (%s, %d maps)\n",
> -			      ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
> -		ioreq_unmap(ioreq);
> -		return -1;
> -	    }
> -	    ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
> -	    ioreq->blkdev->cnt_map++;
> -	}
> +        for (i = 0; i<  ioreq->v.niov; i++) {
> +            ioreq->page[i] = xc_gnttab_map_grant_ref
> +                (gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
> +            if (ioreq->page[i] == NULL) {
> +                xen_be_printf(&ioreq->blkdev->xendev, 0,
> +                              "can't map grant ref %d (%s, %d maps)\n",
> +                              ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
> +                ioreq_unmap(ioreq);
> +                return -1;
> +            }
> +            ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
> +            ioreq->blkdev->cnt_map++;
> +        }
>       }
>       return 0;
>   }
> @@ -310,53 +310,53 @@ static int ioreq_runio_qemu_sync(struct ioreq *ioreq)
>       off_t pos;
>
>       if (ioreq->req.nr_segments&&  ioreq_map(ioreq) == -1)
> -	goto err;
> +        goto err;
>       if (ioreq->presync)
> -	bdrv_flush(blkdev->bs);
> +        bdrv_flush(blkdev->bs);
>
>       switch (ioreq->req.operation) {
>       case BLKIF_OP_READ:
> -	pos = ioreq->start;
> -	for (i = 0; i<  ioreq->v.niov; i++) {
> -	    rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,
> -			   ioreq->v.iov[i].iov_base,
> -			   ioreq->v.iov[i].iov_len / BLOCK_SIZE);
> -	    if (rc != 0) {
> -		xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",
> -			      ioreq->v.iov[i].iov_base,
> -			      ioreq->v.iov[i].iov_len);
> -		goto err;
> -	    }
> -	    len += ioreq->v.iov[i].iov_len;
> -	    pos += ioreq->v.iov[i].iov_len;
> -	}
> -	break;
> +        pos = ioreq->start;
> +        for (i = 0; i<  ioreq->v.niov; i++) {
> +            rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,
> +                           ioreq->v.iov[i].iov_base,
> +                           ioreq->v.iov[i].iov_len / BLOCK_SIZE);
> +            if (rc != 0) {
> +                xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",
> +                              ioreq->v.iov[i].iov_base,
> +                              ioreq->v.iov[i].iov_len);
> +                goto err;
> +            }
> +            len += ioreq->v.iov[i].iov_len;
> +            pos += ioreq->v.iov[i].iov_len;
> +        }
> +        break;
>       case BLKIF_OP_WRITE:
>       case BLKIF_OP_WRITE_BARRIER:
>           if (!ioreq->req.nr_segments)
>               break;
> -	pos = ioreq->start;
> -	for (i = 0; i<  ioreq->v.niov; i++) {
> -	    rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,
> -			    ioreq->v.iov[i].iov_base,
> -			    ioreq->v.iov[i].iov_len / BLOCK_SIZE);
> -	    if (rc != 0) {
> -		xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",
> -			      ioreq->v.iov[i].iov_base,
> -			      ioreq->v.iov[i].iov_len);
> -		goto err;
> -	    }
> -	    len += ioreq->v.iov[i].iov_len;
> -	    pos += ioreq->v.iov[i].iov_len;
> -	}
> -	break;
> +        pos = ioreq->start;
> +        for (i = 0; i<  ioreq->v.niov; i++) {
> +            rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,
> +                            ioreq->v.iov[i].iov_base,
> +                            ioreq->v.iov[i].iov_len / BLOCK_SIZE);
> +            if (rc != 0) {
> +                xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",
> +                              ioreq->v.iov[i].iov_base,
> +                              ioreq->v.iov[i].iov_len);
> +                goto err;
> +            }
> +            len += ioreq->v.iov[i].iov_len;
> +            pos += ioreq->v.iov[i].iov_len;
> +        }
> +        break;
>       default:
> -	/* unknown operation (shouldn't happen -- parse catches this) */
> -	goto err;
> +        /* unknown operation (shouldn't happen -- parse catches this) */
> +        goto err;
>       }
>
>       if (ioreq->postsync)
> -	bdrv_flush(blkdev->bs);
> +        bdrv_flush(blkdev->bs);
>       ioreq->status = BLKIF_RSP_OKAY;
>
>       ioreq_unmap(ioreq);
> @@ -393,11 +393,11 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
>       struct XenBlkDev *blkdev = ioreq->blkdev;
>
>       if (ioreq->req.nr_segments&&  ioreq_map(ioreq) == -1)
> -	goto err;
> +        goto err;
>
>       ioreq->aio_inflight++;
>       if (ioreq->presync)
> -	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
> +        bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
>
>       switch (ioreq->req.operation) {
>       case BLKIF_OP_READ:
> @@ -405,7 +405,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
>           bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
>                          &ioreq->v, ioreq->v.size / BLOCK_SIZE,
>                          qemu_aio_complete, ioreq);
> -	break;
> +        break;
>       case BLKIF_OP_WRITE:
>       case BLKIF_OP_WRITE_BARRIER:
>           ioreq->aio_inflight++;
> @@ -414,14 +414,14 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
>           bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
>                           &ioreq->v, ioreq->v.size / BLOCK_SIZE,
>                           qemu_aio_complete, ioreq);
> -	break;
> +        break;
>       default:
> -	/* unknown operation (shouldn't happen -- parse catches this) */
> -	goto err;
> +        /* unknown operation (shouldn't happen -- parse catches this) */
> +        goto err;
>       }
>
>       if (ioreq->postsync)
> -	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
> +        bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
>       qemu_aio_complete(ioreq, 0);
>
>       return 0;
> @@ -446,36 +446,36 @@ static int blk_send_response_one(struct ioreq *ioreq)
>       /* Place on the response ring for the relevant domain. */
>       switch (blkdev->protocol) {
>       case BLKIF_PROTOCOL_NATIVE:
> -	dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
> -	break;
> +        dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
> +        break;
>       case BLKIF_PROTOCOL_X86_32:
>           dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
>                                   blkdev->rings.x86_32_part.rsp_prod_pvt);
> -	break;
> +        break;
>       case BLKIF_PROTOCOL_X86_64:
>           dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
>                                   blkdev->rings.x86_64_part.rsp_prod_pvt);
> -	break;
> +        break;
>       default:
> -	dst = NULL;
> +        dst = NULL;
>       }
>       memcpy(dst,&resp, sizeof(resp));
>       blkdev->rings.common.rsp_prod_pvt++;
>
>       RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
>       if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
> -	/*
> -	 * Tail check for pending requests. Allows frontend to avoid
> -	 * notifications if requests are already in flight (lower
> -	 * overheads and promotes batching).
> -	 */
> -	RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
> +        /*
> +         * Tail check for pending requests. Allows frontend to avoid
> +         * notifications if requests are already in flight (lower
> +         * overheads and promotes batching).
> +         */
> +        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
>       } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
> -	have_requests = 1;
> +        have_requests = 1;
>       }
>
>       if (have_requests)
> -	blkdev->more_work++;
> +        blkdev->more_work++;
>       return send_notify;
>   }
>
> @@ -487,28 +487,28 @@ static void blk_send_response_all(struct XenBlkDev *blkdev)
>
>       while (!QLIST_EMPTY(&blkdev->finished)) {
>           ioreq = QLIST_FIRST(&blkdev->finished);
> -	send_notify += blk_send_response_one(ioreq);
> -	ioreq_release(ioreq);
> +        send_notify += blk_send_response_one(ioreq);
> +        ioreq_release(ioreq);
>       }
>       if (send_notify)
> -	xen_be_send_notify(&blkdev->xendev);
> +        xen_be_send_notify(&blkdev->xendev);
>   }
>
>   static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_IDX rc)
>   {
>       switch (blkdev->protocol) {
>       case BLKIF_PROTOCOL_NATIVE:
> -	memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
> -	       sizeof(ioreq->req));
> -	break;
> +        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
> +               sizeof(ioreq->req));
> +        break;
>       case BLKIF_PROTOCOL_X86_32:
>           blkif_get_x86_32_req(&ioreq->req,
>                                RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
> -	break;
> +        break;
>       case BLKIF_PROTOCOL_X86_64:
>           blkif_get_x86_64_req(&ioreq->req,
>                                RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
> -	break;
> +        break;
>       }
>       return 0;
>   }
> @@ -589,44 +589,44 @@ static int blk_init(struct XenDevice *xendev)
>
>       /* read xenstore entries */
>       if (blkdev->params == NULL) {
> -	blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
> +        blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
>           h = strchr(blkdev->params, ':');
> -	if (h != NULL) {
> -	    blkdev->fileproto = blkdev->params;
> -	    blkdev->filename  = h+1;
> -	    *h = 0;
> -	} else {
> -	    blkdev->fileproto = "<unset>";
> -	    blkdev->filename  = blkdev->params;
> -	}
> +        if (h != NULL) {
> +            blkdev->fileproto = blkdev->params;
> +            blkdev->filename  = h+1;
> +            *h = 0;
> +        } else {
> +            blkdev->fileproto = "<unset>";
> +            blkdev->filename  = blkdev->params;
> +        }
>       }
>       if (blkdev->mode == NULL)
> -	blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
> +        blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
>       if (blkdev->type == NULL)
> -	blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type");
> +        blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type");
>       if (blkdev->dev == NULL)
> -	blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev");
> +        blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev");
>       if (blkdev->devtype == NULL)
> -	blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type");
> +        blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type");
>
>       /* do we have all we need? */
>       if (blkdev->params == NULL ||
> -	blkdev->mode == NULL   ||
> -	blkdev->type == NULL   ||
> -	blkdev->dev == NULL)
> -	return -1;
> +        blkdev->mode == NULL   ||
> +        blkdev->type == NULL   ||
> +        blkdev->dev == NULL)
> +        return -1;
>
>       /* read-only ? */
>       if (strcmp(blkdev->mode, "w") == 0) {
> -	qflags = BDRV_O_RDWR;
> +        qflags = BDRV_O_RDWR;
>       } else {
> -	qflags = 0;
> -	info  |= VDISK_READONLY;
> +        qflags = 0;
> +        info  |= VDISK_READONLY;
>       }
>
>       /* cdrom ? */
>       if (blkdev->devtype&&  !strcmp(blkdev->devtype, "cdrom"))
> -	info  |= VDISK_CDROM;
> +        info  |= VDISK_CDROM;
>
>       /* init qemu block driver */
>       index = (blkdev->xendev.dev - 202 * 256) / 16;
> @@ -643,7 +643,7 @@ static int blk_init(struct XenDevice *xendev)
>       } else {
>           /* setup via qemu cmdline ->  already setup for us */
>           xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
> -	blkdev->bs = blkdev->dinfo->bdrv;
> +        blkdev->bs = blkdev->dinfo->bdrv;
>       }
>       blkdev->file_blk  = BLOCK_SIZE;
>       blkdev->file_size = bdrv_getlength(blkdev->bs);
> @@ -651,21 +651,21 @@ static int blk_init(struct XenDevice *xendev)
>           xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
>                         (int)blkdev->file_size, strerror(-blkdev->file_size),
>                         blkdev->bs->drv ? blkdev->bs->drv->format_name : "-");
> -	blkdev->file_size = 0;
> +        blkdev->file_size = 0;
>       }
>       have_barriers = blkdev->bs->drv&&  blkdev->bs->drv->bdrv_flush ? 1 : 0;
>
>       xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
> -		  " size %" PRId64 " (%" PRId64 " MB)\n",
> -		  blkdev->type, blkdev->fileproto, blkdev->filename,
> -		  blkdev->file_size, blkdev->file_size>>  20);
> +                  " size %" PRId64 " (%" PRId64 " MB)\n",
> +                  blkdev->type, blkdev->fileproto, blkdev->filename,
> +                  blkdev->file_size, blkdev->file_size>>  20);
>
>       /* fill info */
>       xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers);
>       xenstore_write_be_int(&blkdev->xendev, "info",            info);
>       xenstore_write_be_int(&blkdev->xendev, "sector-size",     blkdev->file_blk);
>       xenstore_write_be_int(&blkdev->xendev, "sectors",
> -			  blkdev->file_size / blkdev->file_blk);
> +                          blkdev->file_size / blkdev->file_blk);
>       return 0;
>   }
>
> @@ -674,10 +674,10 @@ static int blk_connect(struct XenDevice *xendev)
>       struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
>
>       if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref",&blkdev->ring_ref) == -1)
> -	return -1;
> +        return -1;
>       if (xenstore_read_fe_int(&blkdev->xendev, "event-channel",
>                                &blkdev->xendev.remote_port) == -1)
> -	return -1;
> +        return -1;
>
>       blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
>       if (blkdev->xendev.protocol) {
> @@ -688,42 +688,42 @@ static int blk_connect(struct XenDevice *xendev)
>       }
>
>       blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev,
> -					    blkdev->xendev.dom,
> -					    blkdev->ring_ref,
> -					    PROT_READ | PROT_WRITE);
> +                                            blkdev->xendev.dom,
> +                                            blkdev->ring_ref,
> +                                            PROT_READ | PROT_WRITE);
>       if (!blkdev->sring)
> -	return -1;
> +        return -1;
>       blkdev->cnt_map++;
>
>       switch (blkdev->protocol) {
>       case BLKIF_PROTOCOL_NATIVE:
>       {
> -	blkif_sring_t *sring_native = blkdev->sring;
> -	BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);
> -	break;
> +        blkif_sring_t *sring_native = blkdev->sring;
> +        BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);
> +        break;
>       }
>       case BLKIF_PROTOCOL_X86_32:
>       {
> -	blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
> +        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
>
>           BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, XC_PAGE_SIZE);
> -	break;
> +        break;
>       }
>       case BLKIF_PROTOCOL_X86_64:
>       {
> -	blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
> +        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
>
>           BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, XC_PAGE_SIZE);
> -	break;
> +        break;
>       }
>       }
>
>       xen_be_bind_evtchn(&blkdev->xendev);
>
>       xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
> -		  "remote port %d, local port %d\n",
> -		  blkdev->xendev.protocol, blkdev->ring_ref,
> -		  blkdev->xendev.remote_port, blkdev->xendev.local_port);
> +                  "remote port %d, local port %d\n",
> +                  blkdev->xendev.protocol, blkdev->ring_ref,
> +                  blkdev->xendev.remote_port, blkdev->xendev.local_port);
>       return 0;
>   }
>
> @@ -737,14 +737,14 @@ static void blk_disconnect(struct XenDevice *xendev)
>               bdrv_close(blkdev->bs);
>               bdrv_delete(blkdev->bs);
>           }
> -	blkdev->bs = NULL;
> +        blkdev->bs = NULL;
>       }
>       xen_be_unbind_evtchn(&blkdev->xendev);
>
>       if (blkdev->sring) {
> -	xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
> -	blkdev->cnt_map--;
> -	blkdev->sring = NULL;
> +        xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
> +        blkdev->cnt_map--;
> +        blkdev->sring = NULL;
>       }
>   }
>
> @@ -754,10 +754,10 @@ static int blk_free(struct XenDevice *xendev)
>       struct ioreq *ioreq;
>
>       while (!QLIST_EMPTY(&blkdev->freelist)) {
> -	ioreq = QLIST_FIRST(&blkdev->freelist);
> +        ioreq = QLIST_FIRST(&blkdev->freelist);
>           QLIST_REMOVE(ioreq, list);
>           qemu_iovec_destroy(&ioreq->v);
> -	qemu_free(ioreq);
> +        qemu_free(ioreq);
>       }
>
>       qemu_free(blkdev->params);
> diff --git a/hw/xen_nic.c b/hw/xen_nic.c
> index 08055b8..8fcf856 100644
> --- a/hw/xen_nic.c
> +++ b/hw/xen_nic.c
> @@ -75,19 +75,19 @@ static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, i
>
>   #if 0
>       if (txp->flags&  NETTXF_extra_info)
> -	RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
> +        RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
>   #endif
>
>       netdev->tx_ring.rsp_prod_pvt = ++i;
>       RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
>       if (notify)
> -	xen_be_send_notify(&netdev->xendev);
> +        xen_be_send_notify(&netdev->xendev);
>
>       if (i == netdev->tx_ring.req_cons) {
> -	int more_to_do;
> -	RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
> -	if (more_to_do)
> -	    netdev->tx_work++;
> +        int more_to_do;
> +        RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
> +        if (more_to_do)
> +            netdev->tx_work++;
>       }
>   }
>
> @@ -101,10 +101,10 @@ static void net_tx_error(struct XenNetDev *netdev, netif_tx_request_t *txp, RING
>       RING_IDX cons = netdev->tx_ring.req_cons;
>
>       do {
> -	make_tx_response(netif, txp, NETIF_RSP_ERROR);
> -	if (cons>= end)
> -	    break;
> -	txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
> +        make_tx_response(netif, txp, NETIF_RSP_ERROR);
> +        if (cons>= end)
> +            break;
> +        txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
>       } while (1);
>       netdev->tx_ring.req_cons = cons;
>       netif_schedule_work(netif);
> @@ -122,75 +122,75 @@ static void net_tx_packets(struct XenNetDev *netdev)
>       void *tmpbuf = NULL;
>
>       for (;;) {
> -	rc = netdev->tx_ring.req_cons;
> -	rp = netdev->tx_ring.sring->req_prod;
> -	xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
> +        rc = netdev->tx_ring.req_cons;
> +        rp = netdev->tx_ring.sring->req_prod;
> +        xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
>
> -	while ((rc != rp)) {
> -	    if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc))
> -		break;
> -	    memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
> -	    netdev->tx_ring.req_cons = ++rc;
> +        while ((rc != rp)) {
> +            if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc))
> +                break;
> +            memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
> +            netdev->tx_ring.req_cons = ++rc;
>
>   #if 1
> -	    /* should not happen in theory, we don't announce the *
> -	     * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
> -	    if (txreq.flags&  NETTXF_extra_info) {
> -		xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
> -		net_tx_error(netdev,&txreq, rc);
> -		continue;
> -	    }
> -	    if (txreq.flags&  NETTXF_more_data) {
> -		xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
> -		net_tx_error(netdev,&txreq, rc);
> -		continue;
> -	    }
> +            /* should not happen in theory, we don't announce the *
> +             * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
> +            if (txreq.flags&  NETTXF_extra_info) {
> +                xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
> +                net_tx_error(netdev,&txreq, rc);
> +                continue;
> +            }
> +            if (txreq.flags&  NETTXF_more_data) {
> +                xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
> +                net_tx_error(netdev,&txreq, rc);
> +                continue;
> +            }
>   #endif
>
> -	    if (txreq.size<  14) {
> -		xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
> -		net_tx_error(netdev,&txreq, rc);
> -		continue;
> -	    }
> -
> -	    if ((txreq.offset + txreq.size)>  XC_PAGE_SIZE) {
> -		xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
> -		net_tx_error(netdev,&txreq, rc);
> -		continue;
> -	    }
> -
> -	    xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
> -			  txreq.gref, txreq.offset, txreq.size, txreq.flags,
> -			  (txreq.flags&  NETTXF_csum_blank)     ? " csum_blank"     : "",
> -			  (txreq.flags&  NETTXF_data_validated) ? " data_validated" : "",
> -			  (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);
> -	    if (page == NULL) {
> -		xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
> +            if (txreq.size<  14) {
> +                xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
> +                net_tx_error(netdev,&txreq, rc);
> +                continue;
> +            }
> +
> +            if ((txreq.offset + txreq.size)>  XC_PAGE_SIZE) {
> +                xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
> +                net_tx_error(netdev,&txreq, rc);
> +                continue;
> +            }
> +
> +            xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
> +                          txreq.gref, txreq.offset, txreq.size, txreq.flags,
> +                          (txreq.flags&  NETTXF_csum_blank)     ? " csum_blank"     : "",
> +                          (txreq.flags&  NETTXF_data_validated) ? " data_validated" : "",
> +                          (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);
> +            if (page == NULL) {
> +                xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
>                                 txreq.gref);
> -		net_tx_error(netdev,&txreq, rc);
> -		continue;
> -	    }
> -	    if (txreq.flags&  NETTXF_csum_blank) {
> +                net_tx_error(netdev,&txreq, rc);
> +                continue;
> +            }
> +            if (txreq.flags&  NETTXF_csum_blank) {
>                   /* have read-only mapping ->  can't fill checksum in-place */
>                   if (!tmpbuf)
>                       tmpbuf = qemu_malloc(XC_PAGE_SIZE);
>                   memcpy(tmpbuf, page + txreq.offset, txreq.size);
> -		net_checksum_calculate(tmpbuf, txreq.size);
> +                net_checksum_calculate(tmpbuf, txreq.size);
>                   qemu_send_packet(&netdev->nic->nc, tmpbuf, txreq.size);
>               } else {
>                   qemu_send_packet(&netdev->nic->nc, page + txreq.offset, txreq.size);
>               }
> -	    xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
> -	    net_tx_response(netdev,&txreq, NETIF_RSP_OKAY);
> -	}
> -	if (!netdev->tx_work)
> -	    break;
> -	netdev->tx_work = 0;
> +            xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
> +            net_tx_response(netdev,&txreq, NETIF_RSP_OKAY);
> +        }
> +        if (!netdev->tx_work)
> +            break;
> +        netdev->tx_work = 0;
>       }
>       qemu_free(tmpbuf);
>   }
> @@ -198,9 +198,9 @@ static void net_tx_packets(struct XenNetDev *netdev)
>   /* ------------------------------------------------------------- */
>
>   static void net_rx_response(struct XenNetDev *netdev,
> -			    netif_rx_request_t *req, int8_t st,
> -			    uint16_t offset, uint16_t size,
> -			    uint16_t flags)
> +                            netif_rx_request_t *req, int8_t st,
> +                            uint16_t offset, uint16_t size,
> +                            uint16_t flags)
>   {
>       RING_IDX i = netdev->rx_ring.rsp_prod_pvt;
>       netif_rx_response_t *resp;
> @@ -212,15 +212,15 @@ static void net_rx_response(struct XenNetDev *netdev,
>       resp->id         = req->id;
>       resp->status     = (int16_t)size;
>       if (st<  0)
> -	resp->status = (int16_t)st;
> +        resp->status = (int16_t)st;
>
>       xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n",
> -		  i, resp->status, resp->flags);
> +                  i, resp->status, resp->flags);
>
>       netdev->rx_ring.rsp_prod_pvt = ++i;
>       RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
>       if (notify)
> -	xen_be_send_notify(&netdev->xendev);
> +        xen_be_send_notify(&netdev->xendev);
>   }
>
>   #define NET_IP_ALIGN 2
> @@ -231,16 +231,16 @@ static int net_rx_ok(VLANClientState *nc)
>       RING_IDX rc, rp;
>
>       if (netdev->xendev.be_state != XenbusStateConnected)
> -	return 0;
> +        return 0;
>
>       rc = netdev->rx_ring.req_cons;
>       rp = netdev->rx_ring.sring->req_prod;
>       xen_rmb();
>
>       if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
> -	xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
> -		      __FUNCTION__, rc, rp);
> -	return 0;
> +        xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
> +                      __FUNCTION__, rc, rp);
> +        return 0;
>       }
>       return 1;
>   }
> @@ -253,33 +253,33 @@ static ssize_t net_rx_packet(VLANClientState *nc, const uint8_t *buf, size_t siz
>       void *page;
>
>       if (netdev->xendev.be_state != XenbusStateConnected)
> -	return -1;
> +        return -1;
>
>       rc = netdev->rx_ring.req_cons;
>       rp = netdev->rx_ring.sring->req_prod;
>       xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
>
>       if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
> -	xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
> -	return -1;
> +        xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
> +        return -1;
>       }
>       if (size>  XC_PAGE_SIZE - NET_IP_ALIGN) {
> -	xen_be_printf(&netdev->xendev, 0, "packet too big (%lu>  %ld)",
> -		      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
> -	return -1;
> +        xen_be_printf(&netdev->xendev, 0, "packet too big (%lu>  %ld)",
> +                      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
> +        return -1;
>       }
>
>       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);
> +                                   netdev->xendev.dom,
> +                                   rxreq.gref, PROT_WRITE);
>       if (page == NULL) {
> -	xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
> +        xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
>                         rxreq.gref);
> -	net_rx_response(netdev,&rxreq, NETIF_RSP_ERROR, 0, 0, 0);
> -	return -1;
> +        net_rx_response(netdev,&rxreq, NETIF_RSP_ERROR, 0, 0, 0);
> +        return -1;
>       }
>       memcpy(page + NET_IP_ALIGN, buf, size);
>       xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
> @@ -303,11 +303,11 @@ static int net_init(struct XenDevice *xendev)
>
>       /* read xenstore entries */
>       if (netdev->mac == NULL)
> -	netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac");
> +        netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac");
>
>       /* do we have all we need? */
>       if (netdev->mac == NULL)
> -	return -1;
> +        return -1;
>
>       if (net_parse_macaddr(netdev->conf.macaddr.a, netdev->mac)<  0)
>           return -1;
> @@ -334,41 +334,41 @@ static int net_connect(struct XenDevice *xendev)
>       int rx_copy;
>
>       if (xenstore_read_fe_int(&netdev->xendev, "tx-ring-ref",
> -				&netdev->tx_ring_ref) == -1)
> -	return -1;
> +&netdev->tx_ring_ref) == -1)
> +        return -1;
>       if (xenstore_read_fe_int(&netdev->xendev, "rx-ring-ref",
> -				&netdev->rx_ring_ref) == -1)
> -	return 1;
> +&netdev->rx_ring_ref) == -1)
> +        return 1;
>       if (xenstore_read_fe_int(&netdev->xendev, "event-channel",
> -				&netdev->xendev.remote_port) == -1)
> -	return -1;
> +&netdev->xendev.remote_port) == -1)
> +        return -1;
>
>       if (xenstore_read_fe_int(&netdev->xendev, "request-rx-copy",&rx_copy) == -1)
> -	rx_copy = 0;
> +        rx_copy = 0;
>       if (rx_copy == 0) {
> -	xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
> -	return -1;
> +        xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
> +        return -1;
>       }
>
>       netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
> -					  netdev->xendev.dom,
> -					  netdev->tx_ring_ref,
> -					  PROT_READ | PROT_WRITE);
> +                                          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->xendev.dom,
> +                                          netdev->rx_ring_ref,
> +                                          PROT_READ | PROT_WRITE);
>       if (!netdev->txs || !netdev->rxs)
> -	return -1;
> +        return -1;
>       BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XC_PAGE_SIZE);
>       BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XC_PAGE_SIZE);
>
>       xen_be_bind_evtchn(&netdev->xendev);
>
>       xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
> -		  "remote port %d, local port %d\n",
> -		  netdev->tx_ring_ref, netdev->rx_ring_ref,
> -		  netdev->xendev.remote_port, netdev->xendev.local_port);
> +                  "remote port %d, local port %d\n",
> +                  netdev->tx_ring_ref, netdev->rx_ring_ref,
> +                  netdev->xendev.remote_port, netdev->xendev.local_port);
>
>       net_tx_packets(netdev);
>       return 0;
> @@ -381,12 +381,12 @@ 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);
> -	netdev->txs = NULL;
> +        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
> +        netdev->txs = NULL;
>       }
>       if (netdev->rxs) {
> -	xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
> -	netdev->rxs = NULL;
> +        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
> +        netdev->rxs = NULL;
>       }
>       if (netdev->nic) {
>           qemu_del_vlan_client(&netdev->nic->nc);
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-02-02 14:49   ` anthony.perard
  (?)
@ 2011-02-24 16:11   ` Anthony Liguori
  2011-02-24 16:25       ` Anthony PERARD
  -1 siblings, 1 reply; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 16:11 UTC (permalink / raw)
  To: anthony.perard; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
> From: Anthony PERARD<anthony.perard@citrix.com>
>
> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> Acked-by: Alexander Graf<agraf@suse.de>
>    

Is this really necessary?  The advantage to building globally is that it 
keeps the code from getting unnecessary i386-isms.

Regards,

Anthony Liguori

> ---
>   Makefile.objs   |    4 ----
>   Makefile.target |    4 +++-
>   configure       |    5 +----
>   3 files changed, 4 insertions(+), 9 deletions(-)
>
> diff --git a/Makefile.objs b/Makefile.objs
> index 93406ff..d91b9bc 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -150,10 +150,6 @@ slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
>   slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
>   common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
>
> -# xen backend driver support
> -common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
> -common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
> -
>   ######################################################################
>   # libuser
>
> diff --git a/Makefile.target b/Makefile.target
> index b0ba95f..db29e96 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
>   QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>
>   # xen backend driver support
> -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
> +obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
> +obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
> +obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>
>   # Inter-VM PCI shared memory
>   obj-$(CONFIG_KVM) += ivshmem.o
> diff --git a/configure b/configure
> index 210670c..5a9121d 100755
> --- a/configure
> +++ b/configure
> @@ -1151,7 +1151,6 @@ int main(void) { xs_daemon_open(); xc_interface_open(); return 0; }
>   EOF
>     if compile_prog "" "$xen_libs" ; then
>       xen=yes
> -    libs_softmmu="$xen_libs $libs_softmmu"
>     else
>       if test "$xen" = "yes" ; then
>         feature_not_found "xen"
> @@ -2674,9 +2673,6 @@ if test "$bluez" = "yes" ; then
>     echo "CONFIG_BLUEZ=y">>  $config_host_mak
>     echo "BLUEZ_CFLAGS=$bluez_cflags">>  $config_host_mak
>   fi
> -if test "$xen" = "yes" ; then
> -  echo "CONFIG_XEN=y">>  $config_host_mak
> -fi
>   if test "$io_thread" = "yes" ; then
>     echo "CONFIG_IOTHREAD=y">>  $config_host_mak
>     echo "CONFIG_THREAD=y">>  $config_host_mak
> @@ -3012,6 +3008,7 @@ case "$target_arch2" in
>     i386|x86_64)
>       if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
>         echo "CONFIG_XEN=y">>  $config_target_mak
> +      echo "LIBS+=$xen_libs">>  $config_target_mak
>       fi
>   esac
>   case "$target_arch2" in
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-02-24 16:11   ` [Qemu-devel] " Anthony Liguori
@ 2011-02-24 16:25       ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-24 16:25 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, Xen Devel, QEMU-devel, Stefano Stabellini

On Thu, Feb 24, 2011 at 16:11, Anthony Liguori <anthony@codemonkey.ws> wrote:
> Is this really necessary?  The advantage to building globally is that it
> keeps the code from getting unnecessary i386-isms.

Nop, is not necessary, I add this patch after this mail:
http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
@ 2011-02-24 16:25       ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-24 16:25 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, Xen Devel, QEMU-devel, Stefano Stabellini

On Thu, Feb 24, 2011 at 16:11, Anthony Liguori <anthony@codemonkey.ws> wrote:
> Is this really necessary?  The advantage to building globally is that it
> keeps the code from getting unnecessary i386-isms.

Nop, is not necessary, I add this patch after this mail:
http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-02-24 16:25       ` Anthony PERARD
@ 2011-02-24 17:27         ` Anthony Liguori
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:27 UTC (permalink / raw)
  To: Anthony PERARD
  Cc: Jan Kiszka, Alexander Graf, Xen Devel, QEMU-devel, Stefano Stabellini

On 02/24/2011 10:25 AM, Anthony PERARD wrote:
> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>    
>> Is this really necessary?  The advantage to building globally is that it
>> keeps the code from getting unnecessary i386-isms.
>>      
> Nop, is not necessary, I add this patch after this mail:
> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>    

Alex, do you feel strongly here?

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
@ 2011-02-24 17:27         ` Anthony Liguori
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:27 UTC (permalink / raw)
  To: Anthony PERARD
  Cc: Jan Kiszka, Alexander Graf, Xen Devel, QEMU-devel, Stefano Stabellini

On 02/24/2011 10:25 AM, Anthony PERARD wrote:
> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>    
>> Is this really necessary?  The advantage to building globally is that it
>> keeps the code from getting unnecessary i386-isms.
>>      
> Nop, is not necessary, I add this patch after this mail:
> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>    

Alex, do you feel strongly here?

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
  2011-02-02 14:49   ` anthony.perard
  (?)
@ 2011-02-24 17:29   ` Anthony Liguori
  2011-02-25 14:06       ` Anthony PERARD
  -1 siblings, 1 reply; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:29 UTC (permalink / raw)
  To: anthony.perard; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
> From: Anthony PERARD<anthony.perard@citrix.com>
>
> This patch adds a generic layer for xc calls, allowing us to choose between the
> xenner and xen implementations at runtime.
>
> It also 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 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>
> Acked-by: Alexander Graf<agraf@suse.de>
> ---
>   Makefile.target      |    3 +
>   configure            |   62 +++++++++++++++-
>   hw/xen_backend.c     |   74 ++++++++++---------
>   hw/xen_backend.h     |    7 +-
>   hw/xen_common.h      |   38 ++++++----
>   hw/xen_console.c     |   10 +-
>   hw/xen_devconfig.c   |   10 +-
>   hw/xen_disk.c        |   28 ++++---
>   hw/xen_domainbuild.c |   29 ++++----
>   hw/xen_interfaces.c  |  191 ++++++++++++++++++++++++++++++++++++++++++++++++
>   hw/xen_interfaces.h  |  198 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   hw/xen_nic.c         |   36 +++++-----
>   hw/xenfb.c           |   14 ++--
>   13 files changed, 584 insertions(+), 116 deletions(-)
>   create mode 100644 hw/xen_interfaces.c
>   create mode 100644 hw/xen_interfaces.h
>
> 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..cf081e1 100644
> --- a/hw/xen_backend.c
> +++ b/hw/xen_backend.c
> @@ -43,7 +43,8 @@
>   /* ------------------------------------------------------------- */
>
>   /* public */
> -int xen_xc;
> +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
> +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
>   struct xs_handle *xenstore = NULL;
>   const char *xen_protocol;
>
> @@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char *node, const char *val)
>       char abspath[XEN_BUFSIZE];
>
>       snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
> -    if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
> +    if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val)))
>           return -1;
>       return 0;
>   }
> @@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char *node)
>       char *str, *ret = NULL;
>
>       snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
> -    str = xs_read(xenstore, 0, abspath,&len);
> +    str = xs_ops.read(xenstore, 0, abspath,&len);
>    

I think I gave this feedback before but I'd really like to see static 
inlines here.

It's very likely that you'll either want to have tracing or some 
commands can have a NULL function pointer in which case having a central 
location to do this is very useful.

Plus, it's more natural to read code that's making a function call 
instead of going through a function pointer in a structure redirection.

Can probably do this with just a sed over the current patch.

Regards,

Anthony Liguori

>       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;
>
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine
  2011-02-02 14:49   ` anthony.perard
  (?)
@ 2011-02-24 17:31   ` Anthony Liguori
  2011-02-25 13:55     ` Anthony PERARD
  -1 siblings, 1 reply; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:31 UTC (permalink / raw)
  To: anthony.perard; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
> From: Anthony PERARD<anthony.perard@citrix.com>
>
> Introduce the Xen FV (Fully Virtualized) machine to Qemu, some more Xen
> specific call will be added in further patches.
>
> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> ---
>   hw/pc.c      |   19 +++++++++++++++++--
>   hw/pc_piix.c |   21 ++++++++++++++++++++-
>   hw/xen.h     |    4 ++++
>   3 files changed, 41 insertions(+), 3 deletions(-)
>
> diff --git a/hw/pc.c b/hw/pc.c
> index 4dfdc0b..ab9d365 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -41,6 +41,7 @@
>   #include "sysemu.h"
>   #include "blockdev.h"
>   #include "ui/qemu-spice.h"
> +#include "xen.h"
>
>   /* output Bochs bios info messages */
>   //#define DEBUG_BIOS
> @@ -906,7 +907,11 @@ static void pc_cpu_reset(void *opaque)
>       CPUState *env = opaque;
>
>       cpu_reset(env);
> -    env->halted = !cpu_is_bsp(env);
> +    if (!xen_enabled()) {
> +        env->halted = !cpu_is_bsp(env);
> +    } else {
> +        env->halted = 1;
> +    }
>   }
>
>   static CPUState *pc_new_cpu(const char *cpu_model)
> @@ -940,7 +945,12 @@ void pc_cpus_init(const char *cpu_model)
>   #endif
>       }
>
> -    for(i = 0; i<  smp_cpus; i++) {
> +    if (!xen_enabled()) {
> +        for(i = 0; i<  smp_cpus; i++) {
> +            pc_new_cpu(cpu_model);
> +        }
> +    } else {
> +        /* Xen require only one Qemu VCPU */
>           pc_new_cpu(cpu_model);
>       }
>   }
> @@ -968,6 +978,11 @@ void pc_memory_init(ram_addr_t ram_size,
>       *above_4g_mem_size_p = above_4g_mem_size;
>       *below_4g_mem_size_p = below_4g_mem_size;
>
> +    if (xen_enabled()) {
> +        /* Nothing to do for Xen */
> +        return;
> +    }
> +
>   #if TARGET_PHYS_ADDR_BITS == 32
>       if (above_4g_mem_size>  0) {
>           hw_error("To much RAM for 32-bit physical address");
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index 7b74473..0ab8907 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -36,6 +36,10 @@
>   #include "sysbus.h"
>   #include "arch_init.h"
>   #include "blockdev.h"
> +#include "xen.h"
> +#ifdef CONFIG_XEN
> +#  include "xen/hvm/hvm_info_table.h"
> +#endif
>    

Admittedly a nit, but isn't this a system header?

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
  2011-02-02 14:49   ` anthony.perard
  (?)
@ 2011-02-24 17:33   ` Anthony Liguori
  2011-02-24 17:36     ` Paolo Bonzini
  -1 siblings, 1 reply; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:33 UTC (permalink / raw)
  To: anthony.perard; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini, Steven Smith

On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
> From: Steven Smith<ssmith@xensource.com>
>
> Introduce a new emulated PCI device, specific to fully virtualized Xen
> guests.  The device is necessary for PV on HVM drivers to work.
>
> Signed-off-by: Steven Smith<ssmith@xensource.com>
> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> ---
>   Makefile.target   |    1 +
>   hw/hw.h           |    3 +
>   hw/pc_piix.c      |    4 +
>   hw/pci_ids.h      |    2 +
>   hw/xen.h          |    2 +
>   hw/xen_platform.c |  348 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>   xen-stub.c        |    4 +
>   7 files changed, 364 insertions(+), 0 deletions(-)
>   create mode 100644 hw/xen_platform.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 00bb690..7a4fd72 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -215,6 +215,7 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o
>   obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
>   obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
>   obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
> +obj-i386-$(CONFIG_XEN) += xen_platform.o
>
>   # Inter-VM PCI shared memory
>   obj-$(CONFIG_KVM) += ivshmem.o
> diff --git a/hw/hw.h b/hw/hw.h
> index dd993de..298df31 100644
> --- a/hw/hw.h
> +++ b/hw/hw.h
> @@ -672,6 +672,9 @@ extern const VMStateDescription vmstate_i2c_slave;
>   #define VMSTATE_INT32_LE(_f, _s)                                   \
>       VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
>
> +#define VMSTATE_UINT8_TEST(_f, _s, _t)                               \
> +    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
> +
>   #define VMSTATE_UINT16_TEST(_f, _s, _t)                               \
>       VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
>
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index 0ab8907..765877c 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -120,6 +120,10 @@ static void pc_init1(ram_addr_t ram_size,
>
>       pc_vga_init(pci_enabled? pci_bus: NULL);
>
> +    if (xen_enabled()) {
> +        pci_xen_platform_init(pci_bus);
> +    }
> +
>       /* init basic PC hardware */
>       pc_basic_device_init(isa_irq,&floppy_controller,&rtc_state);
>
> diff --git a/hw/pci_ids.h b/hw/pci_ids.h
> index ea3418c..6e9eabc 100644
> --- a/hw/pci_ids.h
> +++ b/hw/pci_ids.h
> @@ -108,3 +108,5 @@
>   #define PCI_DEVICE_ID_INTEL_82371AB      0x7111
>   #define PCI_DEVICE_ID_INTEL_82371AB_2    0x7112
>   #define PCI_DEVICE_ID_INTEL_82371AB_3    0x7113
> +
> +#define PCI_VENDOR_ID_XENSOURCE          0x5853
> diff --git a/hw/xen.h b/hw/xen.h
> index 3984069..53a2ca4 100644
> --- a/hw/xen.h
> +++ b/hw/xen.h
> @@ -29,6 +29,8 @@ static inline int xen_enabled(void)
>   #endif
>   }
>
> +void pci_xen_platform_init(PCIBus *bus);
> +
>   int xen_init(int smp_cpus);
>
>   #if defined(CONFIG_XEN)&&  CONFIG_XEN_CTRL_INTERFACE_VERSION<  400
> diff --git a/hw/xen_platform.c b/hw/xen_platform.c
> new file mode 100644
> index 0000000..383cfcf
> --- /dev/null
> +++ b/hw/xen_platform.c
> @@ -0,0 +1,348 @@
> +/*
> + * XEN platform pci device, formerly known as the event channel device
> + *
> + * Copyright (c) 2003-2004 Intel Corp.
> + * Copyright (c) 2006 XenSource
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "hw.h"
> +#include "pc.h"
> +#include "pci.h"
> +#include "irq.h"
> +#include "xen_common.h"
> +#include "net.h"
> +#include "xen_backend.h"
> +#include "qemu-log.h"
> +#include "rwhandler.h"
> +
> +#include<assert.h>
> +#include<xenguest.h>
> +
> +//#define DEBUG_PLATFORM
> +
> +#ifdef DEBUG_PLATFORM
> +#define DPRINTF(fmt, ...) do { \
> +    fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \
> +} while (0)
> +#else
> +#define DPRINTF(fmt, ...) do { } while (0)
> +#endif
> +
> +#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
> +
> +typedef struct PCIXenPlatformState {
> +    PCIDevice  pci_dev;
> +    uint8_t flags; /* used only for version_id == 2 */
> +    int drivers_blacklisted;
> +    uint16_t driver_product_version;
> +
> +    /* Log from guest drivers */
> +    char log_buffer[4096];
> +    int log_buffer_off;
> +} PCIXenPlatformState;
> +
> +#define XEN_PLATFORM_IOPORT 0x10
> +
> +/* Send bytes to syslog */
> +static void log_writeb(PCIXenPlatformState *s, char val)
> +{
> +    if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) {
> +        /* Flush buffer */
> +        s->log_buffer[s->log_buffer_off] = 0;
> +        DPRINTF("%s\n", s->log_buffer);
>    

This should go to a chardev.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 07/15] piix_pci: Introduces Xen specific call for irq.
  2011-02-02 14:49   ` anthony.perard
  (?)
@ 2011-02-24 17:34   ` Anthony Liguori
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:34 UTC (permalink / raw)
  To: anthony.perard; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
> From: Anthony PERARD<anthony.perard@citrix.com>
>
> This patch introduces Xen specific call in piix_pci.
>
> The specific part for Xen is in write_config, set_irq and get_pirq.
>
> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> Acked-by: Alexander Graf<agraf@suse.de>
> ---
>   hw/piix_pci.c |   28 ++++++++++++++++++++++++++--
>   hw/xen.h      |    6 ++++++
>   xen-all.c     |   31 +++++++++++++++++++++++++++++++
>   xen-stub.c    |   13 +++++++++++++
>   4 files changed, 76 insertions(+), 2 deletions(-)
>
> diff --git a/hw/piix_pci.c b/hw/piix_pci.c
> index 358da58..152fcc0 100644
> --- a/hw/piix_pci.c
> +++ b/hw/piix_pci.c
> @@ -29,6 +29,7 @@
>   #include "isa.h"
>   #include "sysbus.h"
>   #include "range.h"
> +#include "xen.h"
>
>   /*
>    * I440FX chipset data sheet.
> @@ -151,6 +152,13 @@ static void i440fx_write_config(PCIDevice *dev,
>       }
>   }
>
> +static void i440fx_write_config_xen(PCIDevice *dev,
> +                                    uint32_t address, uint32_t val, int len)
> +{
> +    xen_piix_pci_write_config_client(address, val, len);
> +    i440fx_write_config(dev, address, val, len);
> +}
> +
>   static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
>   {
>       PCII440FXState *d = opaque;
> @@ -230,13 +238,21 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
>       s->bus = b;
>       qdev_init_nofail(dev);
>
> -    d = pci_create_simple(b, 0, "i440FX");
> +    if (xen_enabled()) {
> +        d = pci_create_simple(b, 0, "i440FX-xen");
> +    } else {
> +        d = pci_create_simple(b, 0, "i440FX");
>    

We don't really want to have a device that magically becomes another 
device if Xen is enabled.

You should introduce an i440fx_xen_init() and make enough of the code 
common here to simply it.  We don't want to have if (xen_enabled())'s 
sprinkled through the device model.

Regards,

Anthony Liguori

> +    }
>       *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
>
>       piix3 = DO_UPCAST(PIIX3State, dev,
>                         pci_create_simple_multifunction(b, -1, true, "PIIX3"));
>       piix3->pic = pic;
> -    pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
> +    if (xen_enabled()) {
> +        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, 4);
> +    } else {
> +        pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
> +    }
>       (*pi440fx_state)->piix3 = piix3;
>
>       *piix3_devfn = piix3->dev.devfn;
> @@ -352,6 +368,14 @@ static PCIDeviceInfo i440fx_info[] = {
>           .init         = i440fx_initfn,
>           .config_write = i440fx_write_config,
>       },{
> +        .qdev.name    = "i440FX-xen",
> +        .qdev.desc    = "Host bridge",
> +        .qdev.size    = sizeof(PCII440FXState),
> +        .qdev.vmsd    =&vmstate_i440fx,
> +        .qdev.no_user = 1,
> +        .init         = i440fx_initfn,
> +        .config_write = i440fx_write_config_xen,
> +    },{
>           .qdev.name    = "PIIX3",
>           .qdev.desc    = "ISA bridge",
>           .qdev.size    = sizeof(PIIX3State),
> diff --git a/hw/xen.h b/hw/xen.h
> index 53a2ca4..2a53f8b 100644
> --- a/hw/xen.h
> +++ b/hw/xen.h
> @@ -8,6 +8,8 @@
>    */
>   #include<inttypes.h>
>
> +#include "qemu-common.h"
> +
>   /* xen-machine.c */
>   enum xen_mode {
>       XEN_EMULATE = 0,  // xen emulation, using xenner (default)
> @@ -29,6 +31,10 @@ static inline int xen_enabled(void)
>   #endif
>   }
>
> +int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
> +void xen_piix3_set_irq(void *opaque, int irq_num, int level);
> +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
> +
>   void pci_xen_platform_init(PCIBus *bus);
>
>   int xen_init(int smp_cpus);
> diff --git a/xen-all.c b/xen-all.c
> index 8d77d42..123decb 100644
> --- a/xen-all.c
> +++ b/xen-all.c
> @@ -8,9 +8,40 @@
>
>   #include "config.h"
>
> +#include "hw/pci.h"
>   #include "hw/xen_common.h"
>   #include "hw/xen_backend.h"
>
> +/* Xen specific function for piix pci */
> +
> +int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
> +{
> +    return irq_num + ((pci_dev->devfn>>  3)<<  2);
> +}
> +
> +void xen_piix3_set_irq(void *opaque, int irq_num, int level)
> +{
> +    xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num>>  2,
> +                              irq_num&  3, level);
> +}
> +
> +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
> +{
> +    int i;
> +
> +    /* Scan for updates to PCI link routes (0x60-0x63). */
> +    for (i = 0; i<  len; i++) {
> +        uint8_t v = (val>>  (8 * i))&  0xff;
> +        if (v&  0x80) {
> +            v = 0;
> +        }
> +        v&= 0xf;
> +        if (((address + i)>= 0x60)&&  ((address + i)<= 0x63)) {
> +            xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
> +        }
> +    }
> +}
> +
>   /* Initialise Xen */
>
>   int xen_init(int smp_cpus)
> diff --git a/xen-stub.c b/xen-stub.c
> index a6d5850..ba95537 100644
> --- a/xen-stub.c
> +++ b/xen-stub.c
> @@ -11,6 +11,19 @@
>   #include "qemu-common.h"
>   #include "hw/xen.h"
>
> +int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
> +{
> +    return -1;
> +}
> +
> +void xen_piix3_set_irq(void *opaque, int irq_num, int level)
> +{
> +}
> +
> +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
> +{
> +}
> +
>   void pci_xen_platform_init(PCIBus *bus)
>   {
>   }
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
  2011-02-24 17:33   ` [Qemu-devel] " Anthony Liguori
@ 2011-02-24 17:36     ` Paolo Bonzini
  2011-02-25  9:58         ` Ian Campbell
  0 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2011-02-24 17:36 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: anthony.perard, Xen Devel, QEMU-devel, Steven Smith, Stefano Stabellini

On 02/24/2011 06:33 PM, Anthony Liguori wrote:
> On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
>> From: Steven Smith<ssmith@xensource.com>
>>
>> Introduce a new emulated PCI device, specific to fully virtualized Xen
>> guests. The device is necessary for PV on HVM drivers to work.
>>
>> Signed-off-by: Steven Smith<ssmith@xensource.com>
>> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
>> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
>> ---
>> Makefile.target | 1 +
>> hw/hw.h | 3 +
>> hw/pc_piix.c | 4 +
>> hw/pci_ids.h | 2 +
>> hw/xen.h | 2 +
>> hw/xen_platform.c | 348
>> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> xen-stub.c | 4 +
>> 7 files changed, 364 insertions(+), 0 deletions(-)
>> create mode 100644 hw/xen_platform.c
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index 00bb690..7a4fd72 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -215,6 +215,7 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o
>> obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
>> obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
>> obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>> +obj-i386-$(CONFIG_XEN) += xen_platform.o
>>
>> # Inter-VM PCI shared memory
>> obj-$(CONFIG_KVM) += ivshmem.o
>> diff --git a/hw/hw.h b/hw/hw.h
>> index dd993de..298df31 100644
>> --- a/hw/hw.h
>> +++ b/hw/hw.h
>> @@ -672,6 +672,9 @@ extern const VMStateDescription vmstate_i2c_slave;
>> #define VMSTATE_INT32_LE(_f, _s) \
>> VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
>>
>> +#define VMSTATE_UINT8_TEST(_f, _s, _t) \
>> + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
>> +
>> #define VMSTATE_UINT16_TEST(_f, _s, _t) \
>> VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
>>
>> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
>> index 0ab8907..765877c 100644
>> --- a/hw/pc_piix.c
>> +++ b/hw/pc_piix.c
>> @@ -120,6 +120,10 @@ static void pc_init1(ram_addr_t ram_size,
>>
>> pc_vga_init(pci_enabled? pci_bus: NULL);
>>
>> + if (xen_enabled()) {
>> + pci_xen_platform_init(pci_bus);
>> + }
>> +
>> /* init basic PC hardware */
>> pc_basic_device_init(isa_irq,&floppy_controller,&rtc_state);
>>
>> diff --git a/hw/pci_ids.h b/hw/pci_ids.h
>> index ea3418c..6e9eabc 100644
>> --- a/hw/pci_ids.h
>> +++ b/hw/pci_ids.h
>> @@ -108,3 +108,5 @@
>> #define PCI_DEVICE_ID_INTEL_82371AB 0x7111
>> #define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
>> #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
>> +
>> +#define PCI_VENDOR_ID_XENSOURCE 0x5853
>> diff --git a/hw/xen.h b/hw/xen.h
>> index 3984069..53a2ca4 100644
>> --- a/hw/xen.h
>> +++ b/hw/xen.h
>> @@ -29,6 +29,8 @@ static inline int xen_enabled(void)
>> #endif
>> }
>>
>> +void pci_xen_platform_init(PCIBus *bus);
>> +
>> int xen_init(int smp_cpus);
>>
>> #if defined(CONFIG_XEN)&& CONFIG_XEN_CTRL_INTERFACE_VERSION< 400
>> diff --git a/hw/xen_platform.c b/hw/xen_platform.c
>> new file mode 100644
>> index 0000000..383cfcf
>> --- /dev/null
>> +++ b/hw/xen_platform.c
>> @@ -0,0 +1,348 @@
>> +/*
>> + * XEN platform pci device, formerly known as the event channel device
>> + *
>> + * Copyright (c) 2003-2004 Intel Corp.
>> + * Copyright (c) 2006 XenSource
>> + *
>> + * Permission is hereby granted, free of charge, to any person
>> obtaining a copy
>> + * of this software and associated documentation files (the
>> "Software"), to deal
>> + * in the Software without restriction, including without limitation
>> the rights
>> + * to use, copy, modify, merge, publish, distribute, sublicense,
>> and/or sell
>> + * copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be
>> included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
>> SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
>> OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>> ARISING FROM,
>> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>> DEALINGS IN
>> + * THE SOFTWARE.
>> + */
>> +
>> +#include "hw.h"
>> +#include "pc.h"
>> +#include "pci.h"
>> +#include "irq.h"
>> +#include "xen_common.h"
>> +#include "net.h"
>> +#include "xen_backend.h"
>> +#include "qemu-log.h"
>> +#include "rwhandler.h"
>> +
>> +#include<assert.h>
>> +#include<xenguest.h>
>> +
>> +//#define DEBUG_PLATFORM
>> +
>> +#ifdef DEBUG_PLATFORM
>> +#define DPRINTF(fmt, ...) do { \
>> + fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \
>> +} while (0)
>> +#else
>> +#define DPRINTF(fmt, ...) do { } while (0)
>> +#endif
>> +
>> +#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
>> +
>> +typedef struct PCIXenPlatformState {
>> + PCIDevice pci_dev;
>> + uint8_t flags; /* used only for version_id == 2 */
>> + int drivers_blacklisted;
>> + uint16_t driver_product_version;
>> +
>> + /* Log from guest drivers */
>> + char log_buffer[4096];
>> + int log_buffer_off;
>> +} PCIXenPlatformState;
>> +
>> +#define XEN_PLATFORM_IOPORT 0x10
>> +
>> +/* Send bytes to syslog */
>> +static void log_writeb(PCIXenPlatformState *s, char val)
>> +{
>> + if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) {
>> + /* Flush buffer */
>> + s->log_buffer[s->log_buffer_off] = 0;
>> + DPRINTF("%s\n", s->log_buffer);
>
> This should go to a chardev.

Or it should just go away.  Guests can already write to 0xe9 and see the 
output on the host's "xm dmesg" ring and serial console.

Paolo

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 00/15] Xen device model support
  2011-02-02 14:49 ` anthony.perard
                   ` (15 preceding siblings ...)
  (?)
@ 2011-02-24 17:38 ` Anthony Liguori
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:38 UTC (permalink / raw)
  To: anthony.perard; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
> From: Anthony PERARD<anthony.perard@citrix.com>
>
> Hi,
>
> There is a lot of change since the V9 of the Xen device model. One of theme is
> to use the 'pc' machine for Xen instead of duplicate this machine in another
> file.
>
> Here is the change since the last version:
>    - typedef of qemu_xc_interface, qemu_xc_gnttab and qemu_xc_evtchn have been
>      renamed to XenXC, XenGnttab and XenEvtchn;
>    - replace asprintf by snprintf;
>    - rename "Xen i8259" to Xen Interrupt Controller;
>    - remove xen_redirect.h file and replace all Xen calls to use xen_interfaces
>      calls;
>    - add copyright header in some files;
>    - in mapcache, use RLIMIT_AS to have the max mapcache size, instead of have a
>      max depends on the architecture;
>    - in mapcache, set rlimit_as.rlim_cur = rlimit_as.rlim_max;
>    - in xen platform pci device, removed the throttle;
>    - qemu_ram_ptr_unlock renamed to qemu_put_ram_ptr;
>    - put specific xen calls into pc_piix and xen_machine_fv have been removed;
>    - fix few coding style.
>
>
> This series depends on the series "Introduce "machine" QemuOpts".
>    

Looks pretty good minus the few comments I made!

Regards,

Anthony Liguori

>
> You can find a git tree here:
>
> git://xenbits.xen.org/people/aperard/qemu-dm.git qemu-dm-v10
>
>
> Anthony PERARD (12):
>    xen: Replace some tab-indents with spaces (clean-up).
>    xen: Make xen build only on x86 target.
>    xen: Support new libxc calls from xen unstable.
>    xen: Add initialisation of Xen
>    xen: Add xenfv machine
>    piix_pci: Introduces Xen specific call for irq.
>    xen: Introduce Xen Interrupt Controller
>    configure: Always use 64bits target physical addresses with xen
>      enabled.
>    Introduce qemu_put_ram_ptr
>    vl.c: Introduce getter for shutdown_requested and reset_requested.
>    xen: Set running state in xenstore.
>    xen: Add Xen hypercall for sleep state in the cmos_s3 callback.
>
> Arun Sharma (1):
>    xen: Initialize event channels and io rings
>
> Jun Nakajima (1):
>    xen: Introduce the Xen mapcache
>
> Steven Smith (1):
>    xen: Add the Xen platform pci device
>
>   Makefile.objs        |    4 -
>   Makefile.target      |   14 ++-
>   configure            |   71 ++++++-
>   cpu-common.h         |    1 +
>   exec.c               |   50 ++++-
>   hw/hw.h              |    3 +
>   hw/pc.c              |   19 ++-
>   hw/pc_piix.c         |   39 +++-
>   hw/pci_ids.h         |    2 +
>   hw/piix_pci.c        |   28 +++-
>   hw/xen.h             |   41 ++++
>   hw/xen_backend.c     |  372 ++++++++++++++++----------------
>   hw/xen_backend.h     |    7 +-
>   hw/xen_common.h      |   40 +++--
>   hw/xen_console.c     |   10 +-
>   hw/xen_devconfig.c   |   10 +-
>   hw/xen_disk.c        |  402 ++++++++++++++++++-----------------
>   hw/xen_domainbuild.c |   29 ++--
>   hw/xen_interfaces.c  |  191 +++++++++++++++++
>   hw/xen_interfaces.h  |  198 +++++++++++++++++
>   hw/xen_nic.c         |  230 ++++++++++----------
>   hw/xen_platform.c    |  348 ++++++++++++++++++++++++++++++
>   hw/xenfb.c           |   14 +-
>   sysemu.h             |    2 +
>   vl.c                 |   12 +
>   xen-all.c            |  579 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   xen-mapcache-stub.c  |   40 ++++
>   xen-mapcache.c       |  344 ++++++++++++++++++++++++++++++
>   xen-mapcache.h       |   22 ++
>   xen-stub.c           |   47 ++++
>   30 files changed, 2599 insertions(+), 570 deletions(-)
>   create mode 100644 hw/xen_interfaces.c
>   create mode 100644 hw/xen_interfaces.h
>   create mode 100644 hw/xen_platform.c
>   create mode 100644 xen-all.c
>   create mode 100644 xen-mapcache-stub.c
>   create mode 100644 xen-mapcache.c
>   create mode 100644 xen-mapcache.h
>   create mode 100644 xen-stub.c
>
>
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-02-24 17:27         ` Anthony Liguori
@ 2011-02-24 17:46           ` Jan Kiszka
  -1 siblings, 0 replies; 68+ messages in thread
From: Jan Kiszka @ 2011-02-24 17:46 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony PERARD, Alexander Graf, Xen Devel, QEMU-devel,
	Stefano Stabellini

On 2011-02-24 18:27, Anthony Liguori wrote:
> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>>    
>>> Is this really necessary?  The advantage to building globally is that it
>>> keeps the code from getting unnecessary i386-isms.
>>>      
>> Nop, is not necessary, I add this patch after this mail:
>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>>    
> 
> Alex, do you feel strongly here?

I'm not Alex, but I brought this issue up:

Either build xen bits once for all archs or restrict it to the only
foreseeable arch with support in qemu. But please don't built it for
each and every target separately.

BTW:

> index b0ba95f..db29e96 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
>  QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>  
>  # xen backend driver support
> -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
> +obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
> +obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
> +obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o

Why restricting the last line to i386? Doesn't CONFIG_XEN also control
here if the arch is xen-capable?

Thanks,
Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
@ 2011-02-24 17:46           ` Jan Kiszka
  0 siblings, 0 replies; 68+ messages in thread
From: Jan Kiszka @ 2011-02-24 17:46 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony PERARD, Alexander Graf, Xen Devel, QEMU-devel,
	Stefano Stabellini

On 2011-02-24 18:27, Anthony Liguori wrote:
> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>>    
>>> Is this really necessary?  The advantage to building globally is that it
>>> keeps the code from getting unnecessary i386-isms.
>>>      
>> Nop, is not necessary, I add this patch after this mail:
>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>>    
> 
> Alex, do you feel strongly here?

I'm not Alex, but I brought this issue up:

Either build xen bits once for all archs or restrict it to the only
foreseeable arch with support in qemu. But please don't built it for
each and every target separately.

BTW:

> index b0ba95f..db29e96 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
>  QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>  
>  # xen backend driver support
> -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
> +obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
> +obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
> +obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o

Why restricting the last line to i386? Doesn't CONFIG_XEN also control
here if the arch is xen-capable?

Thanks,
Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-02-24 17:46           ` Jan Kiszka
@ 2011-02-24 17:59             ` Anthony Liguori
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:59 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Anthony PERARD, Xen Devel, Alexander Graf, Stefano Stabellini,
	QEMU-devel

On 02/24/2011 11:46 AM, Jan Kiszka wrote:
> On 2011-02-24 18:27, Anthony Liguori wrote:
>    
>> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
>>      
>>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>   wrote:
>>>
>>>        
>>>> Is this really necessary?  The advantage to building globally is that it
>>>> keeps the code from getting unnecessary i386-isms.
>>>>
>>>>          
>>> Nop, is not necessary, I add this patch after this mail:
>>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>>>
>>>        
>> Alex, do you feel strongly here?
>>      
> I'm not Alex, but I brought this issue up:
>
> Either build xen bits once for all archs or restrict it to the only
> foreseeable arch with support in qemu. But please don't built it for
> each and every target separately.
>    

Oh yes, I misunderstood.  I thought we had previously built it for all 
architectures.  Yes, we should only build it once.

Regards,

Anthony Liguori

> BTW:
>
>    
>> index b0ba95f..db29e96 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
>>   QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>>
>>   # xen backend driver support
>> -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>> +obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
>> +obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
>> +obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>>      
> Why restricting the last line to i386? Doesn't CONFIG_XEN also control
> here if the arch is xen-capable?
>
> Thanks,
> Jan
>
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
@ 2011-02-24 17:59             ` Anthony Liguori
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-24 17:59 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Anthony PERARD, Xen Devel, Alexander Graf, Stefano Stabellini,
	QEMU-devel

On 02/24/2011 11:46 AM, Jan Kiszka wrote:
> On 2011-02-24 18:27, Anthony Liguori wrote:
>    
>> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
>>      
>>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>   wrote:
>>>
>>>        
>>>> Is this really necessary?  The advantage to building globally is that it
>>>> keeps the code from getting unnecessary i386-isms.
>>>>
>>>>          
>>> Nop, is not necessary, I add this patch after this mail:
>>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>>>
>>>        
>> Alex, do you feel strongly here?
>>      
> I'm not Alex, but I brought this issue up:
>
> Either build xen bits once for all archs or restrict it to the only
> foreseeable arch with support in qemu. But please don't built it for
> each and every target separately.
>    

Oh yes, I misunderstood.  I thought we had previously built it for all 
architectures.  Yes, we should only build it once.

Regards,

Anthony Liguori

> BTW:
>
>    
>> index b0ba95f..db29e96 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -206,7 +206,9 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
>>   QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>>
>>   # xen backend driver support
>> -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>> +obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
>> +obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
>> +obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>>      
> Why restricting the last line to i386? Doesn't CONFIG_XEN also control
> here if the arch is xen-capable?
>
> Thanks,
> Jan
>
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
  2011-02-24 17:36     ` Paolo Bonzini
@ 2011-02-25  9:58         ` Ian Campbell
  0 siblings, 0 replies; 68+ messages in thread
From: Ian Campbell @ 2011-02-25  9:58 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Xen Devel, Stefano Stabellini, QEMU-devel, Steven Smith, Anthony Perard

On Thu, 2011-02-24 at 17:36 +0000, Paolo Bonzini wrote:
> >> +/* Send bytes to syslog */
> >> +static void log_writeb(PCIXenPlatformState *s, char val)
> >> +{
> >> + if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) -
> 1) {
> >> + /* Flush buffer */
> >> + s->log_buffer[s->log_buffer_off] = 0;
> >> + DPRINTF("%s\n", s->log_buffer);
> >
> > This should go to a chardev.
> 
> Or it should just go away.  Guests can already write to 0xe9 and see
> the output on the host's "xm dmesg" ring and serial console. 

Only true if you have configured the guest log level to include debug
messages.

In any case host dmesg is not really the same as going to a file in dom0
from a supportability PoV.

Ian.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
@ 2011-02-25  9:58         ` Ian Campbell
  0 siblings, 0 replies; 68+ messages in thread
From: Ian Campbell @ 2011-02-25  9:58 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Xen Devel, Stefano Stabellini, QEMU-devel, Steven Smith,
	Anthony Liguori, Anthony Perard

On Thu, 2011-02-24 at 17:36 +0000, Paolo Bonzini wrote:
> >> +/* Send bytes to syslog */
> >> +static void log_writeb(PCIXenPlatformState *s, char val)
> >> +{
> >> + if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) -
> 1) {
> >> + /* Flush buffer */
> >> + s->log_buffer[s->log_buffer_off] = 0;
> >> + DPRINTF("%s\n", s->log_buffer);
> >
> > This should go to a chardev.
> 
> Or it should just go away.  Guests can already write to 0xe9 and see
> the output on the host's "xm dmesg" ring and serial console. 

Only true if you have configured the guest log level to include debug
messages.

In any case host dmesg is not really the same as going to a file in dom0
from a supportability PoV.

Ian.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
  2011-02-25  9:58         ` Ian Campbell
@ 2011-02-25 10:54           ` Paolo Bonzini
  -1 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2011-02-25 10:54 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Xen Devel, Stefano Stabellini, QEMU-devel, Anthony Perard, Steven Smith

On 02/25/2011 10:58 AM, Ian Campbell wrote:
> >  Or it should just go away.  Guests can already write to 0xe9 and see
> >  the output on the host's "xm dmesg" ring and serial console.
>
> Only true if you have configured the guest log level to include debug
> messages.

If you can recompile QEMU to add DEBUG_PLATFORM, you can usually do that 
too.  To avoid recompilation, rather than a chardev it would be even 
better to keep it as a trace event.

Paolo

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
@ 2011-02-25 10:54           ` Paolo Bonzini
  0 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2011-02-25 10:54 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Xen Devel, Stefano Stabellini, QEMU-devel, Anthony Perard,
	Anthony Liguori, Steven Smith

On 02/25/2011 10:58 AM, Ian Campbell wrote:
> >  Or it should just go away.  Guests can already write to 0xe9 and see
> >  the output on the host's "xm dmesg" ring and serial console.
>
> Only true if you have configured the guest log level to include debug
> messages.

If you can recompile QEMU to add DEBUG_PLATFORM, you can usually do that 
too.  To avoid recompilation, rather than a chardev it would be even 
better to keep it as a trace event.

Paolo

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine
  2011-02-24 17:31   ` [Qemu-devel] " Anthony Liguori
@ 2011-02-25 13:55     ` Anthony PERARD
  2011-02-25 14:09       ` Anthony Liguori
  0 siblings, 1 reply; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 13:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On Thu, Feb 24, 2011 at 17:31, Anthony Liguori <anthony@codemonkey.ws> wrote:
>> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
>> index 7b74473..0ab8907 100644
>> --- a/hw/pc_piix.c
>> +++ b/hw/pc_piix.c
>> @@ -36,6 +36,10 @@
>>  #include "sysbus.h"
>>  #include "arch_init.h"
>>  #include "blockdev.h"
>> +#include "xen.h"
>> +#ifdef CONFIG_XEN
>> +#  include "xen/hvm/hvm_info_table.h"
>> +#endif
>>
>
> Admittedly a nit, but isn't this a system header?

It belongs to Xen. I use it for HVM_MAX_VCPUS.

I can put it in xen.h, if you prefer.

Regards,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
  2011-02-24 17:29   ` [Qemu-devel] " Anthony Liguori
@ 2011-02-25 14:06       ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 14:06 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On Thu, Feb 24, 2011 at 17:29, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
>>
>> From: Anthony PERARD<anthony.perard@citrix.com>
>>
>> This patch adds a generic layer for xc calls, allowing us to choose
>> between the
>> xenner and xen implementations at runtime.
>>
>> It also 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 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>
>> Acked-by: Alexander Graf<agraf@suse.de>
>> ---
>>  Makefile.target      |    3 +
>>  configure            |   62 +++++++++++++++-
>>  hw/xen_backend.c     |   74 ++++++++++---------
>>  hw/xen_backend.h     |    7 +-
>>  hw/xen_common.h      |   38 ++++++----
>>  hw/xen_console.c     |   10 +-
>>  hw/xen_devconfig.c   |   10 +-
>>  hw/xen_disk.c        |   28 ++++---
>>  hw/xen_domainbuild.c |   29 ++++----
>>  hw/xen_interfaces.c  |  191
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>  hw/xen_interfaces.h  |  198
>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  hw/xen_nic.c         |   36 +++++-----
>>  hw/xenfb.c           |   14 ++--
>>  13 files changed, 584 insertions(+), 116 deletions(-)
>>  create mode 100644 hw/xen_interfaces.c
>>  create mode 100644 hw/xen_interfaces.h
>>
>> 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..cf081e1 100644
>> --- a/hw/xen_backend.c
>> +++ b/hw/xen_backend.c
>> @@ -43,7 +43,8 @@
>>  /* ------------------------------------------------------------- */
>>
>>  /* public */
>> -int xen_xc;
>> +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
>> +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
>>  struct xs_handle *xenstore = NULL;
>>  const char *xen_protocol;
>>
>> @@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char
>> *node, const char *val)
>>      char abspath[XEN_BUFSIZE];
>>
>>      snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>> -    if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
>> +    if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val)))
>>          return -1;
>>      return 0;
>>  }
>> @@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char
>> *node)
>>      char *str, *ret = NULL;
>>
>>      snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>> -    str = xs_read(xenstore, 0, abspath,&len);
>> +    str = xs_ops.read(xenstore, 0, abspath,&len);
>>
>
> I think I gave this feedback before but I'd really like to see static
> inlines here.
>
> It's very likely that you'll either want to have tracing or some commands
> can have a NULL function pointer in which case having a central location to
> do this is very useful.
>
> Plus, it's more natural to read code that's making a function call instead
> of going through a function pointer in a structure redirection.
>
> Can probably do this with just a sed over the current patch.


Is it good to have a .h with functions like that? :

static inline XenXC qemu_xc_interface_open(xentoollog_logger *logger,
                            xentoollog_logger *dombuild_logger,
                            unsigned open_flags)
{
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
    return xc_interface_open();
#else
    return xc_interface_open(logger, dombuild_logger, open_flags);
#endif
}


So there will have no more structure redirection.

Regards,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
@ 2011-02-25 14:06       ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 14:06 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On Thu, Feb 24, 2011 at 17:29, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
>>
>> From: Anthony PERARD<anthony.perard@citrix.com>
>>
>> This patch adds a generic layer for xc calls, allowing us to choose
>> between the
>> xenner and xen implementations at runtime.
>>
>> It also 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 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>
>> Acked-by: Alexander Graf<agraf@suse.de>
>> ---
>>  Makefile.target      |    3 +
>>  configure            |   62 +++++++++++++++-
>>  hw/xen_backend.c     |   74 ++++++++++---------
>>  hw/xen_backend.h     |    7 +-
>>  hw/xen_common.h      |   38 ++++++----
>>  hw/xen_console.c     |   10 +-
>>  hw/xen_devconfig.c   |   10 +-
>>  hw/xen_disk.c        |   28 ++++---
>>  hw/xen_domainbuild.c |   29 ++++----
>>  hw/xen_interfaces.c  |  191
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>  hw/xen_interfaces.h  |  198
>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  hw/xen_nic.c         |   36 +++++-----
>>  hw/xenfb.c           |   14 ++--
>>  13 files changed, 584 insertions(+), 116 deletions(-)
>>  create mode 100644 hw/xen_interfaces.c
>>  create mode 100644 hw/xen_interfaces.h
>>
>> 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..cf081e1 100644
>> --- a/hw/xen_backend.c
>> +++ b/hw/xen_backend.c
>> @@ -43,7 +43,8 @@
>>  /* ------------------------------------------------------------- */
>>
>>  /* public */
>> -int xen_xc;
>> +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
>> +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
>>  struct xs_handle *xenstore = NULL;
>>  const char *xen_protocol;
>>
>> @@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char
>> *node, const char *val)
>>      char abspath[XEN_BUFSIZE];
>>
>>      snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>> -    if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
>> +    if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val)))
>>          return -1;
>>      return 0;
>>  }
>> @@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char
>> *node)
>>      char *str, *ret = NULL;
>>
>>      snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>> -    str = xs_read(xenstore, 0, abspath,&len);
>> +    str = xs_ops.read(xenstore, 0, abspath,&len);
>>
>
> I think I gave this feedback before but I'd really like to see static
> inlines here.
>
> It's very likely that you'll either want to have tracing or some commands
> can have a NULL function pointer in which case having a central location to
> do this is very useful.
>
> Plus, it's more natural to read code that's making a function call instead
> of going through a function pointer in a structure redirection.
>
> Can probably do this with just a sed over the current patch.


Is it good to have a .h with functions like that? :

static inline XenXC qemu_xc_interface_open(xentoollog_logger *logger,
                            xentoollog_logger *dombuild_logger,
                            unsigned open_flags)
{
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
    return xc_interface_open();
#else
    return xc_interface_open(logger, dombuild_logger, open_flags);
#endif
}


So there will have no more structure redirection.

Regards,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine
  2011-02-25 13:55     ` Anthony PERARD
@ 2011-02-25 14:09       ` Anthony Liguori
  2011-02-25 14:28           ` Anthony PERARD
  0 siblings, 1 reply; 68+ messages in thread
From: Anthony Liguori @ 2011-02-25 14:09 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/25/2011 07:55 AM, Anthony PERARD wrote:
> On Thu, Feb 24, 2011 at 17:31, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>    
>>> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
>>> index 7b74473..0ab8907 100644
>>> --- a/hw/pc_piix.c
>>> +++ b/hw/pc_piix.c
>>> @@ -36,6 +36,10 @@
>>>   #include "sysbus.h"
>>>   #include "arch_init.h"
>>>   #include "blockdev.h"
>>> +#include "xen.h"
>>> +#ifdef CONFIG_XEN
>>> +#  include "xen/hvm/hvm_info_table.h"
>>> +#endif
>>>
>>>        
>> Admittedly a nit, but isn't this a system header?
>>      
> It belongs to Xen. I use it for HVM_MAX_VCPUS.
>
> I can put it in xen.h, if you prefer.
>    

I meant, you should use:

#include <xen/hvm/hvm_info_table.h>

Regards,

Anthony Liguori

> Regards,
>
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
  2011-02-25 14:06       ` Anthony PERARD
@ 2011-02-25 14:11         ` Anthony Liguori
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-25 14:11 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/25/2011 08:06 AM, Anthony PERARD wrote:
> On Thu, Feb 24, 2011 at 17:29, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>    
>> On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
>>      
>>> From: Anthony PERARD<anthony.perard@citrix.com>
>>>
>>> This patch adds a generic layer for xc calls, allowing us to choose
>>> between the
>>> xenner and xen implementations at runtime.
>>>
>>> It also 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 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>
>>> Acked-by: Alexander Graf<agraf@suse.de>
>>> ---
>>>   Makefile.target      |    3 +
>>>   configure            |   62 +++++++++++++++-
>>>   hw/xen_backend.c     |   74 ++++++++++---------
>>>   hw/xen_backend.h     |    7 +-
>>>   hw/xen_common.h      |   38 ++++++----
>>>   hw/xen_console.c     |   10 +-
>>>   hw/xen_devconfig.c   |   10 +-
>>>   hw/xen_disk.c        |   28 ++++---
>>>   hw/xen_domainbuild.c |   29 ++++----
>>>   hw/xen_interfaces.c  |  191
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>>   hw/xen_interfaces.h  |  198
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>>   hw/xen_nic.c         |   36 +++++-----
>>>   hw/xenfb.c           |   14 ++--
>>>   13 files changed, 584 insertions(+), 116 deletions(-)
>>>   create mode 100644 hw/xen_interfaces.c
>>>   create mode 100644 hw/xen_interfaces.h
>>>
>>> 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..cf081e1 100644
>>> --- a/hw/xen_backend.c
>>> +++ b/hw/xen_backend.c
>>> @@ -43,7 +43,8 @@
>>>   /* ------------------------------------------------------------- */
>>>
>>>   /* public */
>>> -int xen_xc;
>>> +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
>>> +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
>>>   struct xs_handle *xenstore = NULL;
>>>   const char *xen_protocol;
>>>
>>> @@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char
>>> *node, const char *val)
>>>       char abspath[XEN_BUFSIZE];
>>>
>>>       snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>>> -    if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
>>> +    if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val)))
>>>           return -1;
>>>       return 0;
>>>   }
>>> @@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char
>>> *node)
>>>       char *str, *ret = NULL;
>>>
>>>       snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>>> -    str = xs_read(xenstore, 0, abspath,&len);
>>> +    str = xs_ops.read(xenstore, 0, abspath,&len);
>>>
>>>        
>> I think I gave this feedback before but I'd really like to see static
>> inlines here.
>>
>> It's very likely that you'll either want to have tracing or some commands
>> can have a NULL function pointer in which case having a central location to
>> do this is very useful.
>>
>> Plus, it's more natural to read code that's making a function call instead
>> of going through a function pointer in a structure redirection.
>>
>> Can probably do this with just a sed over the current patch.
>>      
>
> Is it good to have a .h with functions like that? :
>
> static inline XenXC qemu_xc_interface_open(xentoollog_logger *logger,
>                              xentoollog_logger *dombuild_logger,
>                              unsigned open_flags)
> {
> #if CONFIG_XEN_CTRL_INTERFACE_VERSION<  410
>      return xc_interface_open();
> #else
>      return xc_interface_open(logger, dombuild_logger, open_flags);
> #endif
> }
>
>
> So there will have no more structure redirection.
>    

It would be better to have two versions of the header, one that 
implemented the < 410 functions and one that implemented the newer 
functions.

If you're just using the new signature for everything, you could even 
just #define in the later header.

Regards,

Anthony Liguori

> Regards,
>
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
@ 2011-02-25 14:11         ` Anthony Liguori
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony Liguori @ 2011-02-25 14:11 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On 02/25/2011 08:06 AM, Anthony PERARD wrote:
> On Thu, Feb 24, 2011 at 17:29, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>    
>> On 02/02/2011 08:49 AM, anthony.perard@citrix.com wrote:
>>      
>>> From: Anthony PERARD<anthony.perard@citrix.com>
>>>
>>> This patch adds a generic layer for xc calls, allowing us to choose
>>> between the
>>> xenner and xen implementations at runtime.
>>>
>>> It also 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 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>
>>> Acked-by: Alexander Graf<agraf@suse.de>
>>> ---
>>>   Makefile.target      |    3 +
>>>   configure            |   62 +++++++++++++++-
>>>   hw/xen_backend.c     |   74 ++++++++++---------
>>>   hw/xen_backend.h     |    7 +-
>>>   hw/xen_common.h      |   38 ++++++----
>>>   hw/xen_console.c     |   10 +-
>>>   hw/xen_devconfig.c   |   10 +-
>>>   hw/xen_disk.c        |   28 ++++---
>>>   hw/xen_domainbuild.c |   29 ++++----
>>>   hw/xen_interfaces.c  |  191
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>>   hw/xen_interfaces.h  |  198
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>>   hw/xen_nic.c         |   36 +++++-----
>>>   hw/xenfb.c           |   14 ++--
>>>   13 files changed, 584 insertions(+), 116 deletions(-)
>>>   create mode 100644 hw/xen_interfaces.c
>>>   create mode 100644 hw/xen_interfaces.h
>>>
>>> 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..cf081e1 100644
>>> --- a/hw/xen_backend.c
>>> +++ b/hw/xen_backend.c
>>> @@ -43,7 +43,8 @@
>>>   /* ------------------------------------------------------------- */
>>>
>>>   /* public */
>>> -int xen_xc;
>>> +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
>>> +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
>>>   struct xs_handle *xenstore = NULL;
>>>   const char *xen_protocol;
>>>
>>> @@ -58,7 +59,7 @@ int xenstore_write_str(const char *base, const char
>>> *node, const char *val)
>>>       char abspath[XEN_BUFSIZE];
>>>
>>>       snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>>> -    if (!xs_write(xenstore, 0, abspath, val, strlen(val)))
>>> +    if (!xs_ops.write(xenstore, 0, abspath, val, strlen(val)))
>>>           return -1;
>>>       return 0;
>>>   }
>>> @@ -70,7 +71,7 @@ char *xenstore_read_str(const char *base, const char
>>> *node)
>>>       char *str, *ret = NULL;
>>>
>>>       snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
>>> -    str = xs_read(xenstore, 0, abspath,&len);
>>> +    str = xs_ops.read(xenstore, 0, abspath,&len);
>>>
>>>        
>> I think I gave this feedback before but I'd really like to see static
>> inlines here.
>>
>> It's very likely that you'll either want to have tracing or some commands
>> can have a NULL function pointer in which case having a central location to
>> do this is very useful.
>>
>> Plus, it's more natural to read code that's making a function call instead
>> of going through a function pointer in a structure redirection.
>>
>> Can probably do this with just a sed over the current patch.
>>      
>
> Is it good to have a .h with functions like that? :
>
> static inline XenXC qemu_xc_interface_open(xentoollog_logger *logger,
>                              xentoollog_logger *dombuild_logger,
>                              unsigned open_flags)
> {
> #if CONFIG_XEN_CTRL_INTERFACE_VERSION<  410
>      return xc_interface_open();
> #else
>      return xc_interface_open(logger, dombuild_logger, open_flags);
> #endif
> }
>
>
> So there will have no more structure redirection.
>    

It would be better to have two versions of the header, one that 
implemented the < 410 functions and one that implemented the newer 
functions.

If you're just using the new signature for everything, you could even 
just #define in the later header.

Regards,

Anthony Liguori

> Regards,
>
>    

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
  2011-02-25 10:54           ` Paolo Bonzini
@ 2011-02-25 14:18             ` Anthony PERARD
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 14:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Xen Devel, Ian Campbell, Stefano Stabellini, QEMU-devel, Steven Smith

On Fri, Feb 25, 2011 at 10:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
> On 02/25/2011 10:58 AM, Ian Campbell wrote:
>>
>> >  Or it should just go away.  Guests can already write to 0xe9 and see
>> >  the output on the host's "xm dmesg" ring and serial console.
>>
>> Only true if you have configured the guest log level to include debug
>> messages.
>
> If you can recompile QEMU to add DEBUG_PLATFORM, you can usually do that
> too.  To avoid recompilation, rather than a chardev it would be even better
> to keep it as a trace event.

The trace event seems a good idea, let's go for that!

Regards,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device
@ 2011-02-25 14:18             ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 14:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Xen Devel, Ian Campbell, Stefano Stabellini, QEMU-devel,
	Anthony Liguori, Steven Smith

On Fri, Feb 25, 2011 at 10:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
> On 02/25/2011 10:58 AM, Ian Campbell wrote:
>>
>> >  Or it should just go away.  Guests can already write to 0xe9 and see
>> >  the output on the host's "xm dmesg" ring and serial console.
>>
>> Only true if you have configured the guest log level to include debug
>> messages.
>
> If you can recompile QEMU to add DEBUG_PLATFORM, you can usually do that
> too.  To avoid recompilation, rather than a chardev it would be even better
> to keep it as a trace event.

The trace event seems a good idea, let's go for that!

Regards,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine
  2011-02-25 14:09       ` Anthony Liguori
@ 2011-02-25 14:28           ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 14:28 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On Fri, Feb 25, 2011 at 14:09, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 02/25/2011 07:55 AM, Anthony PERARD wrote:
>>
>> On Thu, Feb 24, 2011 at 17:31, Anthony Liguori<anthony@codemonkey.ws>
>>  wrote:
>>
>>>>
>>>> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
>>>> index 7b74473..0ab8907 100644
>>>> --- a/hw/pc_piix.c
>>>> +++ b/hw/pc_piix.c
>>>> @@ -36,6 +36,10 @@
>>>>  #include "sysbus.h"
>>>>  #include "arch_init.h"
>>>>  #include "blockdev.h"
>>>> +#include "xen.h"
>>>> +#ifdef CONFIG_XEN
>>>> +#  include "xen/hvm/hvm_info_table.h"
>>>> +#endif
>>>>
>>>>
>>>
>>> Admittedly a nit, but isn't this a system header?
>>>
>>
>> It belongs to Xen. I use it for HVM_MAX_VCPUS.
>>
>> I can put it in xen.h, if you prefer.
>>
>
> I meant, you should use:
>
> #include <xen/hvm/hvm_info_table.h>

Sure, I will do that.

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine
@ 2011-02-25 14:28           ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 14:28 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Xen Devel, QEMU-devel, Stefano Stabellini

On Fri, Feb 25, 2011 at 14:09, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 02/25/2011 07:55 AM, Anthony PERARD wrote:
>>
>> On Thu, Feb 24, 2011 at 17:31, Anthony Liguori<anthony@codemonkey.ws>
>>  wrote:
>>
>>>>
>>>> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
>>>> index 7b74473..0ab8907 100644
>>>> --- a/hw/pc_piix.c
>>>> +++ b/hw/pc_piix.c
>>>> @@ -36,6 +36,10 @@
>>>>  #include "sysbus.h"
>>>>  #include "arch_init.h"
>>>>  #include "blockdev.h"
>>>> +#include "xen.h"
>>>> +#ifdef CONFIG_XEN
>>>> +#  include "xen/hvm/hvm_info_table.h"
>>>> +#endif
>>>>
>>>>
>>>
>>> Admittedly a nit, but isn't this a system header?
>>>
>>
>> It belongs to Xen. I use it for HVM_MAX_VCPUS.
>>
>> I can put it in xen.h, if you prefer.
>>
>
> I meant, you should use:
>
> #include <xen/hvm/hvm_info_table.h>

Sure, I will do that.

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
  2011-02-25 14:11         ` Anthony Liguori
@ 2011-02-25 16:01           ` Anthony PERARD
  -1 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 16:01 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Alexander Graf, Xen Devel, QEMU-devel, Stefano Stabellini

On Fri, Feb 25, 2011 at 14:11, Anthony Liguori <anthony@codemonkey.ws> wrote:
>>> I think I gave this feedback before but I'd really like to see static
>>> inlines here.
>>>
>>> It's very likely that you'll either want to have tracing or some commands
>>> can have a NULL function pointer in which case having a central location
>>> to
>>> do this is very useful.
>>>
>>> Plus, it's more natural to read code that's making a function call
>>> instead
>>> of going through a function pointer in a structure redirection.
>>>
>>> Can probably do this with just a sed over the current patch.
>>>
>>
>> Is it good to have a .h with functions like that? :
>>
>> static inline XenXC qemu_xc_interface_open(xentoollog_logger *logger,
>>                             xentoollog_logger *dombuild_logger,
>>                             unsigned open_flags)
>> {
>> #if CONFIG_XEN_CTRL_INTERFACE_VERSION<  410
>>     return xc_interface_open();
>> #else
>>     return xc_interface_open(logger, dombuild_logger, open_flags);
>> #endif
>> }
>>
>>
>> So there will have no more structure redirection.
>>
>
> It would be better to have two versions of the header, one that implemented
> the < 410 functions and one that implemented the newer functions.
>
> If you're just using the new signature for everything, you could even just
> #define in the later header.

Actually, the #define in the later header was done in a previous
version of this patch series. But I change to the structure
redirection after a comment of Alexander Graf and by taking one of his
patches for Xenner.

Here is the comment of Alexander:
http://lists.nongnu.org/archive/html/qemu-devel/2010-11/msg01251.html
The function pointers help switch at run time to either Xen or Xenner
implementation.

This message is why I did not use static inline.
http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg03125.html


So, I can go for multiple version of the header that defines the
static inlines functions, or just have a few define.
BTW, I think there are now only 4 functions with a different prototype
between old and new version of Xen. Other prototype change are only
the "handler" parameter, but a typedef handle it.

Regards,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable.
@ 2011-02-25 16:01           ` Anthony PERARD
  0 siblings, 0 replies; 68+ messages in thread
From: Anthony PERARD @ 2011-02-25 16:01 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Alexander Graf, Xen Devel, QEMU-devel, Stefano Stabellini

On Fri, Feb 25, 2011 at 14:11, Anthony Liguori <anthony@codemonkey.ws> wrote:
>>> I think I gave this feedback before but I'd really like to see static
>>> inlines here.
>>>
>>> It's very likely that you'll either want to have tracing or some commands
>>> can have a NULL function pointer in which case having a central location
>>> to
>>> do this is very useful.
>>>
>>> Plus, it's more natural to read code that's making a function call
>>> instead
>>> of going through a function pointer in a structure redirection.
>>>
>>> Can probably do this with just a sed over the current patch.
>>>
>>
>> Is it good to have a .h with functions like that? :
>>
>> static inline XenXC qemu_xc_interface_open(xentoollog_logger *logger,
>>                             xentoollog_logger *dombuild_logger,
>>                             unsigned open_flags)
>> {
>> #if CONFIG_XEN_CTRL_INTERFACE_VERSION<  410
>>     return xc_interface_open();
>> #else
>>     return xc_interface_open(logger, dombuild_logger, open_flags);
>> #endif
>> }
>>
>>
>> So there will have no more structure redirection.
>>
>
> It would be better to have two versions of the header, one that implemented
> the < 410 functions and one that implemented the newer functions.
>
> If you're just using the new signature for everything, you could even just
> #define in the later header.

Actually, the #define in the later header was done in a previous
version of this patch series. But I change to the structure
redirection after a comment of Alexander Graf and by taking one of his
patches for Xenner.

Here is the comment of Alexander:
http://lists.nongnu.org/archive/html/qemu-devel/2010-11/msg01251.html
The function pointers help switch at run time to either Xen or Xenner
implementation.

This message is why I did not use static inline.
http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg03125.html


So, I can go for multiple version of the header that defines the
static inlines functions, or just have a few define.
BTW, I think there are now only 4 functions with a different prototype
between old and new version of Xen. Other prototype change are only
the "handler" parameter, but a typedef handle it.

Regards,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-02-24 17:59             ` Anthony Liguori
@ 2011-03-11  6:20               ` Alexander Graf
  -1 siblings, 0 replies; 68+ messages in thread
From: Alexander Graf @ 2011-03-11  6:20 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony PERARD, Jan Kiszka, Xen Devel, QEMU-devel, Stefano Stabellini


On 24.02.2011, at 18:59, Anthony Liguori wrote:

> On 02/24/2011 11:46 AM, Jan Kiszka wrote:
>> On 2011-02-24 18:27, Anthony Liguori wrote:
>>   
>>> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
>>>     
>>>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>   wrote:
>>>> 
>>>>       
>>>>> Is this really necessary?  The advantage to building globally is that it
>>>>> keeps the code from getting unnecessary i386-isms.
>>>>> 
>>>>>         
>>>> Nop, is not necessary, I add this patch after this mail:
>>>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>>>> 
>>>>       
>>> Alex, do you feel strongly here?
>>>     
>> I'm not Alex, but I brought this issue up:
>> 
>> Either build xen bits once for all archs or restrict it to the only
>> foreseeable arch with support in qemu. But please don't built it for
>> each and every target separately.
>>   
> 
> Oh yes, I misunderstood.  I thought we had previously built it for all architectures.  Yes, we should only build it once.

There's really no point in building it for anything but x86. Xen has never had been broadly used in PV mode on non-x86. Not sure ports even exist.


Alex

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
@ 2011-03-11  6:20               ` Alexander Graf
  0 siblings, 0 replies; 68+ messages in thread
From: Alexander Graf @ 2011-03-11  6:20 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony PERARD, Jan Kiszka, Xen Devel, QEMU-devel, Stefano Stabellini


On 24.02.2011, at 18:59, Anthony Liguori wrote:

> On 02/24/2011 11:46 AM, Jan Kiszka wrote:
>> On 2011-02-24 18:27, Anthony Liguori wrote:
>>   
>>> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
>>>     
>>>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>   wrote:
>>>> 
>>>>       
>>>>> Is this really necessary?  The advantage to building globally is that it
>>>>> keeps the code from getting unnecessary i386-isms.
>>>>> 
>>>>>         
>>>> Nop, is not necessary, I add this patch after this mail:
>>>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
>>>> 
>>>>       
>>> Alex, do you feel strongly here?
>>>     
>> I'm not Alex, but I brought this issue up:
>> 
>> Either build xen bits once for all archs or restrict it to the only
>> foreseeable arch with support in qemu. But please don't built it for
>> each and every target separately.
>>   
> 
> Oh yes, I misunderstood.  I thought we had previously built it for all architectures.  Yes, we should only build it once.

There's really no point in building it for anything but x86. Xen has never had been broadly used in PV mode on non-x86. Not sure ports even exist.


Alex

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Xen-devel] Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
  2011-03-11  6:20               ` Alexander Graf
@ 2011-03-11 11:15                 ` Stefano Stabellini
  -1 siblings, 0 replies; 68+ messages in thread
From: Stefano Stabellini @ 2011-03-11 11:15 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Devel, Stefano Stabellini, Jan Kiszka, Xen, QEMU-devel, Anthony Perard

On Fri, 11 Mar 2011, Alexander Graf wrote:
> 
> On 24.02.2011, at 18:59, Anthony Liguori wrote:
> 
> > On 02/24/2011 11:46 AM, Jan Kiszka wrote:
> >> On 2011-02-24 18:27, Anthony Liguori wrote:
> >>   
> >>> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
> >>>     
> >>>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>   wrote:
> >>>> 
> >>>>       
> >>>>> Is this really necessary?  The advantage to building globally is that it
> >>>>> keeps the code from getting unnecessary i386-isms.
> >>>>> 
> >>>>>         
> >>>> Nop, is not necessary, I add this patch after this mail:
> >>>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
> >>>> 
> >>>>       
> >>> Alex, do you feel strongly here?
> >>>     
> >> I'm not Alex, but I brought this issue up:
> >> 
> >> Either build xen bits once for all archs or restrict it to the only
> >> foreseeable arch with support in qemu. But please don't built it for
> >> each and every target separately.
> >>   
> > 
> > Oh yes, I misunderstood.  I thought we had previously built it for all architectures.  Yes, we should only build it once.
> 
> There's really no point in building it for anything but x86. Xen has never had been broadly used in PV mode on non-x86. Not sure ports even exist.
> 

There is an ia64 port available, but restricting xen to x86 makes sense
at least for the moment.


BTW qemu is mainly used in HVM mode on xen, but considering that cpu
emulation is not needed, qemu x86 would probably work for the ia64 case
too: this is how qemu-xen is used on ia64 at the moment, even though in
the qemu-xen case xen is not an accelerator but a new target with a set
of hardware devices very similar to x86.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: Re: [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target.
@ 2011-03-11 11:15                 ` Stefano Stabellini
  0 siblings, 0 replies; 68+ messages in thread
From: Stefano Stabellini @ 2011-03-11 11:15 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Devel, Stefano Stabellini, Jan Kiszka, Xen, QEMU-devel,
	Anthony Liguori, Anthony Perard

On Fri, 11 Mar 2011, Alexander Graf wrote:
> 
> On 24.02.2011, at 18:59, Anthony Liguori wrote:
> 
> > On 02/24/2011 11:46 AM, Jan Kiszka wrote:
> >> On 2011-02-24 18:27, Anthony Liguori wrote:
> >>   
> >>> On 02/24/2011 10:25 AM, Anthony PERARD wrote:
> >>>     
> >>>> On Thu, Feb 24, 2011 at 16:11, Anthony Liguori<anthony@codemonkey.ws>   wrote:
> >>>> 
> >>>>       
> >>>>> Is this really necessary?  The advantage to building globally is that it
> >>>>> keeps the code from getting unnecessary i386-isms.
> >>>>> 
> >>>>>         
> >>>> Nop, is not necessary, I add this patch after this mail:
> >>>> http://lists.nongnu.org/archive/html/qemu-devel/2010-12/msg00044.html
> >>>> 
> >>>>       
> >>> Alex, do you feel strongly here?
> >>>     
> >> I'm not Alex, but I brought this issue up:
> >> 
> >> Either build xen bits once for all archs or restrict it to the only
> >> foreseeable arch with support in qemu. But please don't built it for
> >> each and every target separately.
> >>   
> > 
> > Oh yes, I misunderstood.  I thought we had previously built it for all architectures.  Yes, we should only build it once.
> 
> There's really no point in building it for anything but x86. Xen has never had been broadly used in PV mode on non-x86. Not sure ports even exist.
> 

There is an ia64 port available, but restricting xen to x86 makes sense
at least for the moment.


BTW qemu is mainly used in HVM mode on xen, but considering that cpu
emulation is not needed, qemu x86 would probably work for the ia64 case
too: this is how qemu-xen is used on ia64 at the moment, even though in
the qemu-xen case xen is not an accelerator but a new target with a set
of hardware devices very similar to x86.

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2011-03-11 11:16 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-02 14:49 [Qemu-devel] [PATCH V10 00/15] Xen device model support anthony.perard
2011-02-02 14:49 ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 01/15] xen: Replace some tab-indents with spaces (clean-up) anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-24 16:06   ` [Qemu-devel] " Anthony Liguori
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 02/15] xen: Make xen build only on x86 target anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-24 16:11   ` [Qemu-devel] " Anthony Liguori
2011-02-24 16:25     ` [Xen-devel] " Anthony PERARD
2011-02-24 16:25       ` Anthony PERARD
2011-02-24 17:27       ` [Xen-devel] " Anthony Liguori
2011-02-24 17:27         ` Anthony Liguori
2011-02-24 17:46         ` [Xen-devel] " Jan Kiszka
2011-02-24 17:46           ` Jan Kiszka
2011-02-24 17:59           ` [Xen-devel] " Anthony Liguori
2011-02-24 17:59             ` Anthony Liguori
2011-03-11  6:20             ` [Xen-devel] " Alexander Graf
2011-03-11  6:20               ` Alexander Graf
2011-03-11 11:15               ` [Xen-devel] " Stefano Stabellini
2011-03-11 11:15                 ` Stefano Stabellini
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 03/15] xen: Support new libxc calls from xen unstable anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-24 17:29   ` [Qemu-devel] " Anthony Liguori
2011-02-25 14:06     ` [Xen-devel] " Anthony PERARD
2011-02-25 14:06       ` Anthony PERARD
2011-02-25 14:11       ` [Xen-devel] " Anthony Liguori
2011-02-25 14:11         ` Anthony Liguori
2011-02-25 16:01         ` [Xen-devel] " Anthony PERARD
2011-02-25 16:01           ` Anthony PERARD
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 04/15] xen: Add initialisation of Xen anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 05/15] xen: Add xenfv machine anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-24 17:31   ` [Qemu-devel] " Anthony Liguori
2011-02-25 13:55     ` Anthony PERARD
2011-02-25 14:09       ` Anthony Liguori
2011-02-25 14:28         ` [Xen-devel] " Anthony PERARD
2011-02-25 14:28           ` Anthony PERARD
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 06/15] xen: Add the Xen platform pci device anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-24 17:33   ` [Qemu-devel] " Anthony Liguori
2011-02-24 17:36     ` Paolo Bonzini
2011-02-25  9:58       ` [Xen-devel] " Ian Campbell
2011-02-25  9:58         ` Ian Campbell
2011-02-25 10:54         ` Paolo Bonzini
2011-02-25 10:54           ` Paolo Bonzini
2011-02-25 14:18           ` [Xen-devel] " Anthony PERARD
2011-02-25 14:18             ` Anthony PERARD
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 07/15] piix_pci: Introduces Xen specific call for irq anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-24 17:34   ` [Qemu-devel] " Anthony Liguori
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 08/15] xen: Introduce Xen Interrupt Controller anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 09/15] xen: Introduce the Xen mapcache anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 10/15] configure: Always use 64bits target physical addresses with xen enabled anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 11/15] Introduce qemu_put_ram_ptr anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 12/15] vl.c: Introduce getter for shutdown_requested and reset_requested anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 13/15] xen: Initialize event channels and io rings anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 14/15] xen: Set running state in xenstore anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-02 14:49 ` [Qemu-devel] [PATCH V10 15/15] xen: Add Xen hypercall for sleep state in the cmos_s3 callback anthony.perard
2011-02-02 14:49   ` anthony.perard
2011-02-24 17:38 ` [Qemu-devel] [PATCH V10 00/15] Xen device model support Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.