--- /dev/null
+Subject: Fix Xen build wrt. Xen files coming from mainline.
+From: http://xenbits.xensource.com/linux-2.6.18-xen.hg (tip 728:832aac894efd)
+Patch-mainline: obsolete
+
+Acked-by: jbeulich@novell.com
+
+Index: head-2008-11-25/drivers/xen/Makefile
+===================================================================
+--- head-2008-11-25.orig/drivers/xen/Makefile 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/drivers/xen/Makefile 2008-11-25 12:35:56.000000000 +0100
+@@ -1,4 +1,25 @@
+-obj-y += grant-table.o features.o events.o manage.o
++obj-y += core/
++obj-y += console/
++obj-y += evtchn/
+ obj-y += xenbus/
+-obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
+-obj-$(CONFIG_XEN_BALLOON) += balloon.o
++obj-y += char/
++
++obj-y += util.o
++obj-$(CONFIG_XEN_BALLOON) += balloon/
++obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/
++obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/
++obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/
++obj-$(CONFIG_XEN_TPMDEV_BACKEND) += tpmback/
++obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/
++obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/
++obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/
++obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/
++obj-$(CONFIG_XEN_FRAMEBUFFER) += fbfront/
++obj-$(CONFIG_XEN_KEYBOARD) += fbfront/
++obj-$(CONFIG_XEN_SCSI_BACKEND) += scsiback/
++obj-$(CONFIG_XEN_SCSI_FRONTEND) += scsifront/
++obj-$(CONFIG_XEN_PRIVCMD) += privcmd/
++obj-$(CONFIG_XEN_GRANT_DEV) += gntdev/
++obj-$(CONFIG_XEN_NETDEV_ACCEL_SFC_UTIL) += sfc_netutil/
++obj-$(CONFIG_XEN_NETDEV_ACCEL_SFC_FRONTEND) += sfc_netfront/
++obj-$(CONFIG_XEN_NETDEV_ACCEL_SFC_BACKEND) += sfc_netback/
+Index: head-2008-11-25/drivers/xen/xenbus/Makefile
+===================================================================
+--- head-2008-11-25.orig/drivers/xen/xenbus/Makefile 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/drivers/xen/xenbus/Makefile 2008-11-25 12:35:56.000000000 +0100
+@@ -1,7 +1,9 @@
+-obj-y += xenbus.o
++obj-y += xenbus_client.o xenbus_comms.o xenbus_xs.o xenbus_probe.o
++obj-$(CONFIG_XEN_BACKEND) += xenbus_be.o
+
+-xenbus-objs =
+-xenbus-objs += xenbus_client.o
+-xenbus-objs += xenbus_comms.o
+-xenbus-objs += xenbus_xs.o
+-xenbus-objs += xenbus_probe.o
++xenbus_be-objs =
++xenbus_be-objs += xenbus_backend_client.o
++
++xenbus-$(CONFIG_XEN_BACKEND) += xenbus_probe_backend.o
++obj-y += $(xenbus-y) $(xenbus-m)
++obj-$(CONFIG_XEN_XENBUS_DEV) += xenbus_dev.o
+Index: head-2008-11-25/drivers/xen/xenbus/xenbus_client.c
+===================================================================
+--- head-2008-11-25.orig/drivers/xen/xenbus/xenbus_client.c 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/drivers/xen/xenbus/xenbus_client.c 2008-11-25 12:35:56.000000000 +0100
+@@ -30,14 +30,18 @@
+ * IN THE SOFTWARE.
+ */
+
+-#include <linux/types.h>
+-#include <linux/vmalloc.h>
+-#include <asm/xen/hypervisor.h>
+-#include <xen/interface/xen.h>
+-#include <xen/interface/event_channel.h>
+-#include <xen/events.h>
+-#include <xen/grant_table.h>
++#include <linux/slab.h>
++#include <xen/evtchn.h>
++#include <xen/gnttab.h>
+ #include <xen/xenbus.h>
++#include <xen/driver_util.h>
++
++#ifdef HAVE_XEN_PLATFORM_COMPAT_H
++#include <xen/platform-compat.h>
++#endif
++
++#define DPRINTK(fmt, args...) \
++ pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
+
+ const char *xenbus_strstate(enum xenbus_state state)
+ {
+@@ -54,20 +58,6 @@ const char *xenbus_strstate(enum xenbus_
+ }
+ EXPORT_SYMBOL_GPL(xenbus_strstate);
+
+-/**
+- * xenbus_watch_path - register a watch
+- * @dev: xenbus device
+- * @path: path to watch
+- * @watch: watch to register
+- * @callback: callback to register
+- *
+- * Register a @watch on the given path, using the given xenbus_watch structure
+- * for storage, and the given @callback function as the callback. Return 0 on
+- * success, or -errno on error. On success, the given @path will be saved as
+- * @watch->node, and remains the caller's to free. On error, @watch->node will
+- * be NULL, the device will switch to %XenbusStateClosing, and the error will
+- * be saved in the store.
+- */
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+ struct xenbus_watch *watch,
+ void (*callback)(struct xenbus_watch *,
+@@ -91,58 +81,26 @@ int xenbus_watch_path(struct xenbus_devi
+ EXPORT_SYMBOL_GPL(xenbus_watch_path);
+
+
+-/**
+- * xenbus_watch_pathfmt - register a watch on a sprintf-formatted path
+- * @dev: xenbus device
+- * @watch: watch to register
+- * @callback: callback to register
+- * @pathfmt: format of path to watch
+- *
+- * Register a watch on the given @path, using the given xenbus_watch
+- * structure for storage, and the given @callback function as the callback.
+- * Return 0 on success, or -errno on error. On success, the watched path
+- * (@path/@path2) will be saved as @watch->node, and becomes the caller's to
+- * kfree(). On error, watch->node will be NULL, so the caller has nothing to
+- * free, the device will switch to %XenbusStateClosing, and the error will be
+- * saved in the store.
+- */
+-int xenbus_watch_pathfmt(struct xenbus_device *dev,
+- struct xenbus_watch *watch,
+- void (*callback)(struct xenbus_watch *,
+- const char **, unsigned int),
+- const char *pathfmt, ...)
++int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
++ const char *path2, struct xenbus_watch *watch,
++ void (*callback)(struct xenbus_watch *,
++ const char **, unsigned int))
+ {
+ int err;
+- va_list ap;
+- char *path;
+-
+- va_start(ap, pathfmt);
+- path = kvasprintf(GFP_NOIO | __GFP_HIGH, pathfmt, ap);
+- va_end(ap);
+-
+- if (!path) {
++ char *state = kasprintf(GFP_NOIO | __GFP_HIGH, "%s/%s", path, path2);
++ if (!state) {
+ xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
+ return -ENOMEM;
+ }
+- err = xenbus_watch_path(dev, path, watch, callback);
++ err = xenbus_watch_path(dev, state, watch, callback);
+
+ if (err)
+- kfree(path);
++ kfree(state);
+ return err;
+ }
+-EXPORT_SYMBOL_GPL(xenbus_watch_pathfmt);
++EXPORT_SYMBOL_GPL(xenbus_watch_path2);
+
+
+-/**
+- * xenbus_switch_state
+- * @dev: xenbus device
+- * @xbt: transaction handle
+- * @state: new state
+- *
+- * Advertise in the store a change of the given driver to the given new_state.
+- * Return 0 on success, or -errno on error. On error, the device will switch
+- * to XenbusStateClosing, and the error will be saved in the store.
+- */
+ int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
+ {
+ /* We check whether the state is currently set to the given value, and
+@@ -201,13 +159,12 @@ static char *error_path(struct xenbus_de
+ }
+
+
+-static void xenbus_va_dev_error(struct xenbus_device *dev, int err,
+- const char *fmt, va_list ap)
++void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
++ va_list ap)
+ {
+ int ret;
+ unsigned int len;
+- char *printf_buffer = NULL;
+- char *path_buffer = NULL;
++ char *printf_buffer = NULL, *path_buffer = NULL;
+
+ #define PRINTF_BUFFER_SIZE 4096
+ printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
+@@ -224,74 +181,51 @@ static void xenbus_va_dev_error(struct x
+ path_buffer = error_path(dev);
+
+ if (path_buffer == NULL) {
+- dev_err(&dev->dev, "failed to write error node for %s (%s)\n",
++ printk("xenbus: failed to write error node for %s (%s)\n",
+ dev->nodename, printf_buffer);
+ goto fail;
+ }
+
+ if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
+- dev_err(&dev->dev, "failed to write error node for %s (%s)\n",
++ printk("xenbus: failed to write error node for %s (%s)\n",
+ dev->nodename, printf_buffer);
+ goto fail;
+ }
+
+ fail:
+- kfree(printf_buffer);
+- kfree(path_buffer);
++ if (printf_buffer)
++ kfree(printf_buffer);
++ if (path_buffer)
++ kfree(path_buffer);
+ }
+
+
+-/**
+- * xenbus_dev_error
+- * @dev: xenbus device
+- * @err: error to report
+- * @fmt: error message format
+- *
+- * Report the given negative errno into the store, along with the given
+- * formatted message.
+- */
+-void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
++void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
++ ...)
+ {
+ va_list ap;
+
+ va_start(ap, fmt);
+- xenbus_va_dev_error(dev, err, fmt, ap);
++ _dev_error(dev, err, fmt, ap);
+ va_end(ap);
+ }
+ EXPORT_SYMBOL_GPL(xenbus_dev_error);
+
+-/**
+- * xenbus_dev_fatal
+- * @dev: xenbus device
+- * @err: error to report
+- * @fmt: error message format
+- *
+- * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
+- * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
+- * closedown of this driver and its peer.
+- */
+
+-void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...)
++void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
++ ...)
+ {
+ va_list ap;
+
+ va_start(ap, fmt);
+- xenbus_va_dev_error(dev, err, fmt, ap);
++ _dev_error(dev, err, fmt, ap);
+ va_end(ap);
+
+ xenbus_switch_state(dev, XenbusStateClosing);
+ }
+ EXPORT_SYMBOL_GPL(xenbus_dev_fatal);
+
+-/**
+- * xenbus_grant_ring
+- * @dev: xenbus device
+- * @ring_mfn: mfn of ring to grant
+-
+- * Grant access to the given @ring_mfn to the peer of the given device. Return
+- * 0 on success, or -errno on error. On error, the device will switch to
+- * XenbusStateClosing, and the error will be saved in the store.
+- */
++
+ int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
+ {
+ int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0);
+@@ -302,18 +236,12 @@ int xenbus_grant_ring(struct xenbus_devi
+ EXPORT_SYMBOL_GPL(xenbus_grant_ring);
+
+
+-/**
+- * Allocate an event channel for the given xenbus_device, assigning the newly
+- * created local port to *port. Return 0 on success, or -errno on error. On
+- * error, the device will switch to XenbusStateClosing, and the error will be
+- * saved in the store.
+- */
+ int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
+ {
+ struct evtchn_alloc_unbound alloc_unbound;
+ int err;
+
+- alloc_unbound.dom = DOMID_SELF;
++ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = dev->otherend_id;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+@@ -328,36 +256,6 @@ int xenbus_alloc_evtchn(struct xenbus_de
+ EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
+
+
+-/**
+- * Bind to an existing interdomain event channel in another domain. Returns 0
+- * on success and stores the local port in *port. On error, returns -errno,
+- * switches the device to XenbusStateClosing, and saves the error in XenStore.
+- */
+-int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
+-{
+- struct evtchn_bind_interdomain bind_interdomain;
+- int err;
+-
+- bind_interdomain.remote_dom = dev->otherend_id;
+- bind_interdomain.remote_port = remote_port;
+-
+- err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+- &bind_interdomain);
+- if (err)
+- xenbus_dev_fatal(dev, err,
+- "binding to event channel %d from domain %d",
+- remote_port, dev->otherend_id);
+- else
+- *port = bind_interdomain.local_port;
+-
+- return err;
+-}
+-EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
+-
+-
+-/**
+- * Free an existing event channel. Returns 0 on success or -errno on error.
+- */
+ int xenbus_free_evtchn(struct xenbus_device *dev, int port)
+ {
+ struct evtchn_close close;
+@@ -374,189 +272,6 @@ int xenbus_free_evtchn(struct xenbus_dev
+ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
+
+
+-/**
+- * xenbus_map_ring_valloc
+- * @dev: xenbus device
+- * @gnt_ref: grant reference
+- * @vaddr: pointer to address to be filled out by mapping
+- *
+- * Based on Rusty Russell's skeleton driver's map_page.
+- * Map a page of memory into this domain from another domain's grant table.
+- * xenbus_map_ring_valloc allocates a page of virtual address space, maps the
+- * page to that address, and sets *vaddr to that address.
+- * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
+- * or -ENOMEM on error. If an error is returned, device will switch to
+- * XenbusStateClosing and the error message will be saved in XenStore.
+- */
+-int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
+-{
+- struct gnttab_map_grant_ref op = {
+- .flags = GNTMAP_host_map,
+- .ref = gnt_ref,
+- .dom = dev->otherend_id,
+- };
+- struct vm_struct *area;
+-
+- *vaddr = NULL;
+-
+- area = xen_alloc_vm_area(PAGE_SIZE);
+- if (!area)
+- return -ENOMEM;
+-
+- op.host_addr = (unsigned long)area->addr;
+-
+- if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+- BUG();
+-
+- if (op.status != GNTST_okay) {
+- xen_free_vm_area(area);
+- xenbus_dev_fatal(dev, op.status,
+- "mapping in shared page %d from domain %d",
+- gnt_ref, dev->otherend_id);
+- return op.status;
+- }
+-
+- /* Stuff the handle in an unused field */
+- area->phys_addr = (unsigned long)op.handle;
+-
+- *vaddr = area->addr;
+- return 0;
+-}
+-EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
+-
+-
+-/**
+- * xenbus_map_ring
+- * @dev: xenbus device
+- * @gnt_ref: grant reference
+- * @handle: pointer to grant handle to be filled
+- * @vaddr: address to be mapped to
+- *
+- * Map a page of memory into this domain from another domain's grant table.
+- * xenbus_map_ring does not allocate the virtual address space (you must do
+- * this yourself!). It only maps in the page to the specified address.
+- * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
+- * or -ENOMEM on error. If an error is returned, device will switch to
+- * XenbusStateClosing and the error message will be saved in XenStore.
+- */
+-int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
+- grant_handle_t *handle, void *vaddr)
+-{
+- struct gnttab_map_grant_ref op = {
+- .host_addr = (unsigned long)vaddr,
+- .flags = GNTMAP_host_map,
+- .ref = gnt_ref,
+- .dom = dev->otherend_id,
+- };
+-
+- if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+- BUG();
+-
+- if (op.status != GNTST_okay) {
+- xenbus_dev_fatal(dev, op.status,
+- "mapping in shared page %d from domain %d",
+- gnt_ref, dev->otherend_id);
+- } else
+- *handle = op.handle;
+-
+- return op.status;
+-}
+-EXPORT_SYMBOL_GPL(xenbus_map_ring);
+-
+-
+-/**
+- * xenbus_unmap_ring_vfree
+- * @dev: xenbus device
+- * @vaddr: addr to unmap
+- *
+- * Based on Rusty Russell's skeleton driver's unmap_page.
+- * Unmap a page of memory in this domain that was imported from another domain.
+- * Use xenbus_unmap_ring_vfree if you mapped in your memory with
+- * xenbus_map_ring_valloc (it will free the virtual address space).
+- * Returns 0 on success and returns GNTST_* on error
+- * (see xen/include/interface/grant_table.h).
+- */
+-int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
+-{
+- struct vm_struct *area;
+- struct gnttab_unmap_grant_ref op = {
+- .host_addr = (unsigned long)vaddr,
+- };
+-
+- /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
+- * method so that we don't have to muck with vmalloc internals here.
+- * We could force the user to hang on to their struct vm_struct from
+- * xenbus_map_ring_valloc, but these 6 lines considerably simplify
+- * this API.
+- */
+- read_lock(&vmlist_lock);
+- for (area = vmlist; area != NULL; area = area->next) {
+- if (area->addr == vaddr)
+- break;
+- }
+- read_unlock(&vmlist_lock);
+-
+- if (!area) {
+- xenbus_dev_error(dev, -ENOENT,
+- "can't find mapped virtual address %p", vaddr);
+- return GNTST_bad_virt_addr;
+- }
+-
+- op.handle = (grant_handle_t)area->phys_addr;
+-
+- if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+- BUG();
+-
+- if (op.status == GNTST_okay)
+- xen_free_vm_area(area);
+- else
+- xenbus_dev_error(dev, op.status,
+- "unmapping page at handle %d error %d",
+- (int16_t)area->phys_addr, op.status);
+-
+- return op.status;
+-}
+-EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
+-
+-
+-/**
+- * xenbus_unmap_ring
+- * @dev: xenbus device
+- * @handle: grant handle
+- * @vaddr: addr to unmap
+- *
+- * Unmap a page of memory in this domain that was imported from another domain.
+- * Returns 0 on success and returns GNTST_* on error
+- * (see xen/include/interface/grant_table.h).
+- */
+-int xenbus_unmap_ring(struct xenbus_device *dev,
+- grant_handle_t handle, void *vaddr)
+-{
+- struct gnttab_unmap_grant_ref op = {
+- .host_addr = (unsigned long)vaddr,
+- .handle = handle,
+- };
+-
+- if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+- BUG();
+-
+- if (op.status != GNTST_okay)
+- xenbus_dev_error(dev, op.status,
+- "unmapping page at handle %d error %d",
+- handle, op.status);
+-
+- return op.status;
+-}
+-EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
+-
+-
+-/**
+- * xenbus_read_driver_state
+- * @path: path for driver
+- *
+- * Return the state of the driver rooted at the given store path, or
+- * XenbusStateUnknown if no state can be read.
+- */
+ enum xenbus_state xenbus_read_driver_state(const char *path)
+ {
+ enum xenbus_state result;
+Index: head-2008-11-25/drivers/xen/xenbus/xenbus_comms.c
+===================================================================
+--- head-2008-11-25.orig/drivers/xen/xenbus/xenbus_comms.c 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/drivers/xen/xenbus/xenbus_comms.c 2008-11-25 12:35:56.000000000 +0100
+@@ -34,19 +34,28 @@
+ #include <linux/interrupt.h>
+ #include <linux/sched.h>
+ #include <linux/err.h>
++#include <linux/ptrace.h>
++#include <linux/workqueue.h>
++#include <xen/evtchn.h>
+ #include <xen/xenbus.h>
+-#include <asm/xen/hypervisor.h>
+-#include <xen/events.h>
+-#include <xen/page.h>
++
++#include <asm/hypervisor.h>
++
+ #include "xenbus_comms.h"
+
++#ifdef HAVE_XEN_PLATFORM_COMPAT_H
++#include <xen/platform-compat.h>
++#endif
++
+ static int xenbus_irq;
+
+-static DECLARE_WORK(probe_work, xenbus_probe);
++extern void xenbus_probe(void *);
++extern int xenstored_ready;
++static DECLARE_WORK(probe_work, xenbus_probe, NULL);
+
+ static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
+
+-static irqreturn_t wake_waiting(int irq, void *unused)
++static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
+ {
+ if (unlikely(xenstored_ready == 0)) {
+ xenstored_ready = 1;
+@@ -82,13 +91,6 @@ static const void *get_input_chunk(XENST
+ return buf + MASK_XENSTORE_IDX(cons);
+ }
+
+-/**
+- * xb_write - low level write
+- * @data: buffer to send
+- * @len: length of buffer
+- *
+- * Returns 0 on success, error otherwise.
+- */
+ int xb_write(const void *data, unsigned len)
+ {
+ struct xenstore_domain_interface *intf = xen_store_interface;
+@@ -197,12 +199,11 @@ int xb_read(void *data, unsigned len)
+ return 0;
+ }
+
+-/**
+- * xb_init_comms - Set up interrupt handler off store event channel.
+- */
++/* Set up interrupt handler off store event channel. */
+ int xb_init_comms(void)
+ {
+ struct xenstore_domain_interface *intf = xen_store_interface;
++ int err;
+
+ if (intf->req_prod != intf->req_cons)
+ printk(KERN_ERR "XENBUS request ring is not quiescent "
+@@ -215,20 +216,18 @@ int xb_init_comms(void)
+ intf->rsp_cons = intf->rsp_prod;
+ }
+
+- if (xenbus_irq) {
+- /* Already have an irq; assume we're resuming */
+- rebind_evtchn_irq(xen_store_evtchn, xenbus_irq);
+- } else {
+- int err;
+- err = bind_evtchn_to_irqhandler(xen_store_evtchn, wake_waiting,
+- 0, "xenbus", &xb_waitq);
+- if (err <= 0) {
+- printk(KERN_ERR "XENBUS request irq failed %i\n", err);
+- return err;
+- }
++ if (xenbus_irq)
++ unbind_from_irqhandler(xenbus_irq, &xb_waitq);
+
+- xenbus_irq = err;
++ err = bind_caller_port_to_irqhandler(
++ xen_store_evtchn, wake_waiting,
++ 0, "xenbus", &xb_waitq);
++ if (err <= 0) {
++ printk(KERN_ERR "XENBUS request irq failed %i\n", err);
++ return err;
+ }
+
++ xenbus_irq = err;
++
+ return 0;
+ }
+Index: head-2008-11-25/drivers/xen/xenbus/xenbus_probe.c
+===================================================================
+--- head-2008-11-25.orig/drivers/xen/xenbus/xenbus_probe.c 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/drivers/xen/xenbus/xenbus_probe.c 2008-11-25 12:35:56.000000000 +0100
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard
+ * Copyright (C) 2005, 2006 XenSource Ltd
++ * Copyright (C) 2007 Solarflare Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+@@ -32,7 +33,7 @@
+
+ #define DPRINTK(fmt, args...) \
+ pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \
+- __func__, __LINE__, ##args)
++ __FUNCTION__, __LINE__, ##args)
+
+ #include <linux/kernel.h>
+ #include <linux/err.h>
+@@ -41,24 +42,35 @@
+ #include <linux/fcntl.h>
+ #include <linux/mm.h>
+ #include <linux/notifier.h>
+-#include <linux/kthread.h>
+ #include <linux/mutex.h>
+-#include <linux/io.h>
++#include <linux/module.h>
+
++#include <asm/io.h>
+ #include <asm/page.h>
++#include <asm/maddr.h>
+ #include <asm/pgtable.h>
+-#include <asm/xen/hypervisor.h>
++#include <asm/hypervisor.h>
+ #include <xen/xenbus.h>
+-#include <xen/events.h>
+-#include <xen/page.h>
++#include <xen/xen_proc.h>
++#include <xen/evtchn.h>
++#include <xen/features.h>
++#ifdef MODULE
++#include <xen/hvm.h>
++#endif
+
+ #include "xenbus_comms.h"
+ #include "xenbus_probe.h"
+
++#ifdef HAVE_XEN_PLATFORM_COMPAT_H
++#include <xen/platform-compat.h>
++#endif
++
+ int xen_store_evtchn;
+ struct xenstore_domain_interface *xen_store_interface;
+ static unsigned long xen_store_mfn;
+
++extern struct mutex xenwatch_mutex;
++
+ static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
+
+ static void wait_for_devices(struct xenbus_driver *xendrv);
+@@ -88,16 +100,6 @@ int xenbus_match(struct device *_dev, st
+ return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
+ }
+
+-static int xenbus_uevent(struct device *_dev, struct kobj_uevent_env *env)
+-{
+- struct xenbus_device *dev = to_xenbus_device(_dev);
+-
+- if (add_uevent_var(env, "MODALIAS=xen:%s", dev->devicetype))
+- return -ENOMEM;
+-
+- return 0;
+-}
+-
+ /* device/<type>/<id> => <type>-<id> */
+ static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
+ {
+@@ -166,6 +168,30 @@ static int read_backend_details(struct x
+ return read_otherend_details(xendev, "backend-id", "backend");
+ }
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
++static int xenbus_uevent_frontend(struct device *dev, char **envp,
++ int num_envp, char *buffer, int buffer_size)
++{
++ struct xenbus_device *xdev;
++ int length = 0, i = 0;
++
++ if (dev == NULL)
++ return -ENODEV;
++ xdev = to_xenbus_device(dev);
++ if (xdev == NULL)
++ return -ENODEV;
++
++ /* stuff we want to pass to /sbin/hotplug */
++ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
++ "XENBUS_TYPE=%s", xdev->devicetype);
++ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
++ "XENBUS_PATH=%s", xdev->nodename);
++ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
++ "MODALIAS=xen:%s", xdev->devicetype);
++
++ return 0;
++}
++#endif
+
+ /* Bus type for frontend drivers. */
+ static struct xen_bus_type xenbus_frontend = {
+@@ -173,13 +199,19 @@ static struct xen_bus_type xenbus_fronte
+ .levels = 2, /* device/type/<id> */
+ .get_bus_id = frontend_bus_id,
+ .probe = xenbus_probe_frontend,
++ .error = -ENODEV,
+ .bus = {
+ .name = "xen",
+ .match = xenbus_match,
+- .uevent = xenbus_uevent,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+ .probe = xenbus_dev_probe,
+ .remove = xenbus_dev_remove,
+ .shutdown = xenbus_dev_shutdown,
++ .uevent = xenbus_uevent_frontend,
++#endif
++ },
++ .dev = {
++ .bus_id = "xen",
+ },
+ };
+
+@@ -196,17 +228,16 @@ static void otherend_changed(struct xenb
+ if (!dev->otherend ||
+ strncmp(dev->otherend, vec[XS_WATCH_PATH],
+ strlen(dev->otherend))) {
+- dev_dbg(&dev->dev, "Ignoring watch at %s\n",
+- vec[XS_WATCH_PATH]);
++ DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
+ return;
+ }
+
+ state = xenbus_read_driver_state(dev->otherend);
+
+- dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n",
+- state, xenbus_strstate(state), dev->otherend_watch.node,
+- vec[XS_WATCH_PATH]);
++ DPRINTK("state is %d (%s), %s, %s", state, xenbus_strstate(state),
++ dev->otherend_watch.node, vec[XS_WATCH_PATH]);
+
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+ /*
+ * Ignore xenbus transitions during shutdown. This prevents us doing
+ * work that can fail e.g., when the rootfs is gone.
+@@ -220,6 +251,7 @@ static void otherend_changed(struct xenb
+ xenbus_frontend_closed(dev);
+ return;
+ }
++#endif
+
+ if (drv->otherend_changed)
+ drv->otherend_changed(dev, state);
+@@ -239,8 +271,8 @@ static int talk_to_otherend(struct xenbu
+
+ static int watch_otherend(struct xenbus_device *dev)
+ {
+- return xenbus_watch_pathfmt(dev, &dev->otherend_watch, otherend_changed,
+- "%s/%s", dev->otherend, "state");
++ return xenbus_watch_path2(dev, dev->otherend, "state",
++ &dev->otherend_watch, otherend_changed);
+ }
+
+
+@@ -266,8 +298,9 @@ int xenbus_dev_probe(struct device *_dev
+
+ err = talk_to_otherend(dev);
+ if (err) {
+- dev_warn(&dev->dev, "talk_to_otherend on %s failed.\n",
+- dev->nodename);
++ printk(KERN_WARNING
++ "xenbus_probe: talk_to_otherend on %s failed.\n",
++ dev->nodename);
+ return err;
+ }
+
+@@ -277,7 +310,8 @@ int xenbus_dev_probe(struct device *_dev
+
+ err = watch_otherend(dev);
+ if (err) {
+- dev_warn(&dev->dev, "watch_otherend on %s failed.\n",
++ printk(KERN_WARNING
++ "xenbus_probe: watch_otherend on %s failed.\n",
+ dev->nodename);
+ return err;
+ }
+@@ -313,43 +347,55 @@ static void xenbus_dev_shutdown(struct d
+
+ DPRINTK("%s", dev->nodename);
+
++ if (is_initial_xendomain())
++ return;
++
+ get_device(&dev->dev);
+ if (dev->state != XenbusStateConnected) {
+- printk(KERN_INFO "%s: %s: %s != Connected, skipping\n", __func__,
++ printk("%s: %s: %s != Connected, skipping\n", __FUNCTION__,
+ dev->nodename, xenbus_strstate(dev->state));
+ goto out;
+ }
+ xenbus_switch_state(dev, XenbusStateClosing);
+ timeout = wait_for_completion_timeout(&dev->down, timeout);
+ if (!timeout)
+- printk(KERN_INFO "%s: %s timeout closing device\n",
+- __func__, dev->nodename);
++ printk("%s: %s timeout closing device\n", __FUNCTION__, dev->nodename);
+ out:
+ put_device(&dev->dev);
+ }
+
+ int xenbus_register_driver_common(struct xenbus_driver *drv,
+- struct xen_bus_type *bus,
+- struct module *owner,
+- const char *mod_name)
++ struct xen_bus_type *bus)
+ {
++ int ret;
++
++ if (bus->error)
++ return bus->error;
++
+ drv->driver.name = drv->name;
+ drv->driver.bus = &bus->bus;
+- drv->driver.owner = owner;
+- drv->driver.mod_name = mod_name;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
++ drv->driver.owner = drv->owner;
++#endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
++ drv->driver.probe = xenbus_dev_probe;
++ drv->driver.remove = xenbus_dev_remove;
++ drv->driver.shutdown = xenbus_dev_shutdown;
++#endif
+
+- return driver_register(&drv->driver);
++ mutex_lock(&xenwatch_mutex);
++ ret = driver_register(&drv->driver);
++ mutex_unlock(&xenwatch_mutex);
++ return ret;
+ }
+
+-int __xenbus_register_frontend(struct xenbus_driver *drv,
+- struct module *owner, const char *mod_name)
++int xenbus_register_frontend(struct xenbus_driver *drv)
+ {
+ int ret;
+
+ drv->read_otherend_details = read_backend_details;
+
+- ret = xenbus_register_driver_common(drv, &xenbus_frontend,
+- owner, mod_name);
++ ret = xenbus_register_driver_common(drv, &xenbus_frontend);
+ if (ret)
+ return ret;
+
+@@ -358,7 +404,7 @@ int __xenbus_register_frontend(struct xe
+
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(__xenbus_register_frontend);
++EXPORT_SYMBOL_GPL(xenbus_register_frontend);
+
+ void xenbus_unregister_driver(struct xenbus_driver *drv)
+ {
+@@ -436,25 +482,25 @@ static void xenbus_dev_release(struct de
+ }
+
+ static ssize_t xendev_show_nodename(struct device *dev,
+- struct device_attribute *attr, char *buf)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
++ struct device_attribute *attr,
++#endif
++ char *buf)
+ {
+ return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
+ }
+ DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
+
+ static ssize_t xendev_show_devtype(struct device *dev,
+- struct device_attribute *attr, char *buf)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
++ struct device_attribute *attr,
++#endif
++ char *buf)
+ {
+ return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
+ }
+ DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
+
+-static ssize_t xendev_show_modalias(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype);
+-}
+-DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
+
+ int xenbus_probe_node(struct xen_bus_type *bus,
+ const char *type,
+@@ -467,6 +513,9 @@ int xenbus_probe_node(struct xen_bus_typ
+
+ enum xenbus_state state = xenbus_read_driver_state(nodename);
+
++ if (bus->error)
++ return bus->error;
++
+ if (state != XenbusStateInitialising) {
+ /* Device is not new, so ignore it. This can happen if a
+ device is going away after switching to Closed. */
+@@ -491,6 +540,7 @@ int xenbus_probe_node(struct xen_bus_typ
+ xendev->devicetype = tmpstring;
+ init_completion(&xendev->down);
+
++ xendev->dev.parent = &bus->dev;
+ xendev->dev.bus = &bus->bus;
+ xendev->dev.release = xenbus_dev_release;
+
+@@ -505,22 +555,15 @@ int xenbus_probe_node(struct xen_bus_typ
+
+ err = device_create_file(&xendev->dev, &dev_attr_nodename);
+ if (err)
+- goto fail_unregister;
+-
++ goto unregister;
+ err = device_create_file(&xendev->dev, &dev_attr_devtype);
+ if (err)
+- goto fail_remove_nodename;
+-
+- err = device_create_file(&xendev->dev, &dev_attr_modalias);
+- if (err)
+- goto fail_remove_devtype;
++ goto unregister;
+
+ return 0;
+-fail_remove_devtype:
+- device_remove_file(&xendev->dev, &dev_attr_devtype);
+-fail_remove_nodename:
++unregister:
+ device_remove_file(&xendev->dev, &dev_attr_nodename);
+-fail_unregister:
++ device_remove_file(&xendev->dev, &dev_attr_devtype);
+ device_unregister(&xendev->dev);
+ fail:
+ kfree(xendev);
+@@ -533,8 +576,7 @@ static int xenbus_probe_frontend(const c
+ char *nodename;
+ int err;
+
+- nodename = kasprintf(GFP_KERNEL, "%s/%s/%s",
+- xenbus_frontend.root, type, name);
++ nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_frontend.root, type, name);
+ if (!nodename)
+ return -ENOMEM;
+
+@@ -571,6 +613,9 @@ int xenbus_probe_devices(struct xen_bus_
+ char **dir;
+ unsigned int i, dir_n;
+
++ if (bus->error)
++ return bus->error;
++
+ dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
+ if (IS_ERR(dir))
+ return PTR_ERR(dir);
+@@ -607,15 +652,15 @@ static int strsep_len(const char *str, c
+ return (len == 0) ? i : -ERANGE;
+ }
+
+-void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
++void dev_changed(const char *node, struct xen_bus_type *bus)
+ {
+ int exists, rootlen;
+ struct xenbus_device *dev;
+ char type[BUS_ID_SIZE];
+ const char *p, *root;
+
+- if (char_count(node, '/') < 2)
+- return;
++ if (bus->error || char_count(node, '/') < 2)
++ return;
+
+ exists = xenbus_exists(XBT_NIL, node, "");
+ if (!exists) {
+@@ -649,7 +694,7 @@ static void frontend_changed(struct xenb
+ {
+ DPRINTK("");
+
+- xenbus_dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
++ dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
+ }
+
+ /* We watch for devices appearing and vanishing. */
+@@ -748,7 +793,8 @@ void xenbus_suspend(void)
+ {
+ DPRINTK("");
+
+- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
++ if (!xenbus_frontend.error)
++ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
+ xenbus_backend_suspend(suspend_dev);
+ xs_suspend();
+ }
+@@ -758,7 +804,8 @@ void xenbus_resume(void)
+ {
+ xb_init_comms();
+ xs_resume();
+- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
++ if (!xenbus_frontend.error)
++ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
+ xenbus_backend_resume(resume_dev);
+ }
+ EXPORT_SYMBOL_GPL(xenbus_resume);
+@@ -766,7 +813,8 @@ EXPORT_SYMBOL_GPL(xenbus_resume);
+ void xenbus_suspend_cancel(void)
+ {
+ xs_suspend_cancel();
+- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
++ if (!xenbus_frontend.error)
++ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
+ xenbus_backend_resume(suspend_cancel_dev);
+ }
+ EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
+@@ -794,7 +842,8 @@ void unregister_xenstore_notifier(struct
+ }
+ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
+
+-void xenbus_probe(struct work_struct *unused)
++
++void xenbus_probe(void *unused)
+ {
+ BUG_ON((xenstored_ready <= 0));
+
+@@ -807,63 +856,171 @@ void xenbus_probe(struct work_struct *un
+ blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
+ }
+
+-static int __init xenbus_probe_init(void)
++
++#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST)
++static struct file_operations xsd_kva_fops;
++static struct proc_dir_entry *xsd_kva_intf;
++static struct proc_dir_entry *xsd_port_intf;
++
++static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ size_t size = vma->vm_end - vma->vm_start;
++
++ if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
++ return -EINVAL;
++
++ if (remap_pfn_range(vma, vma->vm_start, mfn_to_pfn(xen_store_mfn),
++ size, vma->vm_page_prot))
++ return -EAGAIN;
++
++ return 0;
++}
++
++static int xsd_kva_read(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ int len;
++
++ len = sprintf(page, "0x%p", xen_store_interface);
++ *eof = 1;
++ return len;
++}
++
++static int xsd_port_read(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ int len;
++
++ len = sprintf(page, "%d", xen_store_evtchn);
++ *eof = 1;
++ return len;
++}
++#endif
++
++static int xenbus_probe_init(void)
+ {
+ int err = 0;
++ unsigned long page = 0;
+
+ DPRINTK("");
+
+- err = -ENODEV;
+ if (!is_running_on_xen())
+- goto out_error;
++ return -ENODEV;
+
+ /* Register ourselves with the kernel bus subsystem */
+- err = bus_register(&xenbus_frontend.bus);
+- if (err)
+- goto out_error;
+-
+- err = xenbus_backend_bus_register();
+- if (err)
+- goto out_unreg_front;
++ xenbus_frontend.error = bus_register(&xenbus_frontend.bus);
++ if (xenbus_frontend.error)
++ printk(KERN_WARNING
++ "XENBUS: Error registering frontend bus: %i\n",
++ xenbus_frontend.error);
++ xenbus_backend_bus_register();
+
+ /*
+ * Domain0 doesn't have a store_evtchn or store_mfn yet.
+ */
+ if (is_initial_xendomain()) {
+- /* dom0 not yet supported */
++ struct evtchn_alloc_unbound alloc_unbound;
++
++ /* Allocate page. */
++ page = get_zeroed_page(GFP_KERNEL);
++ if (!page)
++ return -ENOMEM;
++
++ xen_store_mfn = xen_start_info->store_mfn =
++ pfn_to_mfn(virt_to_phys((void *)page) >>
++ PAGE_SHIFT);
++
++ /* Next allocate a local port which xenstored can bind to */
++ alloc_unbound.dom = DOMID_SELF;
++ alloc_unbound.remote_dom = 0;
++
++ err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
++ &alloc_unbound);
++ if (err == -ENOSYS)
++ goto err;
++ BUG_ON(err);
++ xen_store_evtchn = xen_start_info->store_evtchn =
++ alloc_unbound.port;
++
++#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST)
++ /* And finally publish the above info in /proc/xen */
++ xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
++ if (xsd_kva_intf) {
++ memcpy(&xsd_kva_fops, xsd_kva_intf->proc_fops,
++ sizeof(xsd_kva_fops));
++ xsd_kva_fops.mmap = xsd_kva_mmap;
++ xsd_kva_intf->proc_fops = &xsd_kva_fops;
++ xsd_kva_intf->read_proc = xsd_kva_read;
++ }
++ xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
++ if (xsd_port_intf)
++ xsd_port_intf->read_proc = xsd_port_read;
++#endif
++ xen_store_interface = mfn_to_virt(xen_store_mfn);
+ } else {
+ xenstored_ready = 1;
++#ifdef CONFIG_XEN
+ xen_store_evtchn = xen_start_info->store_evtchn;
+ xen_store_mfn = xen_start_info->store_mfn;
++ xen_store_interface = mfn_to_virt(xen_store_mfn);
++#else
++ xen_store_evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN);
++ xen_store_mfn = hvm_get_parameter(HVM_PARAM_STORE_PFN);
++ xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT,
++ PAGE_SIZE);
++#endif
+ }
+- xen_store_interface = mfn_to_virt(xen_store_mfn);
++
++
++ xenbus_dev_init();
+
+ /* Initialize the interface to xenstore. */
+ err = xs_init();
+ if (err) {
+ printk(KERN_WARNING
+ "XENBUS: Error initializing xenstore comms: %i\n", err);
+- goto out_unreg_back;
++ goto err;
+ }
+
++ /* Register ourselves with the kernel device subsystem */
++ if (!xenbus_frontend.error) {
++ xenbus_frontend.error = device_register(&xenbus_frontend.dev);
++ if (xenbus_frontend.error) {
++ bus_unregister(&xenbus_frontend.bus);
++ printk(KERN_WARNING
++ "XENBUS: Error registering frontend device: %i\n",
++ xenbus_frontend.error);
++ }
++ }
++ xenbus_backend_device_register();
++
+ if (!is_initial_xendomain())
+ xenbus_probe(NULL);
+
+ return 0;
+
+- out_unreg_back:
+- xenbus_backend_bus_unregister();
++ err:
++ if (page)
++ free_page(page);
+
+- out_unreg_front:
+- bus_unregister(&xenbus_frontend.bus);
++ /*
++ * Do not unregister the xenbus front/backend buses here. The buses
++ * must exist because front/backend drivers will use them when they are
++ * registered.
++ */
+
+- out_error:
+ return err;
+ }
+
++#ifdef CONFIG_XEN
+ postcore_initcall(xenbus_probe_init);
+-
+-MODULE_LICENSE("GPL");
++MODULE_LICENSE("Dual BSD/GPL");
++#else
++int xenbus_init(void)
++{
++ return xenbus_probe_init();
++}
++#endif
+
+ static int is_disconnected_device(struct device *dev, void *data)
+ {
+@@ -883,12 +1040,14 @@ static int is_disconnected_device(struct
+ return 0;
+
+ xendrv = to_xenbus_driver(dev->driver);
+- return (xendev->state != XenbusStateConnected ||
++ return (xendev->state < XenbusStateConnected ||
+ (xendrv->is_ready && !xendrv->is_ready(xendev)));
+ }
+
+ static int exists_disconnected_device(struct device_driver *drv)
+ {
++ if (xenbus_frontend.error)
++ return xenbus_frontend.error;
+ return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+ is_disconnected_device);
+ }
+@@ -897,6 +1056,7 @@ static int print_device_status(struct de
+ {
+ struct xenbus_device *xendev = to_xenbus_device(dev);
+ struct device_driver *drv = data;
++ struct xenbus_driver *xendrv;
+
+ /* Is this operation limited to a particular driver? */
+ if (drv && (dev->driver != drv))
+@@ -906,12 +1066,23 @@ static int print_device_status(struct de
+ /* Information only: is this too noisy? */
+ printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
+ xendev->nodename);
+- } else if (xendev->state != XenbusStateConnected) {
++ return 0;
++ }
++
++ if (xendev->state < XenbusStateConnected) {
++ enum xenbus_state rstate = XenbusStateUnknown;
++ if (xendev->otherend)
++ rstate = xenbus_read_driver_state(xendev->otherend);
+ printk(KERN_WARNING "XENBUS: Timeout connecting "
+- "to device: %s (state %d)\n",
+- xendev->nodename, xendev->state);
++ "to device: %s (local state %d, remote state %d)\n",
++ xendev->nodename, xendev->state, rstate);
+ }
+
++ xendrv = to_xenbus_driver(dev->driver);
++ if (xendrv->is_ready && !xendrv->is_ready(xendev))
++ printk(KERN_WARNING "XENBUS: Device not ready: %s\n",
++ xendev->nodename);
++
+ return 0;
+ }
+
+@@ -919,7 +1090,7 @@ static int print_device_status(struct de
+ static int ready_to_wait_for_devices;
+
+ /*
+- * On a 10 second timeout, wait for all devices currently configured. We need
++ * On a 5-minute timeout, wait for all devices currently configured. We need
+ * to do this to guarantee that the filesystems and / or network devices
+ * needed for boot are available, before we can allow the boot to proceed.
+ *
+@@ -934,18 +1105,30 @@ static int ready_to_wait_for_devices;
+ */
+ static void wait_for_devices(struct xenbus_driver *xendrv)
+ {
+- unsigned long timeout = jiffies + 10*HZ;
++ unsigned long start = jiffies;
+ struct device_driver *drv = xendrv ? &xendrv->driver : NULL;
++ unsigned int seconds_waited = 0;
+
+ if (!ready_to_wait_for_devices || !is_running_on_xen())
+ return;
+
+ while (exists_disconnected_device(drv)) {
+- if (time_after(jiffies, timeout))
+- break;
++ if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
++ if (!seconds_waited)
++ printk(KERN_WARNING "XENBUS: Waiting for "
++ "devices to initialise: ");
++ seconds_waited += 5;
++ printk("%us...", 300 - seconds_waited);
++ if (seconds_waited == 300)
++ break;
++ }
++
+ schedule_timeout_interruptible(HZ/10);
+ }
+
++ if (seconds_waited)
++ printk("\n");
++
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+ print_device_status);
+ }
+@@ -953,10 +1136,18 @@ static void wait_for_devices(struct xenb
+ #ifndef MODULE
+ static int __init boot_wait_for_devices(void)
+ {
+- ready_to_wait_for_devices = 1;
+- wait_for_devices(NULL);
++ if (!xenbus_frontend.error) {
++ ready_to_wait_for_devices = 1;
++ wait_for_devices(NULL);
++ }
+ return 0;
+ }
+
+ late_initcall(boot_wait_for_devices);
+ #endif
++
++int xenbus_for_each_frontend(void *arg, int (*fn)(struct device *, void *))
++{
++ return bus_for_each_dev(&xenbus_frontend.bus, NULL, arg, fn);
++}
++EXPORT_SYMBOL_GPL(xenbus_for_each_frontend);
+Index: head-2008-11-25/drivers/xen/xenbus/xenbus_probe.h
+===================================================================
+--- head-2008-11-25.orig/drivers/xen/xenbus/xenbus_probe.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/drivers/xen/xenbus/xenbus_probe.h 2008-11-25 12:35:56.000000000 +0100
+@@ -34,41 +34,42 @@
+ #ifndef _XENBUS_PROBE_H
+ #define _XENBUS_PROBE_H
+
+-#ifdef CONFIG_XEN_BACKEND
++#if defined(CONFIG_XEN_BACKEND) || defined(CONFIG_XEN_BACKEND_MODULE)
+ extern void xenbus_backend_suspend(int (*fn)(struct device *, void *));
+ extern void xenbus_backend_resume(int (*fn)(struct device *, void *));
+ extern void xenbus_backend_probe_and_watch(void);
+-extern int xenbus_backend_bus_register(void);
+-extern void xenbus_backend_bus_unregister(void);
++extern void xenbus_backend_bus_register(void);
++extern void xenbus_backend_device_register(void);
+ #else
+ static inline void xenbus_backend_suspend(int (*fn)(struct device *, void *)) {}
+ static inline void xenbus_backend_resume(int (*fn)(struct device *, void *)) {}
+ static inline void xenbus_backend_probe_and_watch(void) {}
+-static inline int xenbus_backend_bus_register(void) { return 0; }
+-static inline void xenbus_backend_bus_unregister(void) {}
++static inline void xenbus_backend_bus_register(void) {}
++static inline void xenbus_backend_device_register(void) {}
+ #endif
+
+ struct xen_bus_type
+ {
+ char *root;
++ int error;
+ unsigned int levels;
+ int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
+ int (*probe)(const char *type, const char *dir);
+ struct bus_type bus;
++ struct device dev;
+ };
+
+ extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
+ extern int xenbus_dev_probe(struct device *_dev);
+ extern int xenbus_dev_remove(struct device *_dev);
+ extern int xenbus_register_driver_common(struct xenbus_driver *drv,
+- struct xen_bus_type *bus,
+- struct module *owner,
+- const char *mod_name);
++ struct xen_bus_type *bus);
+ extern int xenbus_probe_node(struct xen_bus_type *bus,
+ const char *type,
+ const char *nodename);
+ extern int xenbus_probe_devices(struct xen_bus_type *bus);
+
+-extern void xenbus_dev_changed(const char *node, struct xen_bus_type *bus);
++extern void dev_changed(const char *node, struct xen_bus_type *bus);
+
+ #endif
++
+Index: head-2008-11-25/drivers/xen/xenbus/xenbus_xs.c
+===================================================================
+--- head-2008-11-25.orig/drivers/xen/xenbus/xenbus_xs.c 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/drivers/xen/xenbus/xenbus_xs.c 2008-11-25 12:35:56.000000000 +0100
+@@ -47,6 +47,14 @@
+ #include <xen/xenbus.h>
+ #include "xenbus_comms.h"
+
++#ifdef HAVE_XEN_PLATFORM_COMPAT_H
++#include <xen/platform-compat.h>
++#endif
++
++#ifndef PF_NOFREEZE /* Old kernel (pre-2.6.6). */
++#define PF_NOFREEZE 0
++#endif
++
+ struct xs_stored_msg {
+ struct list_head list;
+
+@@ -108,7 +116,7 @@ static DEFINE_SPINLOCK(watch_events_lock
+ * carrying out work.
+ */
+ static pid_t xenwatch_pid;
+-static DEFINE_MUTEX(xenwatch_mutex);
++/* static */ DEFINE_MUTEX(xenwatch_mutex);
+ static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq);
+
+ static int get_error(const char *errorstring)
+@@ -177,7 +185,7 @@ void *xenbus_dev_request_and_reply(struc
+
+ mutex_unlock(&xs_state.request_mutex);
+
+- if ((msg->type == XS_TRANSACTION_END) ||
++ if ((req_msg.type == XS_TRANSACTION_END) ||
+ ((req_msg.type == XS_TRANSACTION_START) &&
+ (msg->type == XS_ERROR)))
+ up_read(&xs_state.transaction_mutex);
+@@ -213,7 +221,7 @@ static void *xs_talkv(struct xenbus_tran
+ }
+
+ for (i = 0; i < num_vecs; i++) {
+- err = xb_write(iovec[i].iov_base, iovec[i].iov_len);
++ err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
+ if (err) {
+ mutex_unlock(&xs_state.request_mutex);
+ return ERR_PTR(err);
+@@ -294,7 +302,7 @@ static char **split(char *strings, unsig
+ char *p, **ret;
+
+ /* Count the strings. */
+- *num = count_strings(strings, len);
++ *num = count_strings(strings, len) + 1;
+
+ /* Transfer to one big alloc for easy freeing. */
+ ret = kmalloc(*num * sizeof(char *) + len, GFP_NOIO | __GFP_HIGH);
+@@ -308,6 +316,7 @@ static char **split(char *strings, unsig
+ strings = (char *)&ret[*num];
+ for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
+ ret[(*num)++] = p;
++ ret[*num] = strings + len;
+
+ return ret;
+ }
+@@ -498,7 +507,7 @@ int xenbus_printf(struct xenbus_transact
+ #define PRINTF_BUFFER_SIZE 4096
+ char *printf_buffer;
+
+- printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
++ printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_NOIO | __GFP_HIGH);
+ if (printf_buffer == NULL)
+ return -ENOMEM;
+
+@@ -621,6 +630,8 @@ void unregister_xenbus_watch(struct xenb
+ char token[sizeof(watch) * 2 + 1];
+ int err;
+
++ BUG_ON(watch->flags & XBWF_new_thread);
++
+ sprintf(token, "%lX", (long)watch);
+
+ down_read(&xs_state.watch_mutex);
+@@ -638,11 +649,6 @@ void unregister_xenbus_watch(struct xenb
+
+ up_read(&xs_state.watch_mutex);
+
+- /* Make sure there are no callbacks running currently (unless
+- its us) */
+- if (current->pid != xenwatch_pid)
+- mutex_lock(&xenwatch_mutex);
+-
+ /* Cancel pending watch events. */
+ spin_lock(&watch_events_lock);
+ list_for_each_entry_safe(msg, tmp, &watch_events, list) {
+@@ -654,8 +660,11 @@ void unregister_xenbus_watch(struct xenb
+ }
+ spin_unlock(&watch_events_lock);
+
+- if (current->pid != xenwatch_pid)
++ /* Flush any currently-executing callback, unless we are it. :-) */
++ if (current->pid != xenwatch_pid) {
++ mutex_lock(&xenwatch_mutex);
+ mutex_unlock(&xenwatch_mutex);
++ }
+ }
+ EXPORT_SYMBOL_GPL(unregister_xenbus_watch);
+
+@@ -693,11 +702,30 @@ void xs_suspend_cancel(void)
+ up_write(&xs_state.transaction_mutex);
+ }
+
++static int xenwatch_handle_callback(void *data)
++{
++ struct xs_stored_msg *msg = data;
++
++ msg->u.watch.handle->callback(msg->u.watch.handle,
++ (const char **)msg->u.watch.vec,
++ msg->u.watch.vec_size);
++
++ kfree(msg->u.watch.vec);
++ kfree(msg);
++
++ /* Kill this kthread if we were spawned just for this callback. */
++ if (current->pid != xenwatch_pid)
++ do_exit(0);
++
++ return 0;
++}
++
+ static int xenwatch_thread(void *unused)
+ {
+ struct list_head *ent;
+ struct xs_stored_msg *msg;
+
++ current->flags |= PF_NOFREEZE;
+ for (;;) {
+ wait_event_interruptible(watch_events_waitq,
+ !list_empty(&watch_events));
+@@ -713,17 +741,29 @@ static int xenwatch_thread(void *unused)
+ list_del(ent);
+ spin_unlock(&watch_events_lock);
+
+- if (ent != &watch_events) {
+- msg = list_entry(ent, struct xs_stored_msg, list);
+- msg->u.watch.handle->callback(
+- msg->u.watch.handle,
+- (const char **)msg->u.watch.vec,
+- msg->u.watch.vec_size);
+- kfree(msg->u.watch.vec);
+- kfree(msg);
++ if (ent == &watch_events) {
++ mutex_unlock(&xenwatch_mutex);
++ continue;
+ }
+
+- mutex_unlock(&xenwatch_mutex);
++ msg = list_entry(ent, struct xs_stored_msg, list);
++
++ /*
++ * Unlock the mutex before running an XBWF_new_thread
++ * handler. kthread_run can block which can deadlock
++ * against unregister_xenbus_watch() if we need to
++ * unregister other watches in order to make
++ * progress. This can occur on resume before the swap
++ * device is attached.
++ */
++ if (msg->u.watch.handle->flags & XBWF_new_thread) {
++ mutex_unlock(&xenwatch_mutex);
++ kthread_run(xenwatch_handle_callback,
++ msg, "xenwatch_cb");
++ } else {
++ xenwatch_handle_callback(msg);
++ mutex_unlock(&xenwatch_mutex);
++ }
+ }
+
+ return 0;
+@@ -817,6 +857,7 @@ static int xenbus_thread(void *unused)
+ {
+ int err;
+
++ current->flags |= PF_NOFREEZE;
+ for (;;) {
+ err = process_msg();
+ if (err)
+Index: head-2008-11-25/include/xen/balloon.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/balloon.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/balloon.h 2008-11-25 12:35:56.000000000 +0100
+@@ -31,12 +31,9 @@
+ * IN THE SOFTWARE.
+ */
+
+-#ifndef __XEN_BALLOON_H__
+-#define __XEN_BALLOON_H__
++#ifndef __ASM_BALLOON_H__
++#define __ASM_BALLOON_H__
+
+-#include <linux/spinlock.h>
+-
+-#if 0
+ /*
+ * Inform the balloon driver that it should allow some slop for device-driver
+ * memory activities.
+@@ -56,6 +53,5 @@ void balloon_release_driver_page(struct
+ extern spinlock_t balloon_lock;
+ #define balloon_lock(__flags) spin_lock_irqsave(&balloon_lock, __flags)
+ #define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)
+-#endif
+
+-#endif /* __XEN_BALLOON_H__ */
++#endif /* __ASM_BALLOON_H__ */
+Index: head-2008-11-25/include/xen/interface/callback.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/callback.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/callback.h 2008-11-25 12:35:56.000000000 +0100
+@@ -86,6 +86,8 @@ struct callback_register {
+ uint16_t flags;
+ xen_callback_t address;
+ };
++typedef struct callback_register callback_register_t;
++DEFINE_XEN_GUEST_HANDLE(callback_register_t);
+
+ /*
+ * Unregister a callback.
+@@ -98,5 +100,22 @@ struct callback_unregister {
+ uint16_t type;
+ uint16_t _unused;
+ };
++typedef struct callback_unregister callback_unregister_t;
++DEFINE_XEN_GUEST_HANDLE(callback_unregister_t);
++
++#if __XEN_INTERFACE_VERSION__ < 0x00030207
++#undef CALLBACKTYPE_sysenter
++#define CALLBACKTYPE_sysenter CALLBACKTYPE_sysenter_deprecated
++#endif
+
+ #endif /* __XEN_PUBLIC_CALLBACK_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/elfnote.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/elfnote.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/elfnote.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Definitions used for the Xen ELF notes.
+ *
++ * 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.
++ *
+ * Copyright (c) 2006, Ian Campbell, XenSource Ltd.
+ */
+
+@@ -10,7 +28,7 @@
+ #define __XEN_PUBLIC_ELFNOTE_H__
+
+ /*
+- * The notes should live in a SHT_NOTE segment and have "Xen" in the
++ * The notes should live in a PT_NOTE segment and have "Xen" in the
+ * name field.
+ *
+ * Numeric types are either 4 or 8 bytes depending on the content of
+@@ -22,8 +40,6 @@
+
+ /*
+ * NAME=VALUE pair (string).
+- *
+- * LEGACY: FEATURES and PAE
+ */
+ #define XEN_ELFNOTE_INFO 0
+
+@@ -90,7 +106,12 @@
+ #define XEN_ELFNOTE_LOADER 8
+
+ /*
+- * The kernel supports PAE (x86/32 only, string = "yes" or "no").
++ * The kernel supports PAE (x86/32 only, string = "yes", "no" or
++ * "bimodal").
++ *
++ * For compatibility with Xen 3.0.3 and earlier the "bimodal" setting
++ * may be given as "yes,bimodal" which will cause older Xen to treat
++ * this kernel as PAE.
+ *
+ * LEGACY: PAE (n.b. The legacy interface included a provision to
+ * indicate 'extended-cr3' support allowing L3 page tables to be
+@@ -140,6 +161,65 @@
+ */
+ #define XEN_ELFNOTE_SUSPEND_CANCEL 14
+
++/*
++ * The number of the highest elfnote defined.
++ */
++#define XEN_ELFNOTE_MAX XEN_ELFNOTE_SUSPEND_CANCEL
++
++/*
++ * System information exported through crash notes.
++ *
++ * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO
++ * note in case of a system crash. This note will contain various
++ * information about the system, see xen/include/xen/elfcore.h.
++ */
++#define XEN_ELFNOTE_CRASH_INFO 0x1000001
++
++/*
++ * System registers exported through crash notes.
++ *
++ * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_REGS
++ * note per cpu in case of a system crash. This note is architecture
++ * specific and will contain registers not saved in the "CORE" note.
++ * See xen/include/xen/elfcore.h for more information.
++ */
++#define XEN_ELFNOTE_CRASH_REGS 0x1000002
++
++
++/*
++ * xen dump-core none note.
++ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_NONE
++ * in its dump file to indicate that the file is xen dump-core
++ * file. This note doesn't have any other information.
++ * See tools/libxc/xc_core.h for more information.
++ */
++#define XEN_ELFNOTE_DUMPCORE_NONE 0x2000000
++
++/*
++ * xen dump-core header note.
++ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_HEADER
++ * in its dump file.
++ * See tools/libxc/xc_core.h for more information.
++ */
++#define XEN_ELFNOTE_DUMPCORE_HEADER 0x2000001
++
++/*
++ * xen dump-core xen version note.
++ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_XEN_VERSION
++ * in its dump file. It contains the xen version obtained via the
++ * XENVER hypercall.
++ * See tools/libxc/xc_core.h for more information.
++ */
++#define XEN_ELFNOTE_DUMPCORE_XEN_VERSION 0x2000002
++
++/*
++ * xen dump-core format version note.
++ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION
++ * in its dump file. It contains a format version identifier.
++ * See tools/libxc/xc_core.h for more information.
++ */
++#define XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION 0x2000003
++
+ #endif /* __XEN_PUBLIC_ELFNOTE_H__ */
+
+ /*
+Index: head-2008-11-25/include/xen/interface/event_channel.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/event_channel.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/event_channel.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,14 +3,39 @@
+ *
+ * Event channels between domains.
+ *
++ * 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.
++ *
+ * Copyright (c) 2003-2004, K A Fraser.
+ */
+
+ #ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
+ #define __XEN_PUBLIC_EVENT_CHANNEL_H__
+
++/*
++ * Prototype for this hypercall is:
++ * int event_channel_op(int cmd, void *args)
++ * @cmd == EVTCHNOP_??? (event-channel operation).
++ * @args == Operation-specific extra arguments (NULL if none).
++ */
++
+ typedef uint32_t evtchn_port_t;
+-DEFINE_GUEST_HANDLE(evtchn_port_t);
++DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
+
+ /*
+ * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
+@@ -20,13 +45,14 @@ DEFINE_GUEST_HANDLE(evtchn_port_t);
+ * 1. If the caller is unprivileged then <dom> must be DOMID_SELF.
+ * 2. <rdom> may be DOMID_SELF, allowing loopback connections.
+ */
+-#define EVTCHNOP_alloc_unbound 6
++#define EVTCHNOP_alloc_unbound 6
+ struct evtchn_alloc_unbound {
+- /* IN parameters */
+- domid_t dom, remote_dom;
+- /* OUT parameters */
+- evtchn_port_t port;
++ /* IN parameters */
++ domid_t dom, remote_dom;
++ /* OUT parameters */
++ evtchn_port_t port;
+ };
++typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t;
+
+ /*
+ * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between
+@@ -39,29 +65,35 @@ struct evtchn_alloc_unbound {
+ */
+ #define EVTCHNOP_bind_interdomain 0
+ struct evtchn_bind_interdomain {
+- /* IN parameters. */
+- domid_t remote_dom;
+- evtchn_port_t remote_port;
+- /* OUT parameters. */
+- evtchn_port_t local_port;
++ /* IN parameters. */
++ domid_t remote_dom;
++ evtchn_port_t remote_port;
++ /* OUT parameters. */
++ evtchn_port_t local_port;
+ };
++typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t;
+
+ /*
+ * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
+ * vcpu.
+ * NOTES:
+- * 1. A virtual IRQ may be bound to at most one event channel per vcpu.
+- * 2. The allocated event channel is bound to the specified vcpu. The binding
+- * may not be changed.
++ * 1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list
++ * in xen.h for the classification of each VIRQ.
++ * 2. Global VIRQs must be allocated on VCPU0 but can subsequently be
++ * re-bound via EVTCHNOP_bind_vcpu.
++ * 3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu.
++ * The allocated event channel is bound to the specified vcpu and the
++ * binding cannot be changed.
+ */
+-#define EVTCHNOP_bind_virq 1
++#define EVTCHNOP_bind_virq 1
+ struct evtchn_bind_virq {
+- /* IN parameters. */
+- uint32_t virq;
+- uint32_t vcpu;
+- /* OUT parameters. */
+- evtchn_port_t port;
++ /* IN parameters. */
++ uint32_t virq;
++ uint32_t vcpu;
++ /* OUT parameters. */
++ evtchn_port_t port;
+ };
++typedef struct evtchn_bind_virq evtchn_bind_virq_t;
+
+ /*
+ * EVTCHNOP_bind_pirq: Bind a local event channel to PIRQ <irq>.
+@@ -69,15 +101,16 @@ struct evtchn_bind_virq {
+ * 1. A physical IRQ may be bound to at most one event channel per domain.
+ * 2. Only a sufficiently-privileged domain may bind to a physical IRQ.
+ */
+-#define EVTCHNOP_bind_pirq 2
++#define EVTCHNOP_bind_pirq 2
+ struct evtchn_bind_pirq {
+- /* IN parameters. */
+- uint32_t pirq;
++ /* IN parameters. */
++ uint32_t pirq;
+ #define BIND_PIRQ__WILL_SHARE 1
+- uint32_t flags; /* BIND_PIRQ__* */
+- /* OUT parameters. */
+- evtchn_port_t port;
++ uint32_t flags; /* BIND_PIRQ__* */
++ /* OUT parameters. */
++ evtchn_port_t port;
+ };
++typedef struct evtchn_bind_pirq evtchn_bind_pirq_t;
+
+ /*
+ * EVTCHNOP_bind_ipi: Bind a local event channel to receive events.
+@@ -85,33 +118,36 @@ struct evtchn_bind_pirq {
+ * 1. The allocated event channel is bound to the specified vcpu. The binding
+ * may not be changed.
+ */
+-#define EVTCHNOP_bind_ipi 7
++#define EVTCHNOP_bind_ipi 7
+ struct evtchn_bind_ipi {
+- uint32_t vcpu;
+- /* OUT parameters. */
+- evtchn_port_t port;
++ uint32_t vcpu;
++ /* OUT parameters. */
++ evtchn_port_t port;
+ };
++typedef struct evtchn_bind_ipi evtchn_bind_ipi_t;
+
+ /*
+ * EVTCHNOP_close: Close a local event channel <port>. If the channel is
+ * interdomain then the remote end is placed in the unbound state
+ * (EVTCHNSTAT_unbound), awaiting a new connection.
+ */
+-#define EVTCHNOP_close 3
++#define EVTCHNOP_close 3
+ struct evtchn_close {
+- /* IN parameters. */
+- evtchn_port_t port;
++ /* IN parameters. */
++ evtchn_port_t port;
+ };
++typedef struct evtchn_close evtchn_close_t;
+
+ /*
+ * EVTCHNOP_send: Send an event to the remote end of the channel whose local
+ * endpoint is <port>.
+ */
+-#define EVTCHNOP_send 4
++#define EVTCHNOP_send 4
+ struct evtchn_send {
+- /* IN parameters. */
+- evtchn_port_t port;
++ /* IN parameters. */
++ evtchn_port_t port;
+ };
++typedef struct evtchn_send evtchn_send_t;
+
+ /*
+ * EVTCHNOP_status: Get the current status of the communication channel which
+@@ -121,75 +157,108 @@ struct evtchn_send {
+ * 2. Only a sufficiently-privileged domain may obtain the status of an event
+ * channel for which <dom> is not DOMID_SELF.
+ */
+-#define EVTCHNOP_status 5
++#define EVTCHNOP_status 5
+ struct evtchn_status {
+- /* IN parameters */
+- domid_t dom;
+- evtchn_port_t port;
+- /* OUT parameters */
+-#define EVTCHNSTAT_closed 0 /* Channel is not in use. */
+-#define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/
+-#define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domain. */
+-#define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */
+-#define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */
+-#define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */
+- uint32_t status;
+- uint32_t vcpu; /* VCPU to which this channel is bound. */
+- union {
+- struct {
+- domid_t dom;
+- } unbound; /* EVTCHNSTAT_unbound */
+- struct {
+- domid_t dom;
+- evtchn_port_t port;
+- } interdomain; /* EVTCHNSTAT_interdomain */
+- uint32_t pirq; /* EVTCHNSTAT_pirq */
+- uint32_t virq; /* EVTCHNSTAT_virq */
+- } u;
++ /* IN parameters */
++ domid_t dom;
++ evtchn_port_t port;
++ /* OUT parameters */
++#define EVTCHNSTAT_closed 0 /* Channel is not in use. */
++#define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/
++#define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domain. */
++#define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */
++#define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */
++#define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */
++ uint32_t status;
++ uint32_t vcpu; /* VCPU to which this channel is bound. */
++ union {
++ struct {
++ domid_t dom;
++ } unbound; /* EVTCHNSTAT_unbound */
++ struct {
++ domid_t dom;
++ evtchn_port_t port;
++ } interdomain; /* EVTCHNSTAT_interdomain */
++ uint32_t pirq; /* EVTCHNSTAT_pirq */
++ uint32_t virq; /* EVTCHNSTAT_virq */
++ } u;
+ };
++typedef struct evtchn_status evtchn_status_t;
+
+ /*
+ * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
+ * event is pending.
+ * NOTES:
+- * 1. IPI- and VIRQ-bound channels always notify the vcpu that initialised
+- * the binding. This binding cannot be changed.
+- * 2. All other channels notify vcpu0 by default. This default is set when
++ * 1. IPI-bound channels always notify the vcpu specified at bind time.
++ * This binding cannot be changed.
++ * 2. Per-VCPU VIRQ channels always notify the vcpu specified at bind time.
++ * This binding cannot be changed.
++ * 3. All other channels notify vcpu0 by default. This default is set when
+ * the channel is allocated (a port that is freed and subsequently reused
+ * has its binding reset to vcpu0).
+ */
+-#define EVTCHNOP_bind_vcpu 8
++#define EVTCHNOP_bind_vcpu 8
+ struct evtchn_bind_vcpu {
+- /* IN parameters. */
+- evtchn_port_t port;
+- uint32_t vcpu;
++ /* IN parameters. */
++ evtchn_port_t port;
++ uint32_t vcpu;
+ };
++typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t;
+
+ /*
+ * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver
+ * a notification to the appropriate VCPU if an event is pending.
+ */
+-#define EVTCHNOP_unmask 9
++#define EVTCHNOP_unmask 9
+ struct evtchn_unmask {
+- /* IN parameters. */
+- evtchn_port_t port;
++ /* IN parameters. */
++ evtchn_port_t port;
++};
++typedef struct evtchn_unmask evtchn_unmask_t;
++
++/*
++ * EVTCHNOP_reset: Close all event channels associated with specified domain.
++ * NOTES:
++ * 1. <dom> may be specified as DOMID_SELF.
++ * 2. Only a sufficiently-privileged domain may specify other than DOMID_SELF.
++ */
++#define EVTCHNOP_reset 10
++struct evtchn_reset {
++ /* IN parameters. */
++ domid_t dom;
+ };
++typedef struct evtchn_reset evtchn_reset_t;
+
++/*
++ * Argument to event_channel_op_compat() hypercall. Superceded by new
++ * event_channel_op() hypercall since 0x00030202.
++ */
+ struct evtchn_op {
+- uint32_t cmd; /* EVTCHNOP_* */
+- union {
+- struct evtchn_alloc_unbound alloc_unbound;
+- struct evtchn_bind_interdomain bind_interdomain;
+- struct evtchn_bind_virq bind_virq;
+- struct evtchn_bind_pirq bind_pirq;
+- struct evtchn_bind_ipi bind_ipi;
+- struct evtchn_close close;
+- struct evtchn_send send;
+- struct evtchn_status status;
+- struct evtchn_bind_vcpu bind_vcpu;
+- struct evtchn_unmask unmask;
+- } u;
++ uint32_t cmd; /* EVTCHNOP_* */
++ union {
++ struct evtchn_alloc_unbound alloc_unbound;
++ struct evtchn_bind_interdomain bind_interdomain;
++ struct evtchn_bind_virq bind_virq;
++ struct evtchn_bind_pirq bind_pirq;
++ struct evtchn_bind_ipi bind_ipi;
++ struct evtchn_close close;
++ struct evtchn_send send;
++ struct evtchn_status status;
++ struct evtchn_bind_vcpu bind_vcpu;
++ struct evtchn_unmask unmask;
++ } u;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(evtchn_op);
++typedef struct evtchn_op evtchn_op_t;
++DEFINE_XEN_GUEST_HANDLE(evtchn_op_t);
+
+ #endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/features.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/features.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/features.h 2008-11-25 12:22:34.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Feature flags, reported by XENVER_get_features.
+ *
++ * 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.
++ *
+ * Copyright (c) 2006, Keir Fraser <keir@xensource.com>
+ */
+
+@@ -41,6 +59,25 @@
+ /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
+ #define XENFEAT_mmu_pt_update_preserve_ad 5
+
++/* x86: Does this Xen host support the MMU_{CLEAR,COPY}_PAGE hypercall? */
++#define XENFEAT_highmem_assist 6
++
++/*
++ * If set, GNTTABOP_map_grant_ref honors flags to be placed into guest kernel
++ * available pte bits.
++ */
++#define XENFEAT_gnttab_map_avail_bits 7
++
+ #define XENFEAT_NR_SUBMAPS 1
+
+ #endif /* __XEN_PUBLIC_FEATURES_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/grant_table.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/grant_table.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/grant_table.h 2008-11-25 12:22:34.000000000 +0100
+@@ -100,6 +100,7 @@ struct grant_entry {
+ */
+ uint32_t frame;
+ };
++typedef struct grant_entry grant_entry_t;
+
+ /*
+ * Type of grant entry.
+@@ -118,6 +119,7 @@ struct grant_entry {
+ * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
+ * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
+ * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
++ * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]
+ */
+ #define _GTF_readonly (2)
+ #define GTF_readonly (1U<<_GTF_readonly)
+@@ -125,6 +127,12 @@ struct grant_entry {
+ #define GTF_reading (1U<<_GTF_reading)
+ #define _GTF_writing (4)
+ #define GTF_writing (1U<<_GTF_writing)
++#define _GTF_PWT (5)
++#define GTF_PWT (1U<<_GTF_PWT)
++#define _GTF_PCD (6)
++#define GTF_PCD (1U<<_GTF_PCD)
++#define _GTF_PAT (7)
++#define GTF_PAT (1U<<_GTF_PAT)
+
+ /*
+ * Subflags for GTF_accept_transfer:
+@@ -185,7 +193,8 @@ struct gnttab_map_grant_ref {
+ grant_handle_t handle;
+ uint64_t dev_bus_addr;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(gnttab_map_grant_ref);
++typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);
+
+ /*
+ * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
+@@ -207,7 +216,8 @@ struct gnttab_unmap_grant_ref {
+ /* OUT parameters. */
+ int16_t status; /* GNTST_* */
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_grant_ref);
++typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);
+
+ /*
+ * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least
+@@ -225,9 +235,10 @@ struct gnttab_setup_table {
+ uint32_t nr_frames;
+ /* OUT parameters. */
+ int16_t status; /* GNTST_* */
+- GUEST_HANDLE(ulong) frame_list;
++ XEN_GUEST_HANDLE(ulong) frame_list;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table);
++typedef struct gnttab_setup_table gnttab_setup_table_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t);
+
+ /*
+ * GNTTABOP_dump_table: Dump the contents of the grant table to the
+@@ -240,7 +251,8 @@ struct gnttab_dump_table {
+ /* OUT parameters. */
+ int16_t status; /* GNTST_* */
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table);
++typedef struct gnttab_dump_table gnttab_dump_table_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t);
+
+ /*
+ * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
+@@ -253,13 +265,15 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_t
+ #define GNTTABOP_transfer 4
+ struct gnttab_transfer {
+ /* IN parameters. */
+- unsigned long mfn;
++ xen_pfn_t mfn;
+ domid_t domid;
+ grant_ref_t ref;
+ /* OUT parameters. */
+ int16_t status;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(gnttab_transfer);
++typedef struct gnttab_transfer gnttab_transfer_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t);
++
+
+ /*
+ * GNTTABOP_copy: Hypervisor based copy
+@@ -285,22 +299,22 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_transf
+ #define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref)
+
+ #define GNTTABOP_copy 5
+-struct gnttab_copy {
+- /* IN parameters. */
+- struct {
+- union {
+- grant_ref_t ref;
+- unsigned long gmfn;
+- } u;
+- domid_t domid;
+- uint16_t offset;
+- } source, dest;
+- uint16_t len;
+- uint16_t flags; /* GNTCOPY_* */
+- /* OUT parameters. */
+- int16_t status;
+-};
+-DEFINE_GUEST_HANDLE_STRUCT(gnttab_copy);
++typedef struct gnttab_copy {
++ /* IN parameters. */
++ struct {
++ union {
++ grant_ref_t ref;
++ xen_pfn_t gmfn;
++ } u;
++ domid_t domid;
++ uint16_t offset;
++ } source, dest;
++ uint16_t len;
++ uint16_t flags; /* GNTCOPY_* */
++ /* OUT parameters. */
++ int16_t status;
++} gnttab_copy_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_copy_t);
+
+ /*
+ * GNTTABOP_query_size: Query the current and maximum sizes of the shared
+@@ -318,10 +332,35 @@ struct gnttab_query_size {
+ uint32_t max_nr_frames;
+ int16_t status; /* GNTST_* */
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);
++typedef struct gnttab_query_size gnttab_query_size_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_query_size_t);
+
+ /*
+- * Bitfield values for update_pin_status.flags.
++ * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings
++ * tracked by <handle> but atomically replace the page table entry with one
++ * pointing to the machine address under <new_addr>. <new_addr> will be
++ * redirected to the null entry.
++ * NOTES:
++ * 1. The call may fail in an undefined manner if either mapping is not
++ * tracked by <handle>.
++ * 2. After executing a batch of unmaps, it is guaranteed that no stale
++ * mappings will remain in the device or host TLBs.
++ */
++#define GNTTABOP_unmap_and_replace 7
++struct gnttab_unmap_and_replace {
++ /* IN parameters. */
++ uint64_t host_addr;
++ uint64_t new_addr;
++ grant_handle_t handle;
++ /* OUT parameters. */
++ int16_t status; /* GNTST_* */
++};
++typedef struct gnttab_unmap_and_replace gnttab_unmap_and_replace_t;
++DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t);
++
++
++/*
++ * Bitfield values for gnttab_map_grant_ref.flags.
+ */
+ /* Map the grant entry for access by I/O devices. */
+ #define _GNTMAP_device_map (0)
+@@ -349,6 +388,13 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_
+ #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte)
+
+ /*
++ * Bits to be placed in guest kernel available PTE bits (architecture
++ * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).
++ */
++#define _GNTMAP_guest_avail0 (16)
++#define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0)
++
++/*
+ * Values for error status returns. All errors are -ve.
+ */
+ #define GNTST_okay (0) /* Normal return. */
+@@ -361,7 +407,8 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_
+ #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */
+ #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */
+ #define GNTST_bad_page (-9) /* Specified page was invalid for op. */
+-#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary */
++#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */
++#define GNTST_address_too_big (-11) /* transfer page address too large. */
+
+ #define GNTTABOP_error_msgs { \
+ "okay", \
+@@ -374,7 +421,18 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_
+ "no spare translation slot in the I/O MMU", \
+ "permission denied", \
+ "bad page", \
+- "copy arguments cross page boundary" \
++ "copy arguments cross page boundary", \
++ "page address size too large" \
+ }
+
+ #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/io/blkif.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/blkif.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/blkif.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Unified block-device I/O interface for Xen guest OSes.
+ *
++ * 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.
++ *
+ * Copyright (c) 2003-2004, Keir Fraser
+ */
+
+@@ -24,8 +42,10 @@
+ * rsp_event appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
+ */
+
+-typedef uint16_t blkif_vdev_t;
+-typedef uint64_t blkif_sector_t;
++#ifndef blkif_vdev_t
++#define blkif_vdev_t uint16_t
++#endif
++#define blkif_sector_t uint64_t
+
+ /*
+ * REQUEST CODES.
+@@ -34,7 +54,7 @@ typedef uint64_t blkif_sector_t;
+ #define BLKIF_OP_WRITE 1
+ /*
+ * Recognised only if "feature-barrier" is present in backend xenbus info.
+- * The "feature_barrier" node contains a boolean indicating whether barrier
++ * The "feature-barrier" node contains a boolean indicating whether barrier
+ * requests are likely to succeed or fail. Either way, a barrier request
+ * may fail at any time with BLKIF_RSP_EOPNOTSUPP if it is unsupported by
+ * the underlying block-device hardware. The boolean simply indicates whether
+@@ -43,33 +63,50 @@ typedef uint64_t blkif_sector_t;
+ * create the "feature-barrier" node!
+ */
+ #define BLKIF_OP_WRITE_BARRIER 2
++/*
++ * Recognised if "feature-flush-cache" is present in backend xenbus
++ * info. A flush will ask the underlying storage hardware to flush its
++ * non-volatile caches as appropriate. The "feature-flush-cache" node
++ * contains a boolean indicating whether flush requests are likely to
++ * succeed or fail. Either way, a flush request may fail at any time
++ * with BLKIF_RSP_EOPNOTSUPP if it is unsupported by the underlying
++ * block-device hardware. The boolean simply indicates whether or not it
++ * is worthwhile for the frontend to attempt flushes. If a backend does
++ * not recognise BLKIF_OP_WRITE_FLUSH_CACHE, it should *not* create the
++ * "feature-flush-cache" node!
++ */
++#define BLKIF_OP_FLUSH_DISKCACHE 3
+
+ /*
+ * Maximum scatter/gather segments per request.
+- * This is carefully chosen so that sizeof(struct blkif_ring) <= PAGE_SIZE.
++ * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
+ * NB. This could be 12 if the ring indexes weren't stored in the same page.
+ */
+ #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
+
++struct blkif_request_segment {
++ grant_ref_t gref; /* reference to I/O buffer frame */
++ /* @first_sect: first sector in frame to transfer (inclusive). */
++ /* @last_sect: last sector in frame to transfer (inclusive). */
++ uint8_t first_sect, last_sect;
++};
++
+ struct blkif_request {
+- uint8_t operation; /* BLKIF_OP_??? */
+- uint8_t nr_segments; /* number of segments */
+- blkif_vdev_t handle; /* only for read/write requests */
+- uint64_t id; /* private guest value, echoed in resp */
+- blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
+- struct blkif_request_segment {
+- grant_ref_t gref; /* reference to I/O buffer frame */
+- /* @first_sect: first sector in frame to transfer (inclusive). */
+- /* @last_sect: last sector in frame to transfer (inclusive). */
+- uint8_t first_sect, last_sect;
+- } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
++ uint8_t operation; /* BLKIF_OP_??? */
++ uint8_t nr_segments; /* number of segments */
++ blkif_vdev_t handle; /* only for read/write requests */
++ uint64_t id; /* private guest value, echoed in resp */
++ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
++ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+ };
++typedef struct blkif_request blkif_request_t;
+
+ struct blkif_response {
+- uint64_t id; /* copied from request */
+- uint8_t operation; /* copied from request */
+- int16_t status; /* BLKIF_RSP_??? */
++ uint64_t id; /* copied from request */
++ uint8_t operation; /* copied from request */
++ int16_t status; /* BLKIF_RSP_??? */
+ };
++typedef struct blkif_response blkif_response_t;
+
+ /*
+ * STATUS RETURN CODES.
+@@ -92,3 +129,13 @@ DEFINE_RING_TYPES(blkif, struct blkif_re
+ #define VDISK_READONLY 0x4
+
+ #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/io/console.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/console.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/console.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Console I/O interface for Xen guest OSes.
+ *
++ * 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.
++ *
+ * Copyright (c) 2005, Keir Fraser
+ */
+
+@@ -21,3 +39,13 @@ struct xencons_interface {
+ };
+
+ #endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/io/fbif.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/fbif.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/fbif.h 2008-11-25 12:35:56.000000000 +0100
+@@ -41,12 +41,13 @@
+ */
+ #define XENFB_TYPE_UPDATE 2
+
+-struct xenfb_update {
+- uint8_t type; /* XENFB_TYPE_UPDATE */
+- int32_t x; /* source x */
+- int32_t y; /* source y */
+- int32_t width; /* rect width */
+- int32_t height; /* rect height */
++struct xenfb_update
++{
++ uint8_t type; /* XENFB_TYPE_UPDATE */
++ int32_t x; /* source x */
++ int32_t y; /* source y */
++ int32_t width; /* rect width */
++ int32_t height; /* rect height */
+ };
+
+ /*
+@@ -55,36 +56,58 @@ struct xenfb_update {
+ */
+ #define XENFB_TYPE_RESIZE 3
+
+-struct xenfb_resize {
+- uint8_t type; /* XENFB_TYPE_RESIZE */
+- int32_t width; /* width in pixels */
+- int32_t height; /* height in pixels */
+- int32_t stride; /* stride in bytes */
+- int32_t depth; /* depth in bits */
+- int32_t offset; /* start offset within framebuffer */
++struct xenfb_resize
++{
++ uint8_t type; /* XENFB_TYPE_RESIZE */
++ int32_t width; /* width in pixels */
++ int32_t height; /* height in pixels */
++ int32_t stride; /* stride in bytes */
++ int32_t depth; /* depth in bits */
++ int32_t offset; /* offset of the framebuffer in bytes */
+ };
+
+ #define XENFB_OUT_EVENT_SIZE 40
+
+-union xenfb_out_event {
+- uint8_t type;
+- struct xenfb_update update;
+- struct xenfb_resize resize;
+- char pad[XENFB_OUT_EVENT_SIZE];
++union xenfb_out_event
++{
++ uint8_t type;
++ struct xenfb_update update;
++ struct xenfb_resize resize;
++ char pad[XENFB_OUT_EVENT_SIZE];
+ };
+
+ /* In events (backend -> frontend) */
+
+ /*
+ * Frontends should ignore unknown in events.
+- * No in events currently defined.
+ */
+
++/*
++ * Framebuffer refresh period advice
++ * Backend sends it to advise the frontend their preferred period of
++ * refresh. Frontends that keep the framebuffer constantly up-to-date
++ * just ignore it. Frontends that use the advice should immediately
++ * refresh the framebuffer (and send an update notification event if
++ * those have been requested), then use the update frequency to guide
++ * their periodical refreshs.
++ */
++#define XENFB_TYPE_REFRESH_PERIOD 1
++#define XENFB_NO_REFRESH 0
++
++struct xenfb_refresh_period
++{
++ uint8_t type; /* XENFB_TYPE_UPDATE_PERIOD */
++ uint32_t period; /* period of refresh, in ms,
++ * XENFB_NO_REFRESH if no refresh is needed */
++};
++
+ #define XENFB_IN_EVENT_SIZE 40
+
+-union xenfb_in_event {
+- uint8_t type;
+- char pad[XENFB_IN_EVENT_SIZE];
++union xenfb_in_event
++{
++ uint8_t type;
++ struct xenfb_refresh_period refresh_period;
++ char pad[XENFB_IN_EVENT_SIZE];
+ };
+
+ /* shared page */
+@@ -93,41 +116,41 @@ union xenfb_in_event {
+ #define XENFB_IN_RING_LEN (XENFB_IN_RING_SIZE / XENFB_IN_EVENT_SIZE)
+ #define XENFB_IN_RING_OFFS 1024
+ #define XENFB_IN_RING(page) \
+- ((union xenfb_in_event *)((char *)(page) + XENFB_IN_RING_OFFS))
++ ((union xenfb_in_event *)((char *)(page) + XENFB_IN_RING_OFFS))
+ #define XENFB_IN_RING_REF(page, idx) \
+- (XENFB_IN_RING((page))[(idx) % XENFB_IN_RING_LEN])
++ (XENFB_IN_RING((page))[(idx) % XENFB_IN_RING_LEN])
+
+ #define XENFB_OUT_RING_SIZE 2048
+ #define XENFB_OUT_RING_LEN (XENFB_OUT_RING_SIZE / XENFB_OUT_EVENT_SIZE)
+ #define XENFB_OUT_RING_OFFS (XENFB_IN_RING_OFFS + XENFB_IN_RING_SIZE)
+ #define XENFB_OUT_RING(page) \
+- ((union xenfb_out_event *)((char *)(page) + XENFB_OUT_RING_OFFS))
++ ((union xenfb_out_event *)((char *)(page) + XENFB_OUT_RING_OFFS))
+ #define XENFB_OUT_RING_REF(page, idx) \
+- (XENFB_OUT_RING((page))[(idx) % XENFB_OUT_RING_LEN])
++ (XENFB_OUT_RING((page))[(idx) % XENFB_OUT_RING_LEN])
+
+-struct xenfb_page {
+- uint32_t in_cons, in_prod;
+- uint32_t out_cons, out_prod;
+-
+- int32_t width; /* width of the framebuffer (in pixels) */
+- int32_t height; /* height of the framebuffer (in pixels) */
+- uint32_t line_length; /* length of a row of pixels (in bytes) */
+- uint32_t mem_length; /* length of the framebuffer (in bytes) */
+- uint8_t depth; /* depth of a pixel (in bits) */
+-
+- /*
+- * Framebuffer page directory
+- *
+- * Each directory page holds PAGE_SIZE / sizeof(*pd)
+- * framebuffer pages, and can thus map up to PAGE_SIZE *
+- * PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and
+- * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2
+- * Megs 64 bit. 256 directories give enough room for a 512
+- * Meg framebuffer with a max resolution of 12,800x10,240.
+- * Should be enough for a while with room leftover for
+- * expansion.
+- */
+- unsigned long pd[256];
++struct xenfb_page
++{
++ uint32_t in_cons, in_prod;
++ uint32_t out_cons, out_prod;
++
++ int32_t width; /* the width of the framebuffer (in pixels) */
++ int32_t height; /* the height of the framebuffer (in pixels) */
++ uint32_t line_length; /* the length of a row of pixels (in bytes) */
++ uint32_t mem_length; /* the length of the framebuffer (in bytes) */
++ uint8_t depth; /* the depth of a pixel (in bits) */
++
++ /*
++ * Framebuffer page directory
++ *
++ * Each directory page holds PAGE_SIZE / sizeof(*pd)
++ * framebuffer pages, and can thus map up to PAGE_SIZE *
++ * PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and
++ * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2 Megs
++ * 64 bit. 256 directories give enough room for a 512 Meg
++ * framebuffer with a max resolution of 12,800x10,240. Should
++ * be enough for a while with room leftover for expansion.
++ */
++ unsigned long pd[256];
+ };
+
+ /*
+@@ -141,3 +164,13 @@ struct xenfb_page {
+ #endif
+
+ #endif
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/io/kbdif.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/kbdif.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/kbdif.h 2008-11-25 12:35:56.000000000 +0100
+@@ -45,34 +45,38 @@
+ */
+ #define XENKBD_TYPE_POS 4
+
+-struct xenkbd_motion {
+- uint8_t type; /* XENKBD_TYPE_MOTION */
+- int32_t rel_x; /* relative X motion */
+- int32_t rel_y; /* relative Y motion */
+- int32_t rel_z; /* relative Z motion (wheel) */
+-};
+-
+-struct xenkbd_key {
+- uint8_t type; /* XENKBD_TYPE_KEY */
+- uint8_t pressed; /* 1 if pressed; 0 otherwise */
+- uint32_t keycode; /* KEY_* from linux/input.h */
+-};
+-
+-struct xenkbd_position {
+- uint8_t type; /* XENKBD_TYPE_POS */
+- int32_t abs_x; /* absolute X position (in FB pixels) */
+- int32_t abs_y; /* absolute Y position (in FB pixels) */
+- int32_t rel_z; /* relative Z motion (wheel) */
++struct xenkbd_motion
++{
++ uint8_t type; /* XENKBD_TYPE_MOTION */
++ int32_t rel_x; /* relative X motion */
++ int32_t rel_y; /* relative Y motion */
++ int32_t rel_z; /* relative Z motion (wheel) */
++};
++
++struct xenkbd_key
++{
++ uint8_t type; /* XENKBD_TYPE_KEY */
++ uint8_t pressed; /* 1 if pressed; 0 otherwise */
++ uint32_t keycode; /* KEY_* from linux/input.h */
++};
++
++struct xenkbd_position
++{
++ uint8_t type; /* XENKBD_TYPE_POS */
++ int32_t abs_x; /* absolute X position (in FB pixels) */
++ int32_t abs_y; /* absolute Y position (in FB pixels) */
++ int32_t rel_z; /* relative Z motion (wheel) */
+ };
+
+ #define XENKBD_IN_EVENT_SIZE 40
+
+-union xenkbd_in_event {
+- uint8_t type;
+- struct xenkbd_motion motion;
+- struct xenkbd_key key;
+- struct xenkbd_position pos;
+- char pad[XENKBD_IN_EVENT_SIZE];
++union xenkbd_in_event
++{
++ uint8_t type;
++ struct xenkbd_motion motion;
++ struct xenkbd_key key;
++ struct xenkbd_position pos;
++ char pad[XENKBD_IN_EVENT_SIZE];
+ };
+
+ /* Out events (frontend -> backend) */
+@@ -85,9 +89,10 @@ union xenkbd_in_event {
+
+ #define XENKBD_OUT_EVENT_SIZE 40
+
+-union xenkbd_out_event {
+- uint8_t type;
+- char pad[XENKBD_OUT_EVENT_SIZE];
++union xenkbd_out_event
++{
++ uint8_t type;
++ char pad[XENKBD_OUT_EVENT_SIZE];
+ };
+
+ /* shared page */
+@@ -96,21 +101,32 @@ union xenkbd_out_event {
+ #define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE)
+ #define XENKBD_IN_RING_OFFS 1024
+ #define XENKBD_IN_RING(page) \
+- ((union xenkbd_in_event *)((char *)(page) + XENKBD_IN_RING_OFFS))
++ ((union xenkbd_in_event *)((char *)(page) + XENKBD_IN_RING_OFFS))
+ #define XENKBD_IN_RING_REF(page, idx) \
+- (XENKBD_IN_RING((page))[(idx) % XENKBD_IN_RING_LEN])
++ (XENKBD_IN_RING((page))[(idx) % XENKBD_IN_RING_LEN])
+
+ #define XENKBD_OUT_RING_SIZE 1024
+ #define XENKBD_OUT_RING_LEN (XENKBD_OUT_RING_SIZE / XENKBD_OUT_EVENT_SIZE)
+ #define XENKBD_OUT_RING_OFFS (XENKBD_IN_RING_OFFS + XENKBD_IN_RING_SIZE)
+ #define XENKBD_OUT_RING(page) \
+- ((union xenkbd_out_event *)((char *)(page) + XENKBD_OUT_RING_OFFS))
++ ((union xenkbd_out_event *)((char *)(page) + XENKBD_OUT_RING_OFFS))
+ #define XENKBD_OUT_RING_REF(page, idx) \
+- (XENKBD_OUT_RING((page))[(idx) % XENKBD_OUT_RING_LEN])
++ (XENKBD_OUT_RING((page))[(idx) % XENKBD_OUT_RING_LEN])
+
+-struct xenkbd_page {
+- uint32_t in_cons, in_prod;
+- uint32_t out_cons, out_prod;
++struct xenkbd_page
++{
++ uint32_t in_cons, in_prod;
++ uint32_t out_cons, out_prod;
+ };
+
+ #endif
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/io/netif.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/netif.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/netif.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Unified network-device I/O interface for Xen guest OSes.
+ *
++ * 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.
++ *
+ * Copyright (c) 2003-2004, Keir Fraser
+ */
+
+@@ -47,18 +65,21 @@
+ #define _NETTXF_extra_info (3)
+ #define NETTXF_extra_info (1U<<_NETTXF_extra_info)
+
+-struct xen_netif_tx_request {
++struct netif_tx_request {
+ grant_ref_t gref; /* Reference to buffer page */
+ uint16_t offset; /* Offset within buffer page */
+ uint16_t flags; /* NETTXF_* */
+ uint16_t id; /* Echoed in response message. */
+ uint16_t size; /* Packet size in bytes. */
+ };
++typedef struct netif_tx_request netif_tx_request_t;
+
+ /* Types of netif_extra_info descriptors. */
+-#define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */
+-#define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */
+-#define XEN_NETIF_EXTRA_TYPE_MAX (2)
++#define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */
++#define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */
++#define XEN_NETIF_EXTRA_TYPE_MCAST_ADD (2) /* u.mcast */
++#define XEN_NETIF_EXTRA_TYPE_MCAST_DEL (3) /* u.mcast */
++#define XEN_NETIF_EXTRA_TYPE_MAX (4)
+
+ /* netif_extra_info flags. */
+ #define _XEN_NETIF_EXTRA_FLAG_MORE (0)
+@@ -71,49 +92,68 @@ struct xen_netif_tx_request {
+ * This structure needs to fit within both netif_tx_request and
+ * netif_rx_response for compatibility.
+ */
+-struct xen_netif_extra_info {
+- uint8_t type; /* XEN_NETIF_EXTRA_TYPE_* */
+- uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
+-
+- union {
+- struct {
+- /*
+- * Maximum payload size of each segment. For
+- * example, for TCP this is just the path MSS.
+- */
+- uint16_t size;
+-
+- /*
+- * GSO type. This determines the protocol of
+- * the packet and any extra features required
+- * to segment the packet properly.
+- */
+- uint8_t type; /* XEN_NETIF_GSO_TYPE_* */
+-
+- /* Future expansion. */
+- uint8_t pad;
+-
+- /*
+- * GSO features. This specifies any extra GSO
+- * features required to process this packet,
+- * such as ECN support for TCPv4.
+- */
+- uint16_t features; /* XEN_NETIF_GSO_FEAT_* */
+- } gso;
++struct netif_extra_info {
++ uint8_t type; /* XEN_NETIF_EXTRA_TYPE_* */
++ uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
++
++ union {
++ /*
++ * XEN_NETIF_EXTRA_TYPE_GSO:
++ */
++ struct {
++ /*
++ * Maximum payload size of each segment. For example, for TCP this
++ * is just the path MSS.
++ */
++ uint16_t size;
++
++ /*
++ * GSO type. This determines the protocol of the packet and any
++ * extra features required to segment the packet properly.
++ */
++ uint8_t type; /* XEN_NETIF_GSO_TYPE_* */
++
++ /* Future expansion. */
++ uint8_t pad;
++
++ /*
++ * GSO features. This specifies any extra GSO features required
++ * to process this packet, such as ECN support for TCPv4.
++ */
++ uint16_t features; /* XEN_NETIF_GSO_FEAT_* */
++ } gso;
++
++ /*
++ * XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL}:
++ * Backend advertises availability via 'feature-multicast-control'
++ * xenbus node containing value '1'.
++ * Frontend requests this feature by advertising
++ * 'request-multicast-control' xenbus node containing value '1'.
++ * If multicast control is requested then multicast flooding is
++ * disabled and the frontend must explicitly register its interest
++ * in multicast groups using dummy transmit requests containing
++ * MCAST_{ADD,DEL} extra-info fragments.
++ */
++ struct {
++ uint8_t addr[6]; /* Address to add/remove. */
++ } mcast;
+
+- uint16_t pad[3];
+- } u;
++ uint16_t pad[3];
++ } u;
+ };
++typedef struct netif_extra_info netif_extra_info_t;
+
+-struct xen_netif_tx_response {
+- uint16_t id;
+- int16_t status; /* NETIF_RSP_* */
++struct netif_tx_response {
++ uint16_t id;
++ int16_t status; /* NETIF_RSP_* */
+ };
++typedef struct netif_tx_response netif_tx_response_t;
+
+-struct xen_netif_rx_request {
+- uint16_t id; /* Echoed in response message. */
+- grant_ref_t gref; /* Reference to incoming granted frame */
++struct netif_rx_request {
++ uint16_t id; /* Echoed in response message. */
++ grant_ref_t gref; /* Reference to incoming granted frame */
+ };
++typedef struct netif_rx_request netif_rx_request_t;
+
+ /* Packet data has been validated against protocol checksum. */
+ #define _NETRXF_data_validated (0)
+@@ -131,23 +171,20 @@ struct xen_netif_rx_request {
+ #define _NETRXF_extra_info (3)
+ #define NETRXF_extra_info (1U<<_NETRXF_extra_info)
+
+-struct xen_netif_rx_response {
++struct netif_rx_response {
+ uint16_t id;
+ uint16_t offset; /* Offset in page of start of received packet */
+ uint16_t flags; /* NETRXF_* */
+ int16_t status; /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */
+ };
++typedef struct netif_rx_response netif_rx_response_t;
+
+ /*
+ * Generate netif ring structures and types.
+ */
+
+-DEFINE_RING_TYPES(xen_netif_tx,
+- struct xen_netif_tx_request,
+- struct xen_netif_tx_response);
+-DEFINE_RING_TYPES(xen_netif_rx,
+- struct xen_netif_rx_request,
+- struct xen_netif_rx_response);
++DEFINE_RING_TYPES(netif_tx, struct netif_tx_request, struct netif_tx_response);
++DEFINE_RING_TYPES(netif_rx, struct netif_rx_request, struct netif_rx_response);
+
+ #define NETIF_RSP_DROPPED -2
+ #define NETIF_RSP_ERROR -1
+@@ -156,3 +193,13 @@ DEFINE_RING_TYPES(xen_netif_rx,
+ #define NETIF_RSP_NULL 1
+
+ #endif
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/io/protocols.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/protocols.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/protocols.h 2008-11-25 12:35:56.000000000 +0100
+@@ -1,10 +1,31 @@
++/******************************************************************************
++ * protocols.h
++ *
++ * 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.
++ */
++
+ #ifndef __XEN_PROTOCOLS_H__
+ #define __XEN_PROTOCOLS_H__
+
+ #define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi"
+ #define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi"
+ #define XEN_IO_PROTO_ABI_IA64 "ia64-abi"
+-#define XEN_IO_PROTO_ABI_POWERPC64 "powerpc64-abi"
+
+ #if defined(__i386__)
+ # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
+@@ -12,8 +33,6 @@
+ # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
+ #elif defined(__ia64__)
+ # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
+-#elif defined(__powerpc64__)
+-# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
+ #else
+ # error arch fixup needed here
+ #endif
+Index: head-2008-11-25/include/xen/interface/io/ring.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/ring.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/ring.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,16 +3,42 @@
+ *
+ * Shared producer-consumer ring macros.
+ *
++ * 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.
++ *
+ * Tim Deegan and Andrew Warfield November 2004.
+ */
+
+ #ifndef __XEN_PUBLIC_IO_RING_H__
+ #define __XEN_PUBLIC_IO_RING_H__
+
++#include "../xen-compat.h"
++
++#if __XEN_INTERFACE_VERSION__ < 0x00030208
++#define xen_mb() mb()
++#define xen_rmb() rmb()
++#define xen_wmb() wmb()
++#endif
++
+ typedef unsigned int RING_IDX;
+
+ /* Round a 32-bit unsigned constant down to the nearest power of two. */
+-#define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1))
++#define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1))
+ #define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x))
+ #define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
+ #define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x))
+@@ -25,73 +51,76 @@ typedef unsigned int RING_IDX;
+ * power of two (so we can mask with (size-1) to loop around).
+ */
+ #define __RING_SIZE(_s, _sz) \
+- (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
++ (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+
+ /*
+ * Macros to make the correct C datatypes for a new kind of ring.
+ *
+ * To make a new ring datatype, you need to have two message structures,
+- * let's say struct request, and struct response already defined.
++ * let's say request_t, and response_t already defined.
+ *
+ * In a header where you want the ring datatype declared, you then do:
+ *
+- * DEFINE_RING_TYPES(mytag, struct request, struct response);
++ * DEFINE_RING_TYPES(mytag, request_t, response_t);
+ *
+ * These expand out to give you a set of types, as you can see below.
+ * The most important of these are:
+ *
+- * struct mytag_sring - The shared ring.
+- * struct mytag_front_ring - The 'front' half of the ring.
+- * struct mytag_back_ring - The 'back' half of the ring.
++ * mytag_sring_t - The shared ring.
++ * mytag_front_ring_t - The 'front' half of the ring.
++ * mytag_back_ring_t - The 'back' half of the ring.
+ *
+ * To initialize a ring in your code you need to know the location and size
+ * of the shared memory area (PAGE_SIZE, for instance). To initialise
+ * the front half:
+ *
+- * struct mytag_front_ring front_ring;
+- * SHARED_RING_INIT((struct mytag_sring *)shared_page);
+- * FRONT_RING_INIT(&front_ring, (struct mytag_sring *)shared_page,
+- * PAGE_SIZE);
++ * mytag_front_ring_t front_ring;
++ * SHARED_RING_INIT((mytag_sring_t *)shared_page);
++ * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
+ *
+ * Initializing the back follows similarly (note that only the front
+ * initializes the shared ring):
+ *
+- * struct mytag_back_ring back_ring;
+- * BACK_RING_INIT(&back_ring, (struct mytag_sring *)shared_page,
+- * PAGE_SIZE);
++ * mytag_back_ring_t back_ring;
++ * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
+ */
+
+-#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \
+- \
+-/* Shared ring entry */ \
+-union __name##_sring_entry { \
+- __req_t req; \
+- __rsp_t rsp; \
+-}; \
+- \
+-/* Shared ring page */ \
+-struct __name##_sring { \
+- RING_IDX req_prod, req_event; \
+- RING_IDX rsp_prod, rsp_event; \
+- uint8_t pad[48]; \
+- union __name##_sring_entry ring[1]; /* variable-length */ \
+-}; \
+- \
+-/* "Front" end's private variables */ \
+-struct __name##_front_ring { \
+- RING_IDX req_prod_pvt; \
+- RING_IDX rsp_cons; \
+- unsigned int nr_ents; \
+- struct __name##_sring *sring; \
+-}; \
+- \
+-/* "Back" end's private variables */ \
+-struct __name##_back_ring { \
+- RING_IDX rsp_prod_pvt; \
+- RING_IDX req_cons; \
+- unsigned int nr_ents; \
+- struct __name##_sring *sring; \
+-};
++#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \
++ \
++/* Shared ring entry */ \
++union __name##_sring_entry { \
++ __req_t req; \
++ __rsp_t rsp; \
++}; \
++ \
++/* Shared ring page */ \
++struct __name##_sring { \
++ RING_IDX req_prod, req_event; \
++ RING_IDX rsp_prod, rsp_event; \
++ uint8_t pad[48]; \
++ union __name##_sring_entry ring[1]; /* variable-length */ \
++}; \
++ \
++/* "Front" end's private variables */ \
++struct __name##_front_ring { \
++ RING_IDX req_prod_pvt; \
++ RING_IDX rsp_cons; \
++ unsigned int nr_ents; \
++ struct __name##_sring *sring; \
++}; \
++ \
++/* "Back" end's private variables */ \
++struct __name##_back_ring { \
++ RING_IDX rsp_prod_pvt; \
++ RING_IDX req_cons; \
++ unsigned int nr_ents; \
++ struct __name##_sring *sring; \
++}; \
++ \
++/* Syntactic sugar */ \
++typedef struct __name##_sring __name##_sring_t; \
++typedef struct __name##_front_ring __name##_front_ring_t; \
++typedef struct __name##_back_ring __name##_back_ring_t
+
+ /*
+ * Macros for manipulating rings.
+@@ -109,86 +138,94 @@ struct __name##_back_ring { \
+ */
+
+ /* Initialising empty rings */
+-#define SHARED_RING_INIT(_s) do { \
+- (_s)->req_prod = (_s)->rsp_prod = 0; \
+- (_s)->req_event = (_s)->rsp_event = 1; \
+- memset((_s)->pad, 0, sizeof((_s)->pad)); \
++#define SHARED_RING_INIT(_s) do { \
++ (_s)->req_prod = (_s)->rsp_prod = 0; \
++ (_s)->req_event = (_s)->rsp_event = 1; \
++ (void)memset((_s)->pad, 0, sizeof((_s)->pad)); \
+ } while(0)
+
+-#define FRONT_RING_INIT(_r, _s, __size) do { \
+- (_r)->req_prod_pvt = 0; \
+- (_r)->rsp_cons = 0; \
+- (_r)->nr_ents = __RING_SIZE(_s, __size); \
+- (_r)->sring = (_s); \
++#define FRONT_RING_INIT(_r, _s, __size) do { \
++ (_r)->req_prod_pvt = 0; \
++ (_r)->rsp_cons = 0; \
++ (_r)->nr_ents = __RING_SIZE(_s, __size); \
++ (_r)->sring = (_s); \
+ } while (0)
+
+-#define BACK_RING_INIT(_r, _s, __size) do { \
+- (_r)->rsp_prod_pvt = 0; \
+- (_r)->req_cons = 0; \
+- (_r)->nr_ents = __RING_SIZE(_s, __size); \
+- (_r)->sring = (_s); \
++#define BACK_RING_INIT(_r, _s, __size) do { \
++ (_r)->rsp_prod_pvt = 0; \
++ (_r)->req_cons = 0; \
++ (_r)->nr_ents = __RING_SIZE(_s, __size); \
++ (_r)->sring = (_s); \
+ } while (0)
+
+ /* Initialize to existing shared indexes -- for recovery */
+-#define FRONT_RING_ATTACH(_r, _s, __size) do { \
+- (_r)->sring = (_s); \
+- (_r)->req_prod_pvt = (_s)->req_prod; \
+- (_r)->rsp_cons = (_s)->rsp_prod; \
+- (_r)->nr_ents = __RING_SIZE(_s, __size); \
++#define FRONT_RING_ATTACH(_r, _s, __size) do { \
++ (_r)->sring = (_s); \
++ (_r)->req_prod_pvt = (_s)->req_prod; \
++ (_r)->rsp_cons = (_s)->rsp_prod; \
++ (_r)->nr_ents = __RING_SIZE(_s, __size); \
+ } while (0)
+
+-#define BACK_RING_ATTACH(_r, _s, __size) do { \
+- (_r)->sring = (_s); \
+- (_r)->rsp_prod_pvt = (_s)->rsp_prod; \
+- (_r)->req_cons = (_s)->req_prod; \
+- (_r)->nr_ents = __RING_SIZE(_s, __size); \
++#define BACK_RING_ATTACH(_r, _s, __size) do { \
++ (_r)->sring = (_s); \
++ (_r)->rsp_prod_pvt = (_s)->rsp_prod; \
++ (_r)->req_cons = (_s)->req_prod; \
++ (_r)->nr_ents = __RING_SIZE(_s, __size); \
+ } while (0)
+
+ /* How big is this ring? */
+-#define RING_SIZE(_r) \
++#define RING_SIZE(_r) \
+ ((_r)->nr_ents)
+
+ /* Number of free requests (for use on front side only). */
+-#define RING_FREE_REQUESTS(_r) \
++#define RING_FREE_REQUESTS(_r) \
+ (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
+
+ /* Test if there is an empty slot available on the front ring.
+ * (This is only meaningful from the front. )
+ */
+-#define RING_FULL(_r) \
++#define RING_FULL(_r) \
+ (RING_FREE_REQUESTS(_r) == 0)
+
+ /* Test if there are outstanding messages to be processed on a ring. */
+-#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
++#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
+ ((_r)->sring->rsp_prod - (_r)->rsp_cons)
+
+-#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
+- ({ \
+- unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
+- unsigned int rsp = RING_SIZE(_r) - \
+- ((_r)->req_cons - (_r)->rsp_prod_pvt); \
+- req < rsp ? req : rsp; \
+- })
++#ifdef __GNUC__
++#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \
++ unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
++ unsigned int rsp = RING_SIZE(_r) - \
++ ((_r)->req_cons - (_r)->rsp_prod_pvt); \
++ req < rsp ? req : rsp; \
++})
++#else
++/* Same as above, but without the nice GCC ({ ... }) syntax. */
++#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
++ ((((_r)->sring->req_prod - (_r)->req_cons) < \
++ (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
++ ((_r)->sring->req_prod - (_r)->req_cons) : \
++ (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
++#endif
+
+ /* Direct access to individual ring elements, by index. */
+-#define RING_GET_REQUEST(_r, _idx) \
++#define RING_GET_REQUEST(_r, _idx) \
+ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
+
+-#define RING_GET_RESPONSE(_r, _idx) \
++#define RING_GET_RESPONSE(_r, _idx) \
+ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
+
+ /* Loop termination condition: Would the specified index overflow the ring? */
+-#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
++#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
+ (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
+
+-#define RING_PUSH_REQUESTS(_r) do { \
+- wmb(); /* back sees requests /before/ updated producer index */ \
+- (_r)->sring->req_prod = (_r)->req_prod_pvt; \
++#define RING_PUSH_REQUESTS(_r) do { \
++ xen_wmb(); /* back sees requests /before/ updated producer index */ \
++ (_r)->sring->req_prod = (_r)->req_prod_pvt; \
+ } while (0)
+
+-#define RING_PUSH_RESPONSES(_r) do { \
+- wmb(); /* front sees responses /before/ updated producer index */ \
+- (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
++#define RING_PUSH_RESPONSES(_r) do { \
++ xen_wmb(); /* front sees resps /before/ updated producer index */ \
++ (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
+ } while (0)
+
+ /*
+@@ -221,40 +258,50 @@ struct __name##_back_ring { \
+ * field appropriately.
+ */
+
+-#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \
+- RING_IDX __old = (_r)->sring->req_prod; \
+- RING_IDX __new = (_r)->req_prod_pvt; \
+- wmb(); /* back sees requests /before/ updated producer index */ \
+- (_r)->sring->req_prod = __new; \
+- mb(); /* back sees new requests /before/ we check req_event */ \
+- (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
+- (RING_IDX)(__new - __old)); \
++#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \
++ RING_IDX __old = (_r)->sring->req_prod; \
++ RING_IDX __new = (_r)->req_prod_pvt; \
++ xen_wmb(); /* back sees requests /before/ updated producer index */ \
++ (_r)->sring->req_prod = __new; \
++ xen_mb(); /* back sees new requests /before/ we check req_event */ \
++ (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
++ (RING_IDX)(__new - __old)); \
+ } while (0)
+
+-#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \
+- RING_IDX __old = (_r)->sring->rsp_prod; \
+- RING_IDX __new = (_r)->rsp_prod_pvt; \
+- wmb(); /* front sees responses /before/ updated producer index */ \
+- (_r)->sring->rsp_prod = __new; \
+- mb(); /* front sees new responses /before/ we check rsp_event */ \
+- (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
+- (RING_IDX)(__new - __old)); \
++#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \
++ RING_IDX __old = (_r)->sring->rsp_prod; \
++ RING_IDX __new = (_r)->rsp_prod_pvt; \
++ xen_wmb(); /* front sees resps /before/ updated producer index */ \
++ (_r)->sring->rsp_prod = __new; \
++ xen_mb(); /* front sees new resps /before/ we check rsp_event */ \
++ (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
++ (RING_IDX)(__new - __old)); \
+ } while (0)
+
+-#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \
+- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
+- if (_work_to_do) break; \
+- (_r)->sring->req_event = (_r)->req_cons + 1; \
+- mb(); \
+- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
++#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \
++ (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
++ if (_work_to_do) break; \
++ (_r)->sring->req_event = (_r)->req_cons + 1; \
++ xen_mb(); \
++ (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
+ } while (0)
+
+-#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \
+- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
+- if (_work_to_do) break; \
+- (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
+- mb(); \
+- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
++#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \
++ (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
++ if (_work_to_do) break; \
++ (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
++ xen_mb(); \
++ (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
+ } while (0)
+
+ #endif /* __XEN_PUBLIC_IO_RING_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/io/xenbus.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/xenbus.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/xenbus.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,42 +3,78 @@
+ *
+ * Xenbus protocol details.
+ *
++ * 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.
++ *
+ * Copyright (C) 2005 XenSource Ltd.
+ */
+
+ #ifndef _XEN_PUBLIC_IO_XENBUS_H
+ #define _XEN_PUBLIC_IO_XENBUS_H
+
+-/* The state of either end of the Xenbus, i.e. the current communication
+- status of initialisation across the bus. States here imply nothing about
+- the state of the connection between the driver and the kernel's device
+- layers. */
+-enum xenbus_state
+-{
+- XenbusStateUnknown = 0,
+- XenbusStateInitialising = 1,
+- XenbusStateInitWait = 2, /* Finished early
+- initialisation, but waiting
+- for information from the peer
+- or hotplug scripts. */
+- XenbusStateInitialised = 3, /* Initialised and waiting for a
+- connection from the peer. */
+- XenbusStateConnected = 4,
+- XenbusStateClosing = 5, /* The device is being closed
+- due to an error or an unplug
+- event. */
+- XenbusStateClosed = 6
++/*
++ * The state of either end of the Xenbus, i.e. the current communication
++ * status of initialisation across the bus. States here imply nothing about
++ * the state of the connection between the driver and the kernel's device
++ * layers.
++ */
++enum xenbus_state {
++ XenbusStateUnknown = 0,
++
++ XenbusStateInitialising = 1,
++
++ /*
++ * InitWait: Finished early initialisation but waiting for information
++ * from the peer or hotplug scripts.
++ */
++ XenbusStateInitWait = 2,
++
++ /*
++ * Initialised: Waiting for a connection from the peer.
++ */
++ XenbusStateInitialised = 3,
++
++ XenbusStateConnected = 4,
++
++ /*
++ * Closing: The device is being closed due to an error or an unplug event.
++ */
++ XenbusStateClosing = 5,
++
++ XenbusStateClosed = 6,
++
++ /*
++ * Reconfiguring: The device is being reconfigured.
++ */
++ XenbusStateReconfiguring = 7,
+
++ XenbusStateReconfigured = 8
+ };
++typedef enum xenbus_state XenbusState;
+
+ #endif /* _XEN_PUBLIC_IO_XENBUS_H */
+
+ /*
+ * Local variables:
+- * c-file-style: "linux"
+- * indent-tabs-mode: t
+- * c-indent-level: 8
+- * c-basic-offset: 8
+- * tab-width: 8
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
+ * End:
+ */
+Index: head-2008-11-25/include/xen/interface/io/xs_wire.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/io/xs_wire.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/io/xs_wire.h 2008-11-25 12:35:56.000000000 +0100
+@@ -1,6 +1,25 @@
+ /*
+ * Details of the "wire" protocol between Xen Store Daemon and client
+ * library or guest kernel.
++ *
++ * 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.
++ *
+ * Copyright (C) 2005 Rusty Russell IBM Corporation
+ */
+
+@@ -26,7 +45,9 @@ enum xsd_sockmsg_type
+ XS_SET_PERMS,
+ XS_WATCH_EVENT,
+ XS_ERROR,
+- XS_IS_DOMAIN_INTRODUCED
++ XS_IS_DOMAIN_INTRODUCED,
++ XS_RESUME,
++ XS_SET_TARGET
+ };
+
+ #define XS_WRITE_NONE "NONE"
+@@ -40,7 +61,12 @@ struct xsd_errors
+ const char *errstring;
+ };
+ #define XSD_ERROR(x) { x, #x }
+-static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
++/* LINTED: static unused */
++static struct xsd_errors xsd_errors[]
++#if defined(__GNUC__)
++__attribute__((unused))
++#endif
++ = {
+ XSD_ERROR(EINVAL),
+ XSD_ERROR(EACCES),
+ XSD_ERROR(EEXIST),
+@@ -84,4 +110,21 @@ struct xenstore_domain_interface {
+ XENSTORE_RING_IDX rsp_cons, rsp_prod;
+ };
+
++/* Violating this is very bad. See docs/misc/xenstore.txt. */
++#define XENSTORE_PAYLOAD_MAX 4096
++
++/* Violating these just gets you an error back */
++#define XENSTORE_ABS_PATH_MAX 3072
++#define XENSTORE_REL_PATH_MAX 2048
++
+ #endif /* _XS_WIRE_H */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/memory.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/memory.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/memory.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Memory reservation and information.
+ *
++ * 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.
++ *
+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
+ */
+
+@@ -10,13 +28,28 @@
+ #define __XEN_PUBLIC_MEMORY_H__
+
+ /*
+- * Increase or decrease the specified domain's memory reservation. Returns a
+- * -ve errcode on failure, or the # extents successfully allocated or freed.
++ * Increase or decrease the specified domain's memory reservation. Returns the
++ * number of extents successfully allocated or freed.
+ * arg == addr of struct xen_memory_reservation.
+ */
+ #define XENMEM_increase_reservation 0
+ #define XENMEM_decrease_reservation 1
+ #define XENMEM_populate_physmap 6
++
++#if __XEN_INTERFACE_VERSION__ >= 0x00030209
++/*
++ * Maximum # bits addressable by the user of the allocated region (e.g., I/O
++ * devices often have a 32-bit limitation even in 64-bit systems). If zero
++ * then the user has no addressing restriction. This field is not used by
++ * XENMEM_decrease_reservation.
++ */
++#define XENMEMF_address_bits(x) (x)
++#define XENMEMF_get_address_bits(x) ((x) & 0xffu)
++/* NUMA node to allocate from. */
++#define XENMEMF_node(x) (((x) + 1) << 8)
++#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu)
++#endif
++
+ struct xen_memory_reservation {
+
+ /*
+@@ -29,19 +62,18 @@ struct xen_memory_reservation {
+ * OUT: GMFN bases of extents that were allocated
+ * (NB. This command also updates the mach_to_phys translation table)
+ */
+- GUEST_HANDLE(ulong) extent_start;
++ XEN_GUEST_HANDLE(ulong) extent_start;
+
+ /* Number of extents, and size/alignment of each (2^extent_order pages). */
+- unsigned long nr_extents;
++ xen_ulong_t nr_extents;
+ unsigned int extent_order;
+
+- /*
+- * Maximum # bits addressable by the user of the allocated region (e.g.,
+- * I/O devices often have a 32-bit limitation even in 64-bit systems). If
+- * zero then the user has no addressing restriction.
+- * This field is not used by XENMEM_decrease_reservation.
+- */
++#if __XEN_INTERFACE_VERSION__ >= 0x00030209
++ /* XENMEMF flags. */
++ unsigned int mem_flags;
++#else
+ unsigned int address_bits;
++#endif
+
+ /*
+ * Domain whose reservation is being changed.
+@@ -50,7 +82,51 @@ struct xen_memory_reservation {
+ domid_t domid;
+
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(xen_memory_reservation);
++typedef struct xen_memory_reservation xen_memory_reservation_t;
++DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t);
++
++/*
++ * An atomic exchange of memory pages. If return code is zero then
++ * @out.extent_list provides GMFNs of the newly-allocated memory.
++ * Returns zero on complete success, otherwise a negative error code.
++ * On complete success then always @nr_exchanged == @in.nr_extents.
++ * On partial success @nr_exchanged indicates how much work was done.
++ */
++#define XENMEM_exchange 11
++struct xen_memory_exchange {
++ /*
++ * [IN] Details of memory extents to be exchanged (GMFN bases).
++ * Note that @in.address_bits is ignored and unused.
++ */
++ struct xen_memory_reservation in;
++
++ /*
++ * [IN/OUT] Details of new memory extents.
++ * We require that:
++ * 1. @in.domid == @out.domid
++ * 2. @in.nr_extents << @in.extent_order ==
++ * @out.nr_extents << @out.extent_order
++ * 3. @in.extent_start and @out.extent_start lists must not overlap
++ * 4. @out.extent_start lists GPFN bases to be populated
++ * 5. @out.extent_start is overwritten with allocated GMFN bases
++ */
++ struct xen_memory_reservation out;
++
++ /*
++ * [OUT] Number of input extents that were successfully exchanged:
++ * 1. The first @nr_exchanged input extents were successfully
++ * deallocated.
++ * 2. The corresponding first entries in the output extent list correctly
++ * indicate the GMFNs that were successfully exchanged.
++ * 3. All other input and output extents are untouched.
++ * 4. If not all input exents are exchanged then the return code of this
++ * command will be non-zero.
++ * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
++ */
++ xen_ulong_t nr_exchanged;
++};
++typedef struct xen_memory_exchange xen_memory_exchange_t;
++DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
+
+ /*
+ * Returns the maximum machine frame number of mapped RAM in this system.
+@@ -68,6 +144,11 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_memory_re
+ #define XENMEM_maximum_reservation 4
+
+ /*
++ * Returns the maximum GPFN in use by the guest, or -ve errcode on failure.
++ */
++#define XENMEM_maximum_gpfn 14
++
++/*
+ * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
+ * mapping table. Architectures which do not have a m2p table do not implement
+ * this command.
+@@ -86,7 +167,7 @@ struct xen_machphys_mfn_list {
+ * any large discontiguities in the machine address space, 2MB gaps in
+ * the machphys table will be represented by an MFN base of zero.
+ */
+- GUEST_HANDLE(ulong) extent_start;
++ XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
+
+ /*
+ * Number of extents written to the above array. This will be smaller
+@@ -94,7 +175,22 @@ struct xen_machphys_mfn_list {
+ */
+ unsigned int nr_extents;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list);
++typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t;
++DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);
++
++/*
++ * Returns the location in virtual address space of the machine_to_phys
++ * mapping table. Architectures which do not have a m2p table, or which do not
++ * map it by default into guest address space, do not implement this command.
++ * arg == addr of xen_machphys_mapping_t.
++ */
++#define XENMEM_machphys_mapping 12
++struct xen_machphys_mapping {
++ xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */
++ xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */
++};
++typedef struct xen_machphys_mapping xen_machphys_mapping_t;
++DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
+
+ /*
+ * Sets the GPFN at which a particular page appears in the specified guest's
+@@ -109,15 +205,33 @@ struct xen_add_to_physmap {
+ /* Source mapping space. */
+ #define XENMAPSPACE_shared_info 0 /* shared info page */
+ #define XENMAPSPACE_grant_table 1 /* grant table page */
++#define XENMAPSPACE_mfn 2 /* usual MFN */
+ unsigned int space;
+
+ /* Index into source mapping space. */
+- unsigned long idx;
++ xen_ulong_t idx;
+
+ /* GPFN where the source mapping page should appear. */
+- unsigned long gpfn;
++ xen_pfn_t gpfn;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
++typedef struct xen_add_to_physmap xen_add_to_physmap_t;
++DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
++
++/*
++ * Unmaps the page appearing at a particular GPFN from the specified guest's
++ * pseudophysical address space.
++ * arg == addr of xen_remove_from_physmap_t.
++ */
++#define XENMEM_remove_from_physmap 15
++struct xen_remove_from_physmap {
++ /* Which domain to change the mapping for. */
++ domid_t domid;
++
++ /* GPFN of the current mapping of the page. */
++ xen_pfn_t gpfn;
++};
++typedef struct xen_remove_from_physmap xen_remove_from_physmap_t;
++DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t);
+
+ /*
+ * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
+@@ -129,17 +243,71 @@ struct xen_translate_gpfn_list {
+ domid_t domid;
+
+ /* Length of list. */
+- unsigned long nr_gpfns;
++ xen_ulong_t nr_gpfns;
+
+ /* List of GPFNs to translate. */
+- GUEST_HANDLE(ulong) gpfn_list;
++ XEN_GUEST_HANDLE(xen_pfn_t) gpfn_list;
+
+ /*
+ * Output list to contain MFN translations. May be the same as the input
+ * list (in which case each input GPFN is overwritten with the output MFN).
+ */
+- GUEST_HANDLE(ulong) mfn_list;
++ XEN_GUEST_HANDLE(xen_pfn_t) mfn_list;
++};
++typedef struct xen_translate_gpfn_list xen_translate_gpfn_list_t;
++DEFINE_XEN_GUEST_HANDLE(xen_translate_gpfn_list_t);
++
++/*
++ * Returns the pseudo-physical memory map as it was when the domain
++ * was started (specified by XENMEM_set_memory_map).
++ * arg == addr of xen_memory_map_t.
++ */
++#define XENMEM_memory_map 9
++struct xen_memory_map {
++ /*
++ * On call the number of entries which can be stored in buffer. On
++ * return the number of entries which have been stored in
++ * buffer.
++ */
++ unsigned int nr_entries;
++
++ /*
++ * Entries in the buffer are in the same format as returned by the
++ * BIOS INT 0x15 EAX=0xE820 call.
++ */
++ XEN_GUEST_HANDLE(void) buffer;
++};
++typedef struct xen_memory_map xen_memory_map_t;
++DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
++
++/*
++ * Returns the real physical memory map. Passes the same structure as
++ * XENMEM_memory_map.
++ * arg == addr of xen_memory_map_t.
++ */
++#define XENMEM_machine_memory_map 10
++
++/*
++ * Set the pseudo-physical memory map of a domain, as returned by
++ * XENMEM_memory_map.
++ * arg == addr of xen_foreign_memory_map_t.
++ */
++#define XENMEM_set_memory_map 13
++struct xen_foreign_memory_map {
++ domid_t domid;
++ struct xen_memory_map map;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list);
++typedef struct xen_foreign_memory_map xen_foreign_memory_map_t;
++DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t);
+
+ #endif /* __XEN_PUBLIC_MEMORY_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/physdev.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/physdev.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/physdev.h 2008-11-25 12:35:56.000000000 +0100
+@@ -24,7 +24,7 @@
+ /*
+ * Prototype for this hypercall is:
+ * int physdev_op(int cmd, void *args)
+- * @cmd == PHYSDEVOP_??? (physdev operation).
++ * @cmd == PHYSDEVOP_??? (physdev operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
+@@ -32,114 +32,188 @@
+ * Notify end-of-interrupt (EOI) for the specified IRQ.
+ * @arg == pointer to physdev_eoi structure.
+ */
+-#define PHYSDEVOP_eoi 12
++#define PHYSDEVOP_eoi 12
+ struct physdev_eoi {
+- /* IN */
+- uint32_t irq;
++ /* IN */
++ uint32_t irq;
+ };
++typedef struct physdev_eoi physdev_eoi_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
+
+ /*
+ * Query the status of an IRQ line.
+ * @arg == pointer to physdev_irq_status_query structure.
+ */
+-#define PHYSDEVOP_irq_status_query 5
++#define PHYSDEVOP_irq_status_query 5
+ struct physdev_irq_status_query {
+- /* IN */
+- uint32_t irq;
+- /* OUT */
+- uint32_t flags; /* XENIRQSTAT_* */
++ /* IN */
++ uint32_t irq;
++ /* OUT */
++ uint32_t flags; /* XENIRQSTAT_* */
+ };
++typedef struct physdev_irq_status_query physdev_irq_status_query_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);
+
+ /* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
+-#define _XENIRQSTAT_needs_eoi (0)
+-#define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi)
++#define _XENIRQSTAT_needs_eoi (0)
++#define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi)
+
+ /* IRQ shared by multiple guests? */
+-#define _XENIRQSTAT_shared (1)
+-#define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared)
++#define _XENIRQSTAT_shared (1)
++#define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared)
+
+ /*
+ * Set the current VCPU's I/O privilege level.
+ * @arg == pointer to physdev_set_iopl structure.
+ */
+-#define PHYSDEVOP_set_iopl 6
++#define PHYSDEVOP_set_iopl 6
+ struct physdev_set_iopl {
+- /* IN */
+- uint32_t iopl;
++ /* IN */
++ uint32_t iopl;
+ };
++typedef struct physdev_set_iopl physdev_set_iopl_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);
+
+ /*
+ * Set the current VCPU's I/O-port permissions bitmap.
+ * @arg == pointer to physdev_set_iobitmap structure.
+ */
+-#define PHYSDEVOP_set_iobitmap 7
++#define PHYSDEVOP_set_iobitmap 7
+ struct physdev_set_iobitmap {
+- /* IN */
+- uint8_t * bitmap;
+- uint32_t nr_ports;
++ /* IN */
++#if __XEN_INTERFACE_VERSION__ >= 0x00030205
++ XEN_GUEST_HANDLE(uint8) bitmap;
++#else
++ uint8_t *bitmap;
++#endif
++ uint32_t nr_ports;
+ };
++typedef struct physdev_set_iobitmap physdev_set_iobitmap_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);
+
+ /*
+ * Read or write an IO-APIC register.
+ * @arg == pointer to physdev_apic structure.
+ */
+-#define PHYSDEVOP_apic_read 8
+-#define PHYSDEVOP_apic_write 9
++#define PHYSDEVOP_apic_read 8
++#define PHYSDEVOP_apic_write 9
+ struct physdev_apic {
+- /* IN */
+- unsigned long apic_physbase;
+- uint32_t reg;
+- /* IN or OUT */
+- uint32_t value;
++ /* IN */
++ unsigned long apic_physbase;
++ uint32_t reg;
++ /* IN or OUT */
++ uint32_t value;
+ };
++typedef struct physdev_apic physdev_apic_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
+
+ /*
+ * Allocate or free a physical upcall vector for the specified IRQ line.
+ * @arg == pointer to physdev_irq structure.
+ */
+-#define PHYSDEVOP_alloc_irq_vector 10
+-#define PHYSDEVOP_free_irq_vector 11
++#define PHYSDEVOP_alloc_irq_vector 10
++#define PHYSDEVOP_free_irq_vector 11
+ struct physdev_irq {
+- /* IN */
+- uint32_t irq;
+- /* IN or OUT */
+- uint32_t vector;
++ /* IN */
++ uint32_t irq;
++ /* IN or OUT */
++ uint32_t vector;
++};
++typedef struct physdev_irq physdev_irq_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
++
++#define MAP_PIRQ_TYPE_MSI 0x0
++#define MAP_PIRQ_TYPE_GSI 0x1
++#define MAP_PIRQ_TYPE_UNKNOWN 0x2
++
++#define PHYSDEVOP_map_pirq 13
++struct physdev_map_pirq {
++ domid_t domid;
++ /* IN */
++ int type;
++ /* IN */
++ int index;
++ /* IN or OUT */
++ int pirq;
++ /* IN */
++ int bus;
++ /* IN */
++ int devfn;
++ /* IN */
++ int entry_nr;
++ /* IN */
++ uint64_t table_base;
++};
++typedef struct physdev_map_pirq physdev_map_pirq_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);
++
++#define PHYSDEVOP_unmap_pirq 14
++struct physdev_unmap_pirq {
++ domid_t domid;
++ /* IN */
++ int pirq;
++};
++
++typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);
++
++#define PHYSDEVOP_manage_pci_add 15
++#define PHYSDEVOP_manage_pci_remove 16
++struct physdev_manage_pci {
++ /* IN */
++ uint8_t bus;
++ uint8_t devfn;
+ };
+
++typedef struct physdev_manage_pci physdev_manage_pci_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t);
++
+ /*
+ * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
+ * hypercall since 0x00030202.
+ */
+ struct physdev_op {
+- uint32_t cmd;
+- union {
+- struct physdev_irq_status_query irq_status_query;
+- struct physdev_set_iopl set_iopl;
+- struct physdev_set_iobitmap set_iobitmap;
+- struct physdev_apic apic_op;
+- struct physdev_irq irq_op;
+- } u;
++ uint32_t cmd;
++ union {
++ struct physdev_irq_status_query irq_status_query;
++ struct physdev_set_iopl set_iopl;
++ struct physdev_set_iobitmap set_iobitmap;
++ struct physdev_apic apic_op;
++ struct physdev_irq irq_op;
++ } u;
+ };
++typedef struct physdev_op physdev_op_t;
++DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
+
+ /*
+ * Notify that some PIRQ-bound event channels have been unmasked.
+ * ** This command is obsolete since interface version 0x00030202 and is **
+- * ** unsupported by newer versions of Xen. **
++ * ** unsupported by newer versions of Xen. **
+ */
+-#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4
++#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4
+
+ /*
+ * These all-capitals physdev operation names are superceded by the new names
+ * (defined above) since interface version 0x00030202.
+ */
+-#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query
+-#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl
+-#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap
+-#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read
+-#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write
+-#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector
+-#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector
++#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query
++#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl
++#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap
++#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read
++#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write
++#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector
++#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector
+ #define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
+-#define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared
++#define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared
+
+ #endif /* __XEN_PUBLIC_PHYSDEV_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/sched.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/sched.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/sched.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Scheduler state interactions
+ *
++ * 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.
++ *
+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
+ */
+
+@@ -13,17 +31,17 @@
+
+ /*
+ * The prototype for this hypercall is:
+- * long sched_op_new(int cmd, void *arg)
++ * long sched_op(int cmd, void *arg)
+ * @cmd == SCHEDOP_??? (scheduler operation).
+ * @arg == Operation-specific extra argument(s), as described below.
+ *
+- * **NOTE**:
+- * Versions of Xen prior to 3.0.2 provide only the following legacy version
++ * Versions of Xen prior to 3.0.2 provided only the following legacy version
+ * of this hypercall, supporting only the commands yield, block and shutdown:
+ * long sched_op(int cmd, unsigned long arg)
+ * @cmd == SCHEDOP_??? (scheduler operation).
+ * @arg == 0 (SCHEDOP_yield and SCHEDOP_block)
+ * == SHUTDOWN_* code (SCHEDOP_shutdown)
++ * This legacy version is available to new guests as sched_op_compat().
+ */
+
+ /*
+@@ -49,7 +67,8 @@
+ struct sched_shutdown {
+ unsigned int reason; /* SHUTDOWN_* */
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(sched_shutdown);
++typedef struct sched_shutdown sched_shutdown_t;
++DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t);
+
+ /*
+ * Poll a set of event-channel ports. Return when one or more are pending. An
+@@ -58,11 +77,26 @@ DEFINE_GUEST_HANDLE_STRUCT(sched_shutdow
+ */
+ #define SCHEDOP_poll 3
+ struct sched_poll {
+- GUEST_HANDLE(evtchn_port_t) ports;
++ XEN_GUEST_HANDLE(evtchn_port_t) ports;
+ unsigned int nr_ports;
+ uint64_t timeout;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(sched_poll);
++typedef struct sched_poll sched_poll_t;
++DEFINE_XEN_GUEST_HANDLE(sched_poll_t);
++
++/*
++ * Declare a shutdown for another domain. The main use of this function is
++ * in interpreting shutdown requests and reasons for fully-virtualized
++ * domains. A para-virtualized domain may use SCHEDOP_shutdown directly.
++ * @arg == pointer to sched_remote_shutdown structure.
++ */
++#define SCHEDOP_remote_shutdown 4
++struct sched_remote_shutdown {
++ domid_t domain_id; /* Remote domain ID */
++ unsigned int reason; /* SHUTDOWN_xxx reason */
++};
++typedef struct sched_remote_shutdown sched_remote_shutdown_t;
++DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t);
+
+ /*
+ * Reason codes for SCHEDOP_shutdown. These may be interpreted by control
+@@ -75,3 +109,13 @@ DEFINE_GUEST_HANDLE_STRUCT(sched_poll);
+ #define SHUTDOWN_crash 3 /* Tell controller we've crashed. */
+
+ #endif /* __XEN_PUBLIC_SCHED_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/vcpu.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/vcpu.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/vcpu.h 2008-11-25 12:35:56.000000000 +0100
+@@ -29,9 +29,9 @@
+
+ /*
+ * Prototype for this hypercall is:
+- * int vcpu_op(int cmd, int vcpuid, void *extra_args)
+- * @cmd == VCPUOP_??? (VCPU operation).
+- * @vcpuid == VCPU to operate on.
++ * int vcpu_op(int cmd, int vcpuid, void *extra_args)
++ * @cmd == VCPUOP_??? (VCPU operation).
++ * @vcpuid == VCPU to operate on.
+ * @extra_args == Operation-specific extra arguments (NULL if none).
+ */
+
+@@ -40,52 +40,53 @@
+ * newly-initialised VCPU will not run until it is brought up by VCPUOP_up.
+ *
+ * @extra_arg == pointer to vcpu_guest_context structure containing initial
+- * state for the VCPU.
++ * state for the VCPU.
+ */
+-#define VCPUOP_initialise 0
++#define VCPUOP_initialise 0
+
+ /*
+ * Bring up a VCPU. This makes the VCPU runnable. This operation will fail
+ * if the VCPU has not been initialised (VCPUOP_initialise).
+ */
+-#define VCPUOP_up 1
++#define VCPUOP_up 1
+
+ /*
+ * Bring down a VCPU (i.e., make it non-runnable).
+ * There are a few caveats that callers should observe:
+- * 1. This operation may return, and VCPU_is_up may return false, before the
+- * VCPU stops running (i.e., the command is asynchronous). It is a good
+- * idea to ensure that the VCPU has entered a non-critical loop before
+- * bringing it down. Alternatively, this operation is guaranteed
+- * synchronous if invoked by the VCPU itself.
+- * 2. After a VCPU is initialised, there is currently no way to drop all its
+- * references to domain memory. Even a VCPU that is down still holds
+- * memory references via its pagetable base pointer and GDT. It is good
+- * practise to move a VCPU onto an 'idle' or default page table, LDT and
+- * GDT before bringing it down.
++ * 1. This operation may return, and VCPU_is_up may return false, before the
++ * VCPU stops running (i.e., the command is asynchronous). It is a good
++ * idea to ensure that the VCPU has entered a non-critical loop before
++ * bringing it down. Alternatively, this operation is guaranteed
++ * synchronous if invoked by the VCPU itself.
++ * 2. After a VCPU is initialised, there is currently no way to drop all its
++ * references to domain memory. Even a VCPU that is down still holds
++ * memory references via its pagetable base pointer and GDT. It is good
++ * practise to move a VCPU onto an 'idle' or default page table, LDT and
++ * GDT before bringing it down.
+ */
+-#define VCPUOP_down 2
++#define VCPUOP_down 2
+
+ /* Returns 1 if the given VCPU is up. */
+-#define VCPUOP_is_up 3
++#define VCPUOP_is_up 3
+
+ /*
+ * Return information about the state and running time of a VCPU.
+ * @extra_arg == pointer to vcpu_runstate_info structure.
+ */
+-#define VCPUOP_get_runstate_info 4
++#define VCPUOP_get_runstate_info 4
+ struct vcpu_runstate_info {
+- /* VCPU's current state (RUNSTATE_*). */
+- int state;
+- /* When was current state entered (system time, ns)? */
+- uint64_t state_entry_time;
+- /*
+- * Time spent in each RUNSTATE_* (ns). The sum of these times is
+- * guaranteed not to drift from system time.
+- */
+- uint64_t time[4];
++ /* VCPU's current state (RUNSTATE_*). */
++ int state;
++ /* When was current state entered (system time, ns)? */
++ uint64_t state_entry_time;
++ /*
++ * Time spent in each RUNSTATE_* (ns). The sum of these times is
++ * guaranteed not to drift from system time.
++ */
++ uint64_t time[4];
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(vcpu_runstate_info);
++typedef struct vcpu_runstate_info vcpu_runstate_info_t;
++DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_t);
+
+ /* VCPU is currently running on a physical CPU. */
+ #define RUNSTATE_running 0
+@@ -108,47 +109,52 @@ DEFINE_GUEST_HANDLE_STRUCT(vcpu_runstate
+ * Register a shared memory area from which the guest may obtain its own
+ * runstate information without needing to execute a hypercall.
+ * Notes:
+- * 1. The registered address may be virtual or physical, depending on the
+- * platform. The virtual address should be registered on x86 systems.
+- * 2. Only one shared area may be registered per VCPU. The shared area is
+- * updated by the hypervisor each time the VCPU is scheduled. Thus
+- * runstate.state will always be RUNSTATE_running and
+- * runstate.state_entry_time will indicate the system time at which the
+- * VCPU was last scheduled to run.
++ * 1. The registered address may be virtual or physical or guest handle,
++ * depending on the platform. Virtual address or guest handle should be
++ * registered on x86 systems.
++ * 2. Only one shared area may be registered per VCPU. The shared area is
++ * updated by the hypervisor each time the VCPU is scheduled. Thus
++ * runstate.state will always be RUNSTATE_running and
++ * runstate.state_entry_time will indicate the system time at which the
++ * VCPU was last scheduled to run.
+ * @extra_arg == pointer to vcpu_register_runstate_memory_area structure.
+ */
+ #define VCPUOP_register_runstate_memory_area 5
+ struct vcpu_register_runstate_memory_area {
+- union {
+- GUEST_HANDLE(vcpu_runstate_info) h;
+- struct vcpu_runstate_info *v;
+- uint64_t p;
+- } addr;
++ union {
++ XEN_GUEST_HANDLE(vcpu_runstate_info_t) h;
++ struct vcpu_runstate_info *v;
++ uint64_t p;
++ } addr;
+ };
++typedef struct vcpu_register_runstate_memory_area vcpu_register_runstate_memory_area_t;
++DEFINE_XEN_GUEST_HANDLE(vcpu_register_runstate_memory_area_t);
+
+ /*
+ * Set or stop a VCPU's periodic timer. Every VCPU has one periodic timer
+ * which can be set via these commands. Periods smaller than one millisecond
+ * may not be supported.
+ */
+-#define VCPUOP_set_periodic_timer 6 /* arg == vcpu_set_periodic_timer_t */
+-#define VCPUOP_stop_periodic_timer 7 /* arg == NULL */
++#define VCPUOP_set_periodic_timer 6 /* arg == vcpu_set_periodic_timer_t */
++#define VCPUOP_stop_periodic_timer 7 /* arg == NULL */
+ struct vcpu_set_periodic_timer {
+- uint64_t period_ns;
++ uint64_t period_ns;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(vcpu_set_periodic_timer);
++typedef struct vcpu_set_periodic_timer vcpu_set_periodic_timer_t;
++DEFINE_XEN_GUEST_HANDLE(vcpu_set_periodic_timer_t);
+
+ /*
+ * Set or stop a VCPU's single-shot timer. Every VCPU has one single-shot
+ * timer which can be set via these commands.
+ */
+-#define VCPUOP_set_singleshot_timer 8 /* arg == vcpu_set_singleshot_timer_t */
++#define VCPUOP_set_singleshot_timer 8 /* arg == vcpu_set_singleshot_timer_t */
+ #define VCPUOP_stop_singleshot_timer 9 /* arg == NULL */
+ struct vcpu_set_singleshot_timer {
+- uint64_t timeout_abs_ns;
+- uint32_t flags; /* VCPU_SSHOTTMR_??? */
++ uint64_t timeout_abs_ns; /* Absolute system time value in nanoseconds. */
++ uint32_t flags; /* VCPU_SSHOTTMR_??? */
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(vcpu_set_singleshot_timer);
++typedef struct vcpu_set_singleshot_timer vcpu_set_singleshot_timer_t;
++DEFINE_XEN_GUEST_HANDLE(vcpu_set_singleshot_timer_t);
+
+ /* Flags to VCPUOP_set_singleshot_timer. */
+ /* Require the timeout to be in the future (return -ETIME if it's passed). */
+@@ -161,13 +167,47 @@ DEFINE_GUEST_HANDLE_STRUCT(vcpu_set_sing
+ * structure in a convenient place, such as in a per-cpu data area.
+ * The pointer need not be page aligned, but the structure must not
+ * cross a page boundary.
++ *
++ * This may be called only once per vcpu.
+ */
+-#define VCPUOP_register_vcpu_info 10 /* arg == struct vcpu_info */
++#define VCPUOP_register_vcpu_info 10 /* arg == vcpu_register_vcpu_info_t */
+ struct vcpu_register_vcpu_info {
+ uint64_t mfn; /* mfn of page to place vcpu_info */
+ uint32_t offset; /* offset within page */
+ uint32_t rsvd; /* unused */
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(vcpu_register_vcpu_info);
++typedef struct vcpu_register_vcpu_info vcpu_register_vcpu_info_t;
++DEFINE_XEN_GUEST_HANDLE(vcpu_register_vcpu_info_t);
++
++/* Send an NMI to the specified VCPU. @extra_arg == NULL. */
++#define VCPUOP_send_nmi 11
++
++/*
++ * Get the physical ID information for a pinned vcpu's underlying physical
++ * processor. The physical ID informmation is architecture-specific.
++ * On x86: id[31:0]=apic_id, id[63:32]=acpi_id, and all values 0xff and
++ * greater are reserved.
++ * This command returns -EINVAL if it is not a valid operation for this VCPU.
++ */
++#define VCPUOP_get_physid 12 /* arg == vcpu_get_physid_t */
++struct vcpu_get_physid {
++ uint64_t phys_id;
++};
++typedef struct vcpu_get_physid vcpu_get_physid_t;
++DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t);
++#define xen_vcpu_physid_to_x86_apicid(physid) \
++ ((((uint32_t)(physid)) >= 0xff) ? 0xff : ((uint8_t)(physid)))
++#define xen_vcpu_physid_to_x86_acpiid(physid) \
++ ((((uint32_t)((physid)>>32)) >= 0xff) ? 0xff : ((uint8_t)((physid)>>32)))
+
+ #endif /* __XEN_PUBLIC_VCPU_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/version.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/version.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/version.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,6 +3,24 @@
+ *
+ * Xen version, type, and compile information.
+ *
++ * 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.
++ *
+ * Copyright (c) 2005, Nguyen Anh Quynh <aquynh@gmail.com>
+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
+ */
+@@ -10,17 +28,15 @@
+ #ifndef __XEN_PUBLIC_VERSION_H__
+ #define __XEN_PUBLIC_VERSION_H__
+
+-/* NB. All ops return zero on success, except XENVER_version. */
++/* NB. All ops return zero on success, except XENVER_{version,pagesize} */
+
+ /* arg == NULL; returns major:minor (16:16). */
+ #define XENVER_version 0
+
+ /* arg == xen_extraversion_t. */
+ #define XENVER_extraversion 1
+-struct xen_extraversion {
+- char extraversion[16];
+-};
+-#define XEN_EXTRAVERSION_LEN (sizeof(struct xen_extraversion))
++typedef char xen_extraversion_t[16];
++#define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t))
+
+ /* arg == xen_compile_info_t. */
+ #define XENVER_compile_info 2
+@@ -30,31 +46,46 @@ struct xen_compile_info {
+ char compile_domain[32];
+ char compile_date[32];
+ };
++typedef struct xen_compile_info xen_compile_info_t;
+
+ #define XENVER_capabilities 3
+-struct xen_capabilities_info {
+- char info[1024];
+-};
+-#define XEN_CAPABILITIES_INFO_LEN (sizeof(struct xen_capabilities_info))
++typedef char xen_capabilities_info_t[1024];
++#define XEN_CAPABILITIES_INFO_LEN (sizeof(xen_capabilities_info_t))
+
+ #define XENVER_changeset 4
+-struct xen_changeset_info {
+- char info[64];
+-};
+-#define XEN_CHANGESET_INFO_LEN (sizeof(struct xen_changeset_info))
++typedef char xen_changeset_info_t[64];
++#define XEN_CHANGESET_INFO_LEN (sizeof(xen_changeset_info_t))
+
+ #define XENVER_platform_parameters 5
+ struct xen_platform_parameters {
+ unsigned long virt_start;
+ };
++typedef struct xen_platform_parameters xen_platform_parameters_t;
+
+ #define XENVER_get_features 6
+ struct xen_feature_info {
+ unsigned int submap_idx; /* IN: which 32-bit submap to return */
+ uint32_t submap; /* OUT: 32-bit submap */
+ };
++typedef struct xen_feature_info xen_feature_info_t;
+
+ /* Declares the features reported by XENVER_get_features. */
+ #include "features.h"
+
++/* arg == NULL; returns host memory page size. */
++#define XENVER_pagesize 7
++
++/* arg == xen_domain_handle_t. */
++#define XENVER_guest_handle 8
++
+ #endif /* __XEN_PUBLIC_VERSION_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/interface/xen.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/interface/xen.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/interface/xen.h 2008-11-25 12:35:56.000000000 +0100
+@@ -3,35 +3,68 @@
+ *
+ * Guest OS interface to Xen.
+ *
++ * 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.
++ *
+ * Copyright (c) 2004, K A Fraser
+ */
+
+ #ifndef __XEN_PUBLIC_XEN_H__
+ #define __XEN_PUBLIC_XEN_H__
+
+-#include <asm/xen/interface.h>
++#include "xen-compat.h"
++#ifdef CONFIG_PARAVIRT_XEN
+ #include <asm/pvclock-abi.h>
++#endif
+
+-/*
+- * XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
+- */
++#if defined(__i386__) || defined(__x86_64__)
++#include "arch-x86/xen.h"
++#elif defined(__ia64__)
++#include "arch-ia64.h"
++#else
++#error "Unsupported architecture"
++#endif
++
++#ifndef __ASSEMBLY__
++/* Guest handles for primitive C types. */
++DEFINE_XEN_GUEST_HANDLE(char);
++__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
++DEFINE_XEN_GUEST_HANDLE(int);
++__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int);
++DEFINE_XEN_GUEST_HANDLE(long);
++__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
++DEFINE_XEN_GUEST_HANDLE(void);
++
++DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
++#endif
+
+ /*
+- * x86_32: EAX = vector; EBX, ECX, EDX, ESI, EDI = args 1, 2, 3, 4, 5.
+- * EAX = return value
+- * (argument registers may be clobbered on return)
+- * x86_64: RAX = vector; RDI, RSI, RDX, R10, R8, R9 = args 1, 2, 3, 4, 5, 6.
+- * RAX = return value
+- * (argument registers not clobbered on return; RCX, R11 are)
++ * HYPERCALLS
+ */
++
+ #define __HYPERVISOR_set_trap_table 0
+ #define __HYPERVISOR_mmu_update 1
+ #define __HYPERVISOR_set_gdt 2
+ #define __HYPERVISOR_stack_switch 3
+ #define __HYPERVISOR_set_callbacks 4
+ #define __HYPERVISOR_fpu_taskswitch 5
+-#define __HYPERVISOR_sched_op 6
+-#define __HYPERVISOR_dom0_op 7
++#define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */
++#define __HYPERVISOR_platform_op 7
+ #define __HYPERVISOR_set_debugreg 8
+ #define __HYPERVISOR_get_debugreg 9
+ #define __HYPERVISOR_update_descriptor 10
+@@ -39,10 +72,10 @@
+ #define __HYPERVISOR_multicall 13
+ #define __HYPERVISOR_update_va_mapping 14
+ #define __HYPERVISOR_set_timer_op 15
+-#define __HYPERVISOR_event_channel_op_compat 16
++#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
+ #define __HYPERVISOR_xen_version 17
+ #define __HYPERVISOR_console_io 18
+-#define __HYPERVISOR_physdev_op_compat 19
++#define __HYPERVISOR_physdev_op_compat 19 /* compat since 0x00030202 */
+ #define __HYPERVISOR_grant_table_op 20
+ #define __HYPERVISOR_vm_assist 21
+ #define __HYPERVISOR_update_va_mapping_otherdomain 22
+@@ -50,7 +83,7 @@
+ #define __HYPERVISOR_vcpu_op 24
+ #define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
+ #define __HYPERVISOR_mmuext_op 26
+-#define __HYPERVISOR_acm_op 27
++#define __HYPERVISOR_xsm_op 27
+ #define __HYPERVISOR_nmi_op 28
+ #define __HYPERVISOR_sched_op_new 29
+ #define __HYPERVISOR_callback_op 30
+@@ -58,6 +91,9 @@
+ #define __HYPERVISOR_event_channel_op 32
+ #define __HYPERVISOR_physdev_op 33
+ #define __HYPERVISOR_hvm_op 34
++#define __HYPERVISOR_sysctl 35
++#define __HYPERVISOR_domctl 36
++#define __HYPERVISOR_kexec_op 37
+
+ /* Architecture-specific hypercall definitions. */
+ #define __HYPERVISOR_arch_0 48
+@@ -70,15 +106,48 @@
+ #define __HYPERVISOR_arch_7 55
+
+ /*
++ * HYPERCALL COMPATIBILITY.
++ */
++
++/* New sched_op hypercall introduced in 0x00030101. */
++#if __XEN_INTERFACE_VERSION__ < 0x00030101
++#undef __HYPERVISOR_sched_op
++#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat
++#else
++#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_new
++#endif
++
++/* New event-channel and physdev hypercalls introduced in 0x00030202. */
++#if __XEN_INTERFACE_VERSION__ < 0x00030202
++#undef __HYPERVISOR_event_channel_op
++#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
++#undef __HYPERVISOR_physdev_op
++#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
++#endif
++
++/* New platform_op hypercall introduced in 0x00030204. */
++#if __XEN_INTERFACE_VERSION__ < 0x00030204
++#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op
++#endif
++
++/*
+ * VIRTUAL INTERRUPTS
+ *
+ * Virtual interrupts that a guest OS may receive from Xen.
+- */
+-#define VIRQ_TIMER 0 /* Timebase update, and/or requested timeout. */
+-#define VIRQ_DEBUG 1 /* Request guest to dump debug info. */
+-#define VIRQ_CONSOLE 2 /* (DOM0) Bytes received on emergency console. */
+-#define VIRQ_DOM_EXC 3 /* (DOM0) Exceptional event for some domain. */
+-#define VIRQ_DEBUGGER 6 /* (DOM0) A domain has paused for debugging. */
++ *
++ * In the side comments, 'V.' denotes a per-VCPU VIRQ while 'G.' denotes a
++ * global VIRQ. The former can be bound once per VCPU and cannot be re-bound.
++ * The latter can be allocated only once per guest: they must initially be
++ * allocated to VCPU0 but can subsequently be re-bound.
++ */
++#define VIRQ_TIMER 0 /* V. Timebase update, and/or requested timeout. */
++#define VIRQ_DEBUG 1 /* V. Request guest to dump debug info. */
++#define VIRQ_CONSOLE 2 /* G. (DOM0) Bytes received on emergency console. */
++#define VIRQ_DOM_EXC 3 /* G. (DOM0) Exceptional event for some domain. */
++#define VIRQ_TBUF 4 /* G. (DOM0) Trace buffer has records available. */
++#define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */
++#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */
++#define VIRQ_CON_RING 8 /* G. (DOM0) Bytes received on console */
+
+ /* Architecture-specific VIRQ definitions. */
+ #define VIRQ_ARCH_0 16
+@@ -91,6 +158,7 @@
+ #define VIRQ_ARCH_7 23
+
+ #define NR_VIRQS 24
++
+ /*
+ * MMU-UPDATE REQUESTS
+ *
+@@ -166,6 +234,13 @@
+ * cmd: MMUEXT_SET_LDT
+ * linear_addr: Linear address of LDT base (NB. must be page-aligned).
+ * nr_ents: Number of entries in LDT.
++ *
++ * cmd: MMUEXT_CLEAR_PAGE
++ * mfn: Machine frame number to be cleared.
++ *
++ * cmd: MMUEXT_COPY_PAGE
++ * mfn: Machine frame number of the destination page.
++ * src_mfn: Machine frame number of the source page.
+ */
+ #define MMUEXT_PIN_L1_TABLE 0
+ #define MMUEXT_PIN_L2_TABLE 1
+@@ -182,24 +257,34 @@
+ #define MMUEXT_FLUSH_CACHE 12
+ #define MMUEXT_SET_LDT 13
+ #define MMUEXT_NEW_USER_BASEPTR 15
++#define MMUEXT_CLEAR_PAGE 16
++#define MMUEXT_COPY_PAGE 17
+
+ #ifndef __ASSEMBLY__
+ struct mmuext_op {
+- unsigned int cmd;
+- union {
+- /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
+- unsigned long mfn;
+- /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
+- unsigned long linear_addr;
+- } arg1;
+- union {
+- /* SET_LDT */
+- unsigned int nr_ents;
+- /* TLB_FLUSH_MULTI, INVLPG_MULTI */
+- void *vcpumask;
+- } arg2;
++ unsigned int cmd;
++ union {
++ /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR
++ * CLEAR_PAGE, COPY_PAGE */
++ xen_pfn_t mfn;
++ /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
++ unsigned long linear_addr;
++ } arg1;
++ union {
++ /* SET_LDT */
++ unsigned int nr_ents;
++ /* TLB_FLUSH_MULTI, INVLPG_MULTI */
++#if __XEN_INTERFACE_VERSION__ >= 0x00030205
++ XEN_GUEST_HANDLE(void) vcpumask;
++#else
++ void *vcpumask;
++#endif
++ /* COPY_PAGE */
++ xen_pfn_t src_mfn;
++ } arg2;
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(mmuext_op);
++typedef struct mmuext_op mmuext_op_t;
++DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
+ #endif
+
+ /* These are passed as 'flags' to update_va_mapping. They can be ORed. */
+@@ -224,11 +309,24 @@ DEFINE_GUEST_HANDLE_STRUCT(mmuext_op);
+ */
+ #define VMASST_CMD_enable 0
+ #define VMASST_CMD_disable 1
++
++/* x86/32 guests: simulate full 4GB segment limits. */
+ #define VMASST_TYPE_4gb_segments 0
++
++/* x86/32 guests: trap (vector 15) whenever above vmassist is used. */
+ #define VMASST_TYPE_4gb_segments_notify 1
++
++/*
++ * x86 guests: support writes to bottom-level PTEs.
++ * NB1. Page-directory entries cannot be written.
++ * NB2. Guest must continue to remove all writable mappings of PTEs.
++ */
+ #define VMASST_TYPE_writable_pagetables 2
++
++/* x86/PAE guests: support PDPTs above 4GB. */
+ #define VMASST_TYPE_pae_extended_cr3 3
+-#define MAX_VMASST_TYPE 3
++
++#define MAX_VMASST_TYPE 3
+
+ #ifndef __ASSEMBLY__
+
+@@ -267,18 +365,19 @@ struct mmu_update {
+ uint64_t ptr; /* Machine address of PTE. */
+ uint64_t val; /* New contents of PTE. */
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(mmu_update);
++typedef struct mmu_update mmu_update_t;
++DEFINE_XEN_GUEST_HANDLE(mmu_update_t);
+
+ /*
+ * Send an array of these to HYPERVISOR_multicall().
+ * NB. The fields are natural register size for this architecture.
+ */
+ struct multicall_entry {
+- unsigned long op;
+- long result;
++ unsigned long op, result;
+ unsigned long args[6];
+ };
+-DEFINE_GUEST_HANDLE_STRUCT(multicall_entry);
++typedef struct multicall_entry multicall_entry_t;
++DEFINE_XEN_GUEST_HANDLE(multicall_entry_t);
+
+ /*
+ * Event channel endpoints per domain:
+@@ -287,173 +386,240 @@ DEFINE_GUEST_HANDLE_STRUCT(multicall_ent
+ #define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
+
+ struct vcpu_time_info {
+- /*
+- * Updates to the following values are preceded and followed
+- * by an increment of 'version'. The guest can therefore
+- * detect updates by looking for changes to 'version'. If the
+- * least-significant bit of the version number is set then an
+- * update is in progress and the guest must wait to read a
+- * consistent set of values. The correct way to interact with
+- * the version number is similar to Linux's seqlock: see the
+- * implementations of read_seqbegin/read_seqretry.
+- */
+- uint32_t version;
+- uint32_t pad0;
+- uint64_t tsc_timestamp; /* TSC at last update of time vals. */
+- uint64_t system_time; /* Time, in nanosecs, since boot. */
+- /*
+- * Current system time:
+- * system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul
+- * CPU frequency (Hz):
+- * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
+- */
+- uint32_t tsc_to_system_mul;
+- int8_t tsc_shift;
+- int8_t pad1[3];
++ /*
++ * Updates to the following values are preceded and followed by an
++ * increment of 'version'. The guest can therefore detect updates by
++ * looking for changes to 'version'. If the least-significant bit of
++ * the version number is set then an update is in progress and the guest
++ * must wait to read a consistent set of values.
++ * The correct way to interact with the version number is similar to
++ * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
++ */
++ uint32_t version;
++ uint32_t pad0;
++ uint64_t tsc_timestamp; /* TSC at last update of time vals. */
++ uint64_t system_time; /* Time, in nanosecs, since boot. */
++ /*
++ * Current system time:
++ * system_time +
++ * ((((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul) >> 32)
++ * CPU frequency (Hz):
++ * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
++ */
++ uint32_t tsc_to_system_mul;
++ int8_t tsc_shift;
++ int8_t pad1[3];
+ }; /* 32 bytes */
++typedef struct vcpu_time_info vcpu_time_info_t;
+
+ struct vcpu_info {
+- /*
+- * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
+- * a pending notification for a particular VCPU. It is then cleared
+- * by the guest OS /before/ checking for pending work, thus avoiding
+- * a set-and-check race. Note that the mask is only accessed by Xen
+- * on the CPU that is currently hosting the VCPU. This means that the
+- * pending and mask flags can be updated by the guest without special
+- * synchronisation (i.e., no need for the x86 LOCK prefix).
+- * This may seem suboptimal because if the pending flag is set by
+- * a different CPU then an IPI may be scheduled even when the mask
+- * is set. However, note:
+- * 1. The task of 'interrupt holdoff' is covered by the per-event-
+- * channel mask bits. A 'noisy' event that is continually being
+- * triggered can be masked at source at this very precise
+- * granularity.
+- * 2. The main purpose of the per-VCPU mask is therefore to restrict
+- * reentrant execution: whether for concurrency control, or to
+- * prevent unbounded stack usage. Whatever the purpose, we expect
+- * that the mask will be asserted only for short periods at a time,
+- * and so the likelihood of a 'spurious' IPI is suitably small.
+- * The mask is read before making an event upcall to the guest: a
+- * non-zero mask therefore guarantees that the VCPU will not receive
+- * an upcall activation. The mask is cleared when the VCPU requests
+- * to block: this avoids wakeup-waiting races.
+- */
+- uint8_t evtchn_upcall_pending;
+- uint8_t evtchn_upcall_mask;
+- unsigned long evtchn_pending_sel;
+- struct arch_vcpu_info arch;
+- struct pvclock_vcpu_time_info time;
++ /*
++ * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
++ * a pending notification for a particular VCPU. It is then cleared
++ * by the guest OS /before/ checking for pending work, thus avoiding
++ * a set-and-check race. Note that the mask is only accessed by Xen
++ * on the CPU that is currently hosting the VCPU. This means that the
++ * pending and mask flags can be updated by the guest without special
++ * synchronisation (i.e., no need for the x86 LOCK prefix).
++ * This may seem suboptimal because if the pending flag is set by
++ * a different CPU then an IPI may be scheduled even when the mask
++ * is set. However, note:
++ * 1. The task of 'interrupt holdoff' is covered by the per-event-
++ * channel mask bits. A 'noisy' event that is continually being
++ * triggered can be masked at source at this very precise
++ * granularity.
++ * 2. The main purpose of the per-VCPU mask is therefore to restrict
++ * reentrant execution: whether for concurrency control, or to
++ * prevent unbounded stack usage. Whatever the purpose, we expect
++ * that the mask will be asserted only for short periods at a time,
++ * and so the likelihood of a 'spurious' IPI is suitably small.
++ * The mask is read before making an event upcall to the guest: a
++ * non-zero mask therefore guarantees that the VCPU will not receive
++ * an upcall activation. The mask is cleared when the VCPU requests
++ * to block: this avoids wakeup-waiting races.
++ */
++ uint8_t evtchn_upcall_pending;
++ uint8_t evtchn_upcall_mask;
++ unsigned long evtchn_pending_sel;
++ struct arch_vcpu_info arch;
++#ifdef CONFIG_PARAVIRT_XEN
++ struct pvclock_vcpu_time_info time;
++#else
++ struct vcpu_time_info time;
++#endif
+ }; /* 64 bytes (x86) */
++#ifndef __XEN__
++typedef struct vcpu_info vcpu_info_t;
++#endif
+
+ /*
+ * Xen/kernel shared data -- pointer provided in start_info.
+- * NB. We expect that this struct is smaller than a page.
++ *
++ * This structure is defined to be both smaller than a page, and the
++ * only data on the shared page, but may vary in actual size even within
++ * compatible Xen versions; guests should not rely on the size
++ * of this structure remaining constant.
+ */
+ struct shared_info {
+- struct vcpu_info vcpu_info[MAX_VIRT_CPUS];
++ struct vcpu_info vcpu_info[MAX_VIRT_CPUS];
+
+- /*
+- * A domain can create "event channels" on which it can send and receive
+- * asynchronous event notifications. There are three classes of event that
+- * are delivered by this mechanism:
+- * 1. Bi-directional inter- and intra-domain connections. Domains must
+- * arrange out-of-band to set up a connection (usually by allocating
+- * an unbound 'listener' port and avertising that via a storage service
+- * such as xenstore).
+- * 2. Physical interrupts. A domain with suitable hardware-access
+- * privileges can bind an event-channel port to a physical interrupt
+- * source.
+- * 3. Virtual interrupts ('events'). A domain can bind an event-channel
+- * port to a virtual interrupt source, such as the virtual-timer
+- * device or the emergency console.
+- *
+- * Event channels are addressed by a "port index". Each channel is
+- * associated with two bits of information:
+- * 1. PENDING -- notifies the domain that there is a pending notification
+- * to be processed. This bit is cleared by the guest.
+- * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING
+- * will cause an asynchronous upcall to be scheduled. This bit is only
+- * updated by the guest. It is read-only within Xen. If a channel
+- * becomes pending while the channel is masked then the 'edge' is lost
+- * (i.e., when the channel is unmasked, the guest must manually handle
+- * pending notifications as no upcall will be scheduled by Xen).
+- *
+- * To expedite scanning of pending notifications, any 0->1 pending
+- * transition on an unmasked channel causes a corresponding bit in a
+- * per-vcpu selector word to be set. Each bit in the selector covers a
+- * 'C long' in the PENDING bitfield array.
+- */
+- unsigned long evtchn_pending[sizeof(unsigned long) * 8];
+- unsigned long evtchn_mask[sizeof(unsigned long) * 8];
+-
+- /*
+- * Wallclock time: updated only by control software. Guests should base
+- * their gettimeofday() syscall on this wallclock-base value.
+- */
+- struct pvclock_wall_clock wc;
++ /*
++ * A domain can create "event channels" on which it can send and receive
++ * asynchronous event notifications. There are three classes of event that
++ * are delivered by this mechanism:
++ * 1. Bi-directional inter- and intra-domain connections. Domains must
++ * arrange out-of-band to set up a connection (usually by allocating
++ * an unbound 'listener' port and avertising that via a storage service
++ * such as xenstore).
++ * 2. Physical interrupts. A domain with suitable hardware-access
++ * privileges can bind an event-channel port to a physical interrupt
++ * source.
++ * 3. Virtual interrupts ('events'). A domain can bind an event-channel
++ * port to a virtual interrupt source, such as the virtual-timer
++ * device or the emergency console.
++ *
++ * Event channels are addressed by a "port index". Each channel is
++ * associated with two bits of information:
++ * 1. PENDING -- notifies the domain that there is a pending notification
++ * to be processed. This bit is cleared by the guest.
++ * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING
++ * will cause an asynchronous upcall to be scheduled. This bit is only
++ * updated by the guest. It is read-only within Xen. If a channel
++ * becomes pending while the channel is masked then the 'edge' is lost
++ * (i.e., when the channel is unmasked, the guest must manually handle
++ * pending notifications as no upcall will be scheduled by Xen).
++ *
++ * To expedite scanning of pending notifications, any 0->1 pending
++ * transition on an unmasked channel causes a corresponding bit in a
++ * per-vcpu selector word to be set. Each bit in the selector covers a
++ * 'C long' in the PENDING bitfield array.
++ */
++ unsigned long evtchn_pending[sizeof(unsigned long) * 8];
++ unsigned long evtchn_mask[sizeof(unsigned long) * 8];
++
++ /*
++ * Wallclock time: updated only by control software. Guests should base
++ * their gettimeofday() syscall on this wallclock-base value.
++ */
++#ifdef CONFIG_PARAVIRT_XEN
++ struct pvclock_wall_clock wc;
++#else
++ uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */
++ uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */
++ uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */
++#endif
+
+- struct arch_shared_info arch;
++ struct arch_shared_info arch;
+
+ };
++#ifndef __XEN__
++typedef struct shared_info shared_info_t;
++#endif
+
+ /*
+- * Start-of-day memory layout for the initial domain (DOM0):
++ * Start-of-day memory layout:
+ * 1. The domain is started within contiguous virtual-memory region.
+- * 2. The contiguous region begins and ends on an aligned 4MB boundary.
+- * 3. The region start corresponds to the load address of the OS image.
+- * If the load address is not 4MB aligned then the address is rounded down.
+- * 4. This the order of bootstrap elements in the initial virtual region:
++ * 2. The contiguous region ends on an aligned 4MB boundary.
++ * 3. This the order of bootstrap elements in the initial virtual region:
+ * a. relocated kernel image
+ * b. initial ram disk [mod_start, mod_len]
+ * c. list of allocated page frames [mfn_list, nr_pages]
+ * d. start_info_t structure [register ESI (x86)]
+ * e. bootstrap page tables [pt_base, CR3 (x86)]
+ * f. bootstrap stack [register ESP (x86)]
+- * 5. Bootstrap elements are packed together, but each is 4kB-aligned.
+- * 6. The initial ram disk may be omitted.
+- * 7. The list of page frames forms a contiguous 'pseudo-physical' memory
++ * 4. Bootstrap elements are packed together, but each is 4kB-aligned.
++ * 5. The initial ram disk may be omitted.
++ * 6. The list of page frames forms a contiguous 'pseudo-physical' memory
+ * layout for the domain. In particular, the bootstrap virtual-memory
+ * region is a 1:1 mapping to the first section of the pseudo-physical map.
+- * 8. All bootstrap elements are mapped read-writable for the guest OS. The
++ * 7. All bootstrap elements are mapped read-writable for the guest OS. The
+ * only exception is the bootstrap page table, which is mapped read-only.
+- * 9. There is guaranteed to be at least 512kB padding after the final
++ * 8. There is guaranteed to be at least 512kB padding after the final
+ * bootstrap element. If necessary, the bootstrap virtual region is
+ * extended by an extra 4MB to ensure this.
+ */
+
+ #define MAX_GUEST_CMDLINE 1024
+ struct start_info {
+- /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
+- char magic[32]; /* "xen-<version>-<platform>". */
+- unsigned long nr_pages; /* Total pages allocated to this domain. */
+- unsigned long shared_info; /* MACHINE address of shared info struct. */
+- uint32_t flags; /* SIF_xxx flags. */
+- unsigned long store_mfn; /* MACHINE page number of shared page. */
+- uint32_t store_evtchn; /* Event channel for store communication. */
+- union {
+- struct {
+- unsigned long mfn; /* MACHINE page number of console page. */
+- uint32_t evtchn; /* Event channel for console page. */
+- } domU;
+- struct {
+- uint32_t info_off; /* Offset of console_info struct. */
+- uint32_t info_size; /* Size of console_info struct from start.*/
+- } dom0;
+- } console;
+- /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
+- unsigned long pt_base; /* VIRTUAL address of page directory. */
+- unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. */
+- unsigned long mfn_list; /* VIRTUAL address of page-frame list. */
+- unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */
+- unsigned long mod_len; /* Size (bytes) of pre-loaded module. */
+- int8_t cmd_line[MAX_GUEST_CMDLINE];
++ /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
++ char magic[32]; /* "xen-<version>-<platform>". */
++ unsigned long nr_pages; /* Total pages allocated to this domain. */
++ unsigned long shared_info; /* MACHINE address of shared info struct. */
++ uint32_t flags; /* SIF_xxx flags. */
++ xen_pfn_t store_mfn; /* MACHINE page number of shared page. */
++ uint32_t store_evtchn; /* Event channel for store communication. */
++ union {
++ struct {
++ xen_pfn_t mfn; /* MACHINE page number of console page. */
++ uint32_t evtchn; /* Event channel for console page. */
++ } domU;
++ struct {
++ uint32_t info_off; /* Offset of console_info struct. */
++ uint32_t info_size; /* Size of console_info struct from start.*/
++ } dom0;
++ } console;
++ /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
++ unsigned long pt_base; /* VIRTUAL address of page directory. */
++ unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. */
++ unsigned long mfn_list; /* VIRTUAL address of page-frame list. */
++ unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */
++ unsigned long mod_len; /* Size (bytes) of pre-loaded module. */
++ int8_t cmd_line[MAX_GUEST_CMDLINE];
+ };
++typedef struct start_info start_info_t;
++
++/* New console union for dom0 introduced in 0x00030203. */
++#if __XEN_INTERFACE_VERSION__ < 0x00030203
++#define console_mfn console.domU.mfn
++#define console_evtchn console.domU.evtchn
++#endif
+
+ /* These flags are passed in the 'flags' field of start_info_t. */
+ #define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */
+ #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */
++#define SIF_PM_MASK (0xFF<<8) /* reserve 1 byte for xen-pm options */
+
+-typedef uint64_t cpumap_t;
++typedef struct dom0_vga_console_info {
++ uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */
++#define XEN_VGATYPE_TEXT_MODE_3 0x03
++#define XEN_VGATYPE_VESA_LFB 0x23
++
++ union {
++ struct {
++ /* Font height, in pixels. */
++ uint16_t font_height;
++ /* Cursor location (column, row). */
++ uint16_t cursor_x, cursor_y;
++ /* Number of rows and columns (dimensions in characters). */
++ uint16_t rows, columns;
++ } text_mode_3;
++
++ struct {
++ /* Width and height, in pixels. */
++ uint16_t width, height;
++ /* Bytes per scan line. */
++ uint16_t bytes_per_line;
++ /* Bits per pixel. */
++ uint16_t bits_per_pixel;
++ /* LFB physical address, and size (in units of 64kB). */
++ uint32_t lfb_base;
++ uint32_t lfb_size;
++ /* RGB mask offsets and sizes, as defined by VBE 1.2+ */
++ uint8_t red_pos, red_size;
++ uint8_t green_pos, green_size;
++ uint8_t blue_pos, blue_size;
++ uint8_t rsvd_pos, rsvd_size;
++#if __XEN_INTERFACE_VERSION__ >= 0x00030206
++ /* VESA capabilities (offset 0xa, VESA command 0x4f00). */
++ uint32_t gbl_caps;
++ /* Mode attributes (offset 0x0, VESA command 0x4f01). */
++ uint16_t mode_attrs;
++#endif
++ } vesa_lfb;
++ } u;
++} dom0_vga_console_info_t;
++#define xen_vga_console_info dom0_vga_console_info
++#define xen_vga_console_info_t dom0_vga_console_info_t
+
+ typedef uint8_t xen_domain_handle_t[16];
+
+@@ -461,6 +627,11 @@ typedef uint8_t xen_domain_handle_t[16];
+ #define __mk_unsigned_long(x) x ## UL
+ #define mk_unsigned_long(x) __mk_unsigned_long(x)
+
++__DEFINE_XEN_GUEST_HANDLE(uint8, uint8_t);
++__DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t);
++__DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t);
++__DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t);
++
+ #else /* __ASSEMBLY__ */
+
+ /* In assembly code we cannot use C numeric constant suffixes. */
+@@ -468,4 +639,24 @@ typedef uint8_t xen_domain_handle_t[16];
+
+ #endif /* !__ASSEMBLY__ */
+
++/* Default definitions for macros used by domctl/sysctl. */
++#if defined(__XEN__) || defined(__XEN_TOOLS__)
++#ifndef uint64_aligned_t
++#define uint64_aligned_t uint64_t
++#endif
++#ifndef XEN_GUEST_HANDLE_64
++#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name)
++#endif
++#endif
++
+ #endif /* __XEN_PUBLIC_XEN_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-set-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+Index: head-2008-11-25/include/xen/xenbus.h
+===================================================================
+--- head-2008-11-25.orig/include/xen/xenbus.h 2008-11-25 12:33:06.000000000 +0100
++++ head-2008-11-25/include/xen/xenbus.h 2008-11-25 12:35:56.000000000 +0100
+@@ -39,6 +39,7 @@
+ #include <linux/mutex.h>
+ #include <linux/completion.h>
+ #include <linux/init.h>
++#include <linux/err.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/grant_table.h>
+ #include <xen/interface/io/xenbus.h>
+@@ -55,8 +56,17 @@ struct xenbus_watch
+ /* Callback (executed in a process context with no locks held). */
+ void (*callback)(struct xenbus_watch *,
+ const char **vec, unsigned int len);
++
++ /* See XBWF_ definitions below. */
++ unsigned long flags;
+ };
+
++/*
++ * Execute callback in its own kthread. Useful if the callback is long
++ * running or heavily serialised, to avoid taking out the main xenwatch thread
++ * for a long period of time (or even unwittingly causing a deadlock).
++ */
++#define XBWF_new_thread 1
+
+ /* A xenbus device. */
+ struct xenbus_device {
+@@ -105,27 +115,8 @@ static inline struct xenbus_driver *to_x
+ return container_of(drv, struct xenbus_driver, driver);
+ }
+
+-int __must_check __xenbus_register_frontend(struct xenbus_driver *drv,
+- struct module *owner,
+- const char *mod_name);
+-
+-static inline int __must_check
+-xenbus_register_frontend(struct xenbus_driver *drv)
+-{
+- WARN_ON(drv->owner != THIS_MODULE);
+- return __xenbus_register_frontend(drv, THIS_MODULE, KBUILD_MODNAME);
+-}
+-
+-int __must_check __xenbus_register_backend(struct xenbus_driver *drv,
+- struct module *owner,
+- const char *mod_name);
+-static inline int __must_check
+-xenbus_register_backend(struct xenbus_driver *drv)
+-{
+- WARN_ON(drv->owner != THIS_MODULE);
+- return __xenbus_register_backend(drv, THIS_MODULE, KBUILD_MODNAME);
+-}
+-
++int xenbus_register_frontend(struct xenbus_driver *drv);
++int xenbus_register_backend(struct xenbus_driver *drv);
+ void xenbus_unregister_driver(struct xenbus_driver *drv);
+
+ struct xenbus_transaction
+@@ -136,8 +127,6 @@ struct xenbus_transaction
+ /* Nil transaction ID. */
+ #define XBT_NIL ((struct xenbus_transaction) { 0 })
+
+-int __init xenbus_dev_init(void);
+-
+ char **xenbus_directory(struct xenbus_transaction t,
+ const char *dir, const char *node, unsigned int *num);
+ void *xenbus_read(struct xenbus_transaction t,
+@@ -167,7 +156,6 @@ int xenbus_printf(struct xenbus_transact
+ int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
+
+ /* notifer routines for when the xenstore comes up */
+-extern int xenstored_ready;
+ int register_xenstore_notifier(struct notifier_block *nb);
+ void unregister_xenstore_notifier(struct notifier_block *nb);
+
+@@ -180,12 +168,9 @@ void xs_suspend_cancel(void);
+ /* Used by xenbus_dev to borrow kernel's store connection. */
+ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
+
+-struct work_struct;
+-
+ /* Prepare for domain suspend: then resume or cancel the suspend. */
+ void xenbus_suspend(void);
+ void xenbus_resume(void);
+-void xenbus_probe(struct work_struct *);
+ void xenbus_suspend_cancel(void);
+
+ #define XENBUS_IS_ERR_READ(str) ({ \
+@@ -198,38 +183,125 @@ void xenbus_suspend_cancel(void);
+
+ #define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
+
++
++/**
++ * Register a watch on the given path, using the given xenbus_watch structure
++ * for storage, and the given callback function as the callback. Return 0 on
++ * success, or -errno on error. On success, the given path will be saved as
++ * watch->node, and remains the caller's to free. On error, watch->node will
++ * be NULL, the device will switch to XenbusStateClosing, and the error will
++ * be saved in the store.
++ */
+ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
+ struct xenbus_watch *watch,
+ void (*callback)(struct xenbus_watch *,
+ const char **, unsigned int));
+-int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch,
+- void (*callback)(struct xenbus_watch *,
+- const char **, unsigned int),
+- const char *pathfmt, ...)
+- __attribute__ ((format (printf, 4, 5)));
+
++
++/**
++ * Register a watch on the given path/path2, using the given xenbus_watch
++ * structure for storage, and the given callback function as the callback.
++ * Return 0 on success, or -errno on error. On success, the watched path
++ * (path/path2) will be saved as watch->node, and becomes the caller's to
++ * kfree(). On error, watch->node will be NULL, so the caller has nothing to
++ * free, the device will switch to XenbusStateClosing, and the error will be
++ * saved in the store.
++ */
++int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
++ const char *path2, struct xenbus_watch *watch,
++ void (*callback)(struct xenbus_watch *,
++ const char **, unsigned int));
++
++
++/**
++ * Advertise in the store a change of the given driver to the given new_state.
++ * Return 0 on success, or -errno on error. On error, the device will switch
++ * to XenbusStateClosing, and the error will be saved in the store.
++ */
+ int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state new_state);
++
++
++/**
++ * Grant access to the given ring_mfn to the peer of the given device. Return
++ * 0 on success, or -errno on error. On error, the device will switch to
++ * XenbusStateClosing, and the error will be saved in the store.
++ */
+ int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
+-int xenbus_map_ring_valloc(struct xenbus_device *dev,
+- int gnt_ref, void **vaddr);
++
++
++/**
++ * Map a page of memory into this domain from another domain's grant table.
++ * xenbus_map_ring_valloc allocates a page of virtual address space, maps the
++ * page to that address, and sets *vaddr to that address.
++ * xenbus_map_ring does not allocate the virtual address space (you must do
++ * this yourself!). It only maps in the page to the specified address.
++ * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
++ * or -ENOMEM on error. If an error is returned, device will switch to
++ * XenbusStateClosing and the error message will be saved in XenStore.
++ */
++struct vm_struct *xenbus_map_ring_valloc(struct xenbus_device *dev,
++ int gnt_ref);
+ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
+ grant_handle_t *handle, void *vaddr);
+
+-int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr);
++
++/**
++ * Unmap a page of memory in this domain that was imported from another domain.
++ * Use xenbus_unmap_ring_vfree if you mapped in your memory with
++ * xenbus_map_ring_valloc (it will free the virtual address space).
++ * Returns 0 on success and returns GNTST_* on error
++ * (see xen/include/interface/grant_table.h).
++ */
++int xenbus_unmap_ring_vfree(struct xenbus_device *dev, struct vm_struct *);
+ int xenbus_unmap_ring(struct xenbus_device *dev,
+ grant_handle_t handle, void *vaddr);
+
++
++/**
++ * Allocate an event channel for the given xenbus_device, assigning the newly
++ * created local port to *port. Return 0 on success, or -errno on error. On
++ * error, the device will switch to XenbusStateClosing, and the error will be
++ * saved in the store.
++ */
+ int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
+-int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port);
++
++
++/**
++ * Free an existing event channel. Returns 0 on success or -errno on error.
++ */
+ int xenbus_free_evtchn(struct xenbus_device *dev, int port);
+
++
++/**
++ * Return the state of the driver rooted at the given store path, or
++ * XenbusStateUnknown if no state can be read.
++ */
+ enum xenbus_state xenbus_read_driver_state(const char *path);
+
+-void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...);
+-void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...);
++
++/***
++ * Report the given negative errno into the store, along with the given
++ * formatted message.
++ */
++void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
++ ...);
++
++
++/***
++ * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
++ * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
++ * closedown of this driver and its peer.
++ */
++void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
++ ...);
++
++int xenbus_dev_init(void);
+
+ const char *xenbus_strstate(enum xenbus_state state);
+ int xenbus_dev_is_online(struct xenbus_device *dev);
+ int xenbus_frontend_closed(struct xenbus_device *dev);
+
++int xenbus_for_each_backend(void *arg, int (*fn)(struct device *, void *));
++int xenbus_for_each_frontend(void *arg, int (*fn)(struct device *, void *));
++
+ #endif /* _XEN_XENBUS_H */