WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 26 Oct 2006 12:11:38 +0000
Delivery-date: Thu, 26 Oct 2006 05:19:37 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 3e26719ab827f249e8fefa310db1c1a45af2f1e0
# Parent  d246b79986d12e99db87339ba57bdac067950ec5
# Parent  abee5c6b930daae7b97ca2837591b737e939ddf4
merge with xen-unstable.hg
---
 xen/include/asm-x86/hvm/vpit.h                                          |  139 
----
 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c                      |   10 
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c                    |   25 
 linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c                         |   10 
 linux-2.6-xen-sparse/drivers/xen/core/features.c                        |    4 
 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c                          |    4 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c                    |    4 
 linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile                        |    1 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c                 |    4 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c                  |    4 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c                    |    5 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c                  |  260 
+------
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h                  |   77 
++
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c          |  271 
++++++++
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c                     |    6 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h       |    4 
 linux-2.6-xen-sparse/include/xen/xenbus.h                               |    1 
 tools/blktap/drivers/blktapctrl.c                                       |  104 
+--
 tools/blktap/drivers/tapdisk.c                                          |   58 
-
 tools/blktap/drivers/tapdisk.h                                          |    8 
 tools/firmware/acpi/acpi_fadt.h                                         |    9 
 tools/ioemu/vl.c                                                        |   10 
 tools/ioemu/vnc.c                                                       |    2 
 tools/libxc/Makefile                                                    |    2 
 tools/libxc/ia64/xc_ia64_hvm_build.c                                    |   10 
 tools/libxc/xc_linux_build.c                                            |    2 
 tools/libxc/xc_linux_restore.c                                          |    2 
 tools/libxc/xc_linux_save.c                                             |    2 
 tools/libxc/xc_private.c                                                |   18 
 tools/python/xen/xend/image.py                                          |   11 
 tools/python/xen/xend/server/SrvDaemon.py                               |    7 
 tools/xenstat/xentop/xentop.1                                           |    3 
 tools/xenstat/xentop/xentop.c                                           |    6 
 tools/xm-test/lib/XmTestLib/arch.py                                     |    3 
 unmodified_drivers/linux-2.6/blkfront/Makefile                          |    3 
 unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopmd.h |   14 
 unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h |   14 
 unmodified_drivers/linux-2.6/compat-include/linux/io.h                  |   10 
 unmodified_drivers/linux-2.6/compat-include/linux/mutex.h               |   31 
 unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h       |   52 
+
 unmodified_drivers/linux-2.6/netfront/Makefile                          |    3 
 unmodified_drivers/linux-2.6/overrides.mk                               |    2 
 unmodified_drivers/linux-2.6/platform-pci/Kbuild                        |    2 
 unmodified_drivers/linux-2.6/platform-pci/Makefile                      |    3 
 unmodified_drivers/linux-2.6/platform-pci/evtchn.c                      |    4 
 unmodified_drivers/linux-2.6/platform-pci/platform-compat.c             |  116 
+++
 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c                |    5 
 unmodified_drivers/linux-2.6/platform-pci/xen_support.c                 |    4 
 unmodified_drivers/linux-2.6/xenbus/Makefile                            |    3 
 xen/arch/ia64/vmx/mmio.c                                                |   70 
++
 xen/arch/ia64/vmx/vmx_init.c                                            |   14 
 xen/arch/x86/Makefile                                                   |    2 
 xen/arch/x86/hvm/Makefile                                               |    1 
 xen/arch/x86/hvm/hvm.c                                                  |    3 
 xen/arch/x86/hvm/i8254.c                                                |    2 
 xen/arch/x86/hvm/io.c                                                   |    2 
 xen/arch/x86/hvm/pmtimer.c                                              |   63 
+
 xen/arch/x86/hvm/rtc.c                                                  |    2 
 xen/arch/x86/hvm/svm/svm.c                                              |    3 
 xen/arch/x86/hvm/vmx/vmx.c                                              |    3 
 xen/arch/x86/numa.c                                                     |  308 
+++++++++
 xen/arch/x86/setup.c                                                    |   30 
 xen/arch/x86/smpboot.c                                                  |    3 
 xen/arch/x86/srat.c                                                     |  315 
+++++++++
 xen/common/memory.c                                                     |   21 
 xen/common/page_alloc.c                                                 |  209 
++++--
 xen/drivers/acpi/Makefile                                               |    1 
 xen/drivers/acpi/numa.c                                                 |  216 
++++++
 xen/include/asm-ia64/vmx_platform.h                                     |    2 
 xen/include/asm-x86/acpi.h                                              |    4 
 xen/include/asm-x86/config.h                                            |    5 
 xen/include/asm-x86/hvm/domain.h                                        |    2 
 xen/include/asm-x86/hvm/vpt.h                                           |  151 
++++
 xen/include/asm-x86/mach-generic/mach_apic.h                            |    6 
 xen/include/asm-x86/numa.h                                              |   78 
++
 xen/include/public/arch-ia64.h                                          |    3 
 xen/include/public/hvm/ioreq.h                                          |    4 
 xen/include/xen/config.h                                                |    2 
 xen/include/xen/mm.h                                                    |    7 
 xen/include/xen/nodemask.h                                              |  338 
++++++++++
 xen/include/xen/numa.h                                                  |   13 
 81 files changed, 2656 insertions(+), 579 deletions(-)

diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Wed Oct 25 
12:12:01 2006 -0600
@@ -392,16 +392,24 @@ static void dispatch_rw_block_io(blkif_t
        for (i = 0; i < nseg; i++) {
                if (unlikely(map[i].status != 0)) {
                        DPRINTK("invalid buffer -- could not remap it\n");
-                       goto fail_flush;
+                       map[i].handle = BLKBACK_INVALID_HANDLE;
+                       ret |= 1;
                }
 
                pending_handle(pending_req, i) = map[i].handle;
+
+               if (ret)
+                       continue;
+
                set_phys_to_machine(__pa(vaddr(
                        pending_req, i)) >> PAGE_SHIFT,
                        FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
                seg[i].buf  = map[i].dev_bus_addr | 
                        (req->seg[i].first_sect << 9);
        }
+
+       if (ret)
+               goto fail_flush;
 
        if (vbd_translate(&preq, blkif, operation) != 0) {
                DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", 
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Oct 25 
12:12:01 2006 -0600
@@ -48,6 +48,10 @@
 #include <asm/hypervisor.h>
 #include <asm/maddr.h>
 
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
 #define BLKIF_STATE_DISCONNECTED 0
 #define BLKIF_STATE_CONNECTED    1
 #define BLKIF_STATE_SUSPENDED    2
@@ -468,6 +472,27 @@ int blkif_ioctl(struct inode *inode, str
                      command, (long)argument, inode->i_rdev);
 
        switch (command) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
+       case HDIO_GETGEO: {
+               struct block_device *bd = inode->i_bdev;
+               struct hd_geometry geo;
+               int ret;
+
+                if (!argument)
+                        return -EINVAL;
+
+               geo.start = get_start_sect(bd);
+               ret = blkif_getgeo(bd, &geo);
+               if (ret)
+                       return ret;
+
+               if (copy_to_user((struct hd_geometry __user *)argument, &geo,
+                                sizeof(geo)))
+                        return -EFAULT;
+
+                return 0;
+       }
+#endif
        case CDROMMULTISESSION:
                DPRINTK("FIXME: support multisession CDs later\n");
                for (i = 0; i < sizeof(struct cdrom_multisession); i++)
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Tue Oct 24 11:21:48 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Wed Oct 25 12:12:01 
2006 -0600
@@ -36,6 +36,10 @@
 #include <linux/blkdev.h>
 #include <linux/list.h>
 
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
 #define BLKIF_MAJOR(dev) ((dev)>>8)
 #define BLKIF_MINOR(dev) ((dev) & 0xff)
 
@@ -91,7 +95,9 @@ static struct block_device_operations xl
        .open = blkif_open,
        .release = blkif_release,
        .ioctl  = blkif_ioctl,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
        .getgeo = blkif_getgeo
+#endif
 };
 
 DEFINE_SPINLOCK(blkif_io_lock);
@@ -186,7 +192,11 @@ xlvbd_init_blk_queue(struct gendisk *gd,
        if (rq == NULL)
                return -1;
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
        elevator_init(rq, "noop");
+#else
+       elevator_init(rq, &elevator_noop);
+#endif
 
        /* Hard sector size and max sectors impersonate the equiv. hardware. */
        blk_queue_hardsect_size(rq, sector_size);
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/core/features.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/features.c  Tue Oct 24 11:21:48 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/features.c  Wed Oct 25 12:12:01 
2006 -0600
@@ -10,6 +10,10 @@
 #include <linux/module.h>
 #include <asm/hypervisor.h>
 #include <xen/features.h>
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
 
 u8 xen_features[XENFEAT_NR_SUBMAPS * 32] __read_mostly;
 /* Not a GPL symbol: used in ubiquitous macros, so too restrictive. */
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Tue Oct 24 11:21:48 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Wed Oct 25 12:12:01 
2006 -0600
@@ -44,6 +44,10 @@
 #include <asm/io.h>
 #include <xen/interface/memory.h>
 
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
 /* External tools reserve first few grant table entries. */
 #define NR_RESERVED_ENTRIES 8
 
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Oct 25 
12:12:01 2006 -0600
@@ -64,6 +64,10 @@
 #include <xen/interface/grant_table.h>
 #include <xen/gnttab.h>
 
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
 /*
  * Mutually-exclusive module options to select receive data path:
  *  rx_copy : Packets are copied by network backend into local memory
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Tue Oct 24 11:21:48 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Wed Oct 25 12:12:01 
2006 -0600
@@ -9,4 +9,5 @@ xenbus-objs += xenbus_comms.o
 xenbus-objs += xenbus_comms.o
 xenbus-objs += xenbus_xs.o
 xenbus-objs += xenbus_probe.o
+obj-$(CONFIG_XEN_BACKEND) += xenbus_probe_backend.o
 obj-$(CONFIG_XEN_XENBUS_DEV) += xenbus_dev.o
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Wed Oct 25 
12:12:01 2006 -0600
@@ -34,6 +34,10 @@
 #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
 
 /* xenbus_probe.c */
 extern char *kasprintf(const char *fmt, ...);
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Wed Oct 25 
12:12:01 2006 -0600
@@ -39,6 +39,10 @@
 #include <xen/xenbus.h>
 #include "xenbus_comms.h"
 
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
 static int xenbus_irq;
 
 extern void xenbus_probe(void *);
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Wed Oct 25 
12:12:01 2006 -0600
@@ -40,6 +40,7 @@
 #include <linux/wait.h>
 #include <linux/fs.h>
 #include <linux/poll.h>
+#include <linux/mutex.h>
 
 #include "xenbus_comms.h"
 
@@ -48,6 +49,10 @@
 #include <xen/xenbus.h>
 #include <xen/xen_proc.h>
 #include <asm/hypervisor.h>
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
 
 struct xenbus_dev_transaction {
        struct list_head list;
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Wed Oct 25 
12:12:01 2006 -0600
@@ -42,6 +42,7 @@
 #include <linux/mm.h>
 #include <linux/notifier.h>
 #include <linux/kthread.h>
+#include <linux/mutex.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -55,6 +56,11 @@
 #include <xen/hvm.h>
 
 #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;
@@ -67,12 +73,7 @@ static void wait_for_devices(struct xenb
 static void wait_for_devices(struct xenbus_driver *xendrv);
 
 static int xenbus_probe_frontend(const char *type, const char *name);
-static int xenbus_uevent_backend(struct device *dev, char **envp,
-                                int num_envp, char *buffer, int buffer_size);
-static int xenbus_probe_backend(const char *type, const char *domid);
-
-static int xenbus_dev_probe(struct device *_dev);
-static int xenbus_dev_remove(struct device *_dev);
+
 static void xenbus_dev_shutdown(struct device *_dev);
 
 /* If something in array of ids matches this device, return it. */
@@ -86,7 +87,7 @@ match_device(const struct xenbus_device_
        return NULL;
 }
 
-static int xenbus_match(struct device *_dev, struct device_driver *_drv)
+int xenbus_match(struct device *_dev, struct device_driver *_drv)
 {
        struct xenbus_driver *drv = to_xenbus_driver(_drv);
 
@@ -95,17 +96,6 @@ static int xenbus_match(struct device *_
 
        return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
 }
-
-struct xen_bus_type
-{
-       char *root;
-       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;
-};
-
 
 /* device/<type>/<id> => <type>-<id> */
 static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
@@ -143,7 +133,7 @@ static void free_otherend_watch(struct x
 }
 
 
-static int read_otherend_details(struct xenbus_device *xendev,
+int read_otherend_details(struct xenbus_device *xendev,
                                 char *id_node, char *path_node)
 {
        int err = xenbus_gather(XBT_NIL, xendev->nodename,
@@ -176,12 +166,6 @@ static int read_backend_details(struct x
 }
 
 
-static int read_frontend_details(struct xenbus_device *xendev)
-{
-       return read_otherend_details(xendev, "frontend-id", "frontend");
-}
-
-
 /* Bus type for frontend drivers. */
 static struct xen_bus_type xenbus_frontend = {
        .root = "device",
@@ -191,114 +175,16 @@ static struct xen_bus_type xenbus_fronte
        .bus = {
                .name     = "xen",
                .match    = xenbus_match,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
                .probe    = xenbus_dev_probe,
                .remove   = xenbus_dev_remove,
                .shutdown = xenbus_dev_shutdown,
+#endif
        },
        .dev = {
                .bus_id = "xen",
        },
 };
-
-/* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
-static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
-{
-       int domid, err;
-       const char *devid, *type, *frontend;
-       unsigned int typelen;
-
-       type = strchr(nodename, '/');
-       if (!type)
-               return -EINVAL;
-       type++;
-       typelen = strcspn(type, "/");
-       if (!typelen || type[typelen] != '/')
-               return -EINVAL;
-
-       devid = strrchr(nodename, '/') + 1;
-
-       err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
-                           "frontend", NULL, &frontend,
-                           NULL);
-       if (err)
-               return err;
-       if (strlen(frontend) == 0)
-               err = -ERANGE;
-       if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
-               err = -ENOENT;
-
-       kfree(frontend);
-
-       if (err)
-               return err;
-
-       if (snprintf(bus_id, BUS_ID_SIZE,
-                    "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
-               return -ENOSPC;
-       return 0;
-}
-
-static struct xen_bus_type xenbus_backend = {
-       .root = "backend",
-       .levels = 3,            /* backend/type/<frontend>/<id> */
-       .get_bus_id = backend_bus_id,
-       .probe = xenbus_probe_backend,
-       .bus = {
-               .name     = "xen-backend",
-               .match    = xenbus_match,
-               .probe    = xenbus_dev_probe,
-               .remove   = xenbus_dev_remove,
-//             .shutdown = xenbus_dev_shutdown,
-               .uevent   = xenbus_uevent_backend,
-       },
-       .dev = {
-               .bus_id = "xen-backend",
-       },
-};
-
-static int xenbus_uevent_backend(struct device *dev, char **envp,
-                                int num_envp, char *buffer, int buffer_size)
-{
-       struct xenbus_device *xdev;
-       struct xenbus_driver *drv;
-       int i = 0;
-       int length = 0;
-
-       DPRINTK("");
-
-       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,
-                      "XENBUS_BASE_PATH=%s", xenbus_backend.root);
-
-       /* terminate, set to next free slot, shrink available space */
-       envp[i] = NULL;
-       envp = &envp[i];
-       num_envp -= i;
-       buffer = &buffer[length];
-       buffer_size -= length;
-
-       if (dev->driver) {
-               drv = to_xenbus_driver(dev->driver);
-               if (drv && drv->uevent)
-                       return drv->uevent(xdev, envp, num_envp, buffer,
-                                          buffer_size);
-       }
-
-       return 0;
-}
 
 static void otherend_changed(struct xenbus_watch *watch,
                             const char **vec, unsigned int len)
@@ -359,7 +245,7 @@ static int watch_otherend(struct xenbus_
 }
 
 
-static int xenbus_dev_probe(struct device *_dev)
+int xenbus_dev_probe(struct device *_dev)
 {
        struct xenbus_device *dev = to_xenbus_device(_dev);
        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
@@ -406,7 +292,7 @@ fail:
        return -ENODEV;
 }
 
-static int xenbus_dev_remove(struct device *_dev)
+int xenbus_dev_remove(struct device *_dev)
 {
        struct xenbus_device *dev = to_xenbus_device(_dev);
        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
@@ -444,14 +330,21 @@ static void xenbus_dev_shutdown(struct d
        put_device(&dev->dev);
 }
 
-static int xenbus_register_driver_common(struct xenbus_driver *drv,
-                                        struct xen_bus_type *bus)
+int xenbus_register_driver_common(struct xenbus_driver *drv,
+                                 struct xen_bus_type *bus)
 {
        int ret;
 
        drv->driver.name = drv->name;
        drv->driver.bus = &bus->bus;
+#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
 
        mutex_lock(&xenwatch_mutex);
        ret = driver_register(&drv->driver);
@@ -475,14 +368,6 @@ int xenbus_register_frontend(struct xenb
        return 0;
 }
 EXPORT_SYMBOL_GPL(xenbus_register_frontend);
-
-int xenbus_register_backend(struct xenbus_driver *drv)
-{
-       drv->read_otherend_details = read_frontend_details;
-
-       return xenbus_register_driver_common(drv, &xenbus_backend);
-}
-EXPORT_SYMBOL_GPL(xenbus_register_backend);
 
 void xenbus_unregister_driver(struct xenbus_driver *drv)
 {
@@ -581,23 +466,29 @@ char *kasprintf(const char *fmt, ...)
 }
 
 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 int xenbus_probe_node(struct xen_bus_type *bus,
-                            const char *type,
-                            const char *nodename)
+int xenbus_probe_node(struct xen_bus_type *bus,
+                     const char *type,
+                     const char *nodename)
 {
        int err;
        struct xenbus_device *xendev;
@@ -667,55 +558,6 @@ static int xenbus_probe_frontend(const c
        return err;
 }
 
-/* backend/<typename>/<frontend-uuid>/<name> */
-static int xenbus_probe_backend_unit(const char *dir,
-                                    const char *type,
-                                    const char *name)
-{
-       char *nodename;
-       int err;
-
-       nodename = kasprintf("%s/%s", dir, name);
-       if (!nodename)
-               return -ENOMEM;
-
-       DPRINTK("%s\n", nodename);
-
-       err = xenbus_probe_node(&xenbus_backend, type, nodename);
-       kfree(nodename);
-       return err;
-}
-
-/* backend/<typename>/<frontend-domid> */
-static int xenbus_probe_backend(const char *type, const char *domid)
-{
-       char *nodename;
-       int err = 0;
-       char **dir;
-       unsigned int i, dir_n = 0;
-
-       DPRINTK("");
-
-       nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
-       if (!nodename)
-               return -ENOMEM;
-
-       dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
-       if (IS_ERR(dir)) {
-               kfree(nodename);
-               return PTR_ERR(dir);
-       }
-
-       for (i = 0; i < dir_n; i++) {
-               err = xenbus_probe_backend_unit(nodename, type, dir[i]);
-               if (err)
-                       break;
-       }
-       kfree(dir);
-       kfree(nodename);
-       return err;
-}
-
 static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
 {
        int err = 0;
@@ -736,7 +578,7 @@ static int xenbus_probe_device_type(stru
        return err;
 }
 
-static int xenbus_probe_devices(struct xen_bus_type *bus)
+int xenbus_probe_devices(struct xen_bus_type *bus)
 {
        int err = 0;
        char **dir;
@@ -778,7 +620,7 @@ static int strsep_len(const char *str, c
        return (len == 0) ? i : -ERANGE;
 }
 
-static void 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;
@@ -823,23 +665,10 @@ static void frontend_changed(struct xenb
        dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
 }
 
-static void backend_changed(struct xenbus_watch *watch,
-                           const char **vec, unsigned int len)
-{
-       DPRINTK("");
-
-       dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
-}
-
 /* We watch for devices appearing and vanishing. */
 static struct xenbus_watch fe_watch = {
        .node = "device",
        .callback = frontend_changed,
-};
-
-static struct xenbus_watch be_watch = {
-       .node = "backend",
-       .callback = backend_changed,
 };
 
 static int suspend_dev(struct device *dev, void *data)
@@ -912,7 +741,7 @@ void xenbus_suspend(void)
        DPRINTK("");
 
        bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
-       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
+       xenbus_backend_suspend(suspend_dev);
        xs_suspend();
 }
 EXPORT_SYMBOL_GPL(xenbus_suspend);
@@ -922,7 +751,7 @@ void xenbus_resume(void)
        xb_init_comms();
        xs_resume();
        bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
-       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
+       xenbus_backend_resume(resume_dev);
 }
 EXPORT_SYMBOL_GPL(xenbus_resume);
 
@@ -955,20 +784,17 @@ void xenbus_probe(void *unused)
 {
        BUG_ON((xenstored_ready <= 0));
 
-       /* Enumerate devices in xenstore. */
+       /* Enumerate devices in xenstore and watch for changes. */
        xenbus_probe_devices(&xenbus_frontend);
-       xenbus_probe_devices(&xenbus_backend);
-
-       /* Watch for changes. */
        register_xenbus_watch(&fe_watch);
-       register_xenbus_watch(&be_watch);
+       xenbus_backend_probe_and_watch();
 
        /* Notify others that xenstore is up */
        notifier_call_chain(&xenstore_chain, 0, NULL);
 }
 
 
-#ifdef CONFIG_PROC_FS
+#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;
@@ -1020,7 +846,7 @@ static int __init xenbus_probe_init(void
 
        /* Register ourselves with the kernel bus subsystem */
        bus_register(&xenbus_frontend.bus);
-       bus_register(&xenbus_backend.bus);
+       xenbus_backend_bus_register();
 
        /*
         * Domain0 doesn't have a store_evtchn or store_mfn yet.
@@ -1049,7 +875,7 @@ static int __init xenbus_probe_init(void
                xen_store_evtchn = xen_start_info->store_evtchn =
                        alloc_unbound.port;
 
-#ifdef CONFIG_PROC_FS
+#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) {
@@ -1091,7 +917,7 @@ static int __init xenbus_probe_init(void
 
        /* Register ourselves with the kernel device subsystem */
        device_register(&xenbus_frontend.dev);
-       device_register(&xenbus_backend.dev);
+       xenbus_backend_device_register();
 
        if (!is_initial_xendomain())
                xenbus_probe(NULL);
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Tue Oct 24 
11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Wed Oct 25 
12:12:01 2006 -0600
@@ -42,8 +42,14 @@
 #include <linux/fcntl.h>
 #include <linux/kthread.h>
 #include <linux/rwsem.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
 #include <xen/xenbus.h>
 #include "xenbus_comms.h"
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
 
 /* xenbus_probe.c */
 extern char *kasprintf(const char *fmt, ...);
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Tue Oct 
24 11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Wed Oct 
25 12:12:01 2006 -0600
@@ -8,6 +8,10 @@
  */
 
 #include <linux/config.h>
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
 
 #define ADDR (*(volatile long *) addr)
 
diff -r d246b79986d1 -r 3e26719ab827 linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Tue Oct 24 11:21:48 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Wed Oct 25 12:12:01 2006 -0600
@@ -38,6 +38,7 @@
 #include <linux/notifier.h>
 #include <linux/mutex.h>
 #include <linux/completion.h>
+#include <linux/init.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/xenbus.h>
diff -r d246b79986d1 -r 3e26719ab827 tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/blktap/drivers/blktapctrl.c Wed Oct 25 12:12:01 2006 -0600
@@ -204,81 +204,49 @@ static blkif_t *test_path(char *path, ch
 
 static void add_disktype(blkif_t *blkif, int type)
 {
-       driver_list_entry_t *entry, *ptr, *last;
-
-       if (type > MAX_DISK_TYPES) return;
+       driver_list_entry_t *entry, **pprev;
+
+       if (type > MAX_DISK_TYPES)
+               return;
 
        entry = malloc(sizeof(driver_list_entry_t));
        entry->blkif = blkif;
-       entry->next = NULL;
-       ptr = active_disks[type];
-
-       if (ptr == NULL) {
-               active_disks[type] = entry;
-               entry->prev = NULL;
-               return;
-       }
-
-       while (ptr != NULL) {
-               last = ptr;
-               ptr = ptr->next;
-       }
-
-       /*We've found the end of the list*/
-        last->next = entry;
-       entry->prev = last;
-       
-       return;
+       entry->next  = NULL;
+
+       pprev = &active_disks[type];
+       while (*pprev != NULL)
+               pprev = &(*pprev)->next;
+
+       *pprev = entry;
+       entry->pprev = pprev;
 }
 
 static int del_disktype(blkif_t *blkif)
 {
-       driver_list_entry_t *ptr, *cur, *last;
+       driver_list_entry_t *entry, **pprev;
        int type = blkif->drivertype, count = 0, close = 0;
 
-       if (type > MAX_DISK_TYPES) return 1;
-
-       ptr = active_disks[type];
-       last = NULL;
-       while (ptr != NULL) {
-               count++;
-               if (blkif == ptr->blkif) {
-                       cur = ptr;
-                       if (ptr->next != NULL) {
-                               /*There's more later in the chain*/
-                               if (!last) {
-                                       /*We're first in the list*/
-                                       active_disks[type] = ptr->next;
-                                       ptr = ptr->next;
-                                       ptr->prev = NULL;
-                               }
-                               else {
-                                       /*We're sandwiched*/
-                                       last->next = ptr->next;
-                                       ptr = ptr->next;
-                                       ptr->prev = last;
-                               }
-                               
-                       } else if (last) {
-                               /*There's more earlier in the chain*/
-                               last->next = NULL;
-                       } else {
-                               /*We're the only entry*/
-                               active_disks[type] = NULL;
-                               if(dtypes[type]->single_handler == 1) 
-                                       close = 1;
-                       }
-                       DPRINTF("DEL_DISKTYPE: Freeing entry\n");
-                       free(cur);
-                       if (dtypes[type]->single_handler == 0) close = 1;
-
-                       return close;
-               }
-               last = ptr;
-               ptr = ptr->next;
-       }
-       DPRINTF("DEL_DISKTYPE: No match\n");
-       return 1;
+       if (type > MAX_DISK_TYPES)
+               return 1;
+
+       pprev = &active_disks[type];
+       while ((*pprev != NULL) && ((*pprev)->blkif != blkif))
+               pprev = &(*pprev)->next;
+
+       if ((entry = *pprev) == NULL) {
+               DPRINTF("DEL_DISKTYPE: No match\n");
+               return 1;
+       }
+
+       *pprev = entry->next;
+       if (entry->next)
+               entry->next->pprev = pprev;
+
+       DPRINTF("DEL_DISKTYPE: Freeing entry\n");
+       free(entry);
+
+       /* Caller should close() if no single controller, or list is empty. */
+       return (!dtypes[type]->single_handler || (active_disks[type] == NULL));
 }
 
 static int write_msg(int fd, int msgtype, void *ptr, void *ptr2)
@@ -592,8 +560,8 @@ int unmap_blktapctrl(blkif_t *blkif)
        if (del_disktype(blkif)) {
                close(blkif->fds[WRITE]);
                close(blkif->fds[READ]);
-
-       }
+       }
+
        return 0;
 }
 
diff -r d246b79986d1 -r 3e26719ab827 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/blktap/drivers/tapdisk.c    Wed Oct 25 12:12:01 2006 -0600
@@ -79,31 +79,17 @@ static void unmap_disk(struct td_state *
 {
        tapdev_info_t *info = s->ring_info;
        struct tap_disk *drv = s->drv;
-       fd_list_entry_t *ptr, *prev;
+       fd_list_entry_t *entry;
 
        drv->td_close(s);
 
        if (info != NULL && info->mem > 0)
                munmap(info->mem, getpagesize() * BLKTAP_MMAP_REGION_SIZE);
 
-       ptr = s->fd_entry;
-       prev = ptr->prev;
-
-       if (prev) {
-               /*There are entries earlier in the list*/
-               prev->next = ptr->next;
-               if (ptr->next) {
-                       ptr = ptr->next;
-                       ptr->prev = prev;
-               }
-       } else {
-               /*We are the first entry in list*/
-               if (ptr->next) {
-                       ptr = ptr->next;
-                       fd_start = ptr;
-                       ptr->prev = NULL;
-               } else fd_start = NULL;
-       }
+       entry = s->fd_entry;
+       *entry->pprev = entry->next;
+       if (entry->next)
+               entry->next->pprev = entry->pprev;
 
        close(info->fd);
 
@@ -144,35 +130,29 @@ static inline int LOCAL_FD_SET(fd_set *r
        return 0;
 }
 
-static inline fd_list_entry_t *add_fd_entry(int tap_fd, int io_fd[MAX_IOFD], 
struct td_state *s)
-{
-       fd_list_entry_t *ptr, *last, *entry;
+static inline fd_list_entry_t *add_fd_entry(
+       int tap_fd, int io_fd[MAX_IOFD], struct td_state *s)
+{
+       fd_list_entry_t **pprev, *entry;
        int i;
+
        DPRINTF("Adding fd_list_entry\n");
 
        /*Add to linked list*/
        s->fd_entry = entry = malloc(sizeof(fd_list_entry_t));
        entry->tap_fd = tap_fd;
-       for (i = 0; i < MAX_IOFD; i++) entry->io_fd[i] = io_fd[i];
+       for (i = 0; i < MAX_IOFD; i++)
+               entry->io_fd[i] = io_fd[i];
        entry->s = s;
        entry->next = NULL;
 
-       ptr = fd_start;
-       if (ptr == NULL) {
-               /*We are the first entry*/
-               fd_start = entry;
-               entry->prev = NULL;
-               goto finish;
-       }
-
-       while (ptr != NULL) {
-               last = ptr;
-               ptr = ptr->next;
-       }
-       last->next = entry;
-       entry->prev = last;
-
- finish:
+       pprev = &fd_start;
+       while (*pprev != NULL)
+               pprev = &(*pprev)->next;
+
+       *pprev = entry;
+       entry->pprev = pprev;
+
        return entry;
 }
 
diff -r d246b79986d1 -r 3e26719ab827 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/blktap/drivers/tapdisk.h    Wed Oct 25 12:12:01 2006 -0600
@@ -191,9 +191,8 @@ static disk_info_t *dtypes[] = {
 };
 
 typedef struct driver_list_entry {
-       void *blkif;
-       void *prev;
-       void *next;
+       struct blkif *blkif;
+       struct driver_list_entry **pprev, *next;
 } driver_list_entry_t;
 
 typedef struct fd_list_entry {
@@ -201,8 +200,7 @@ typedef struct fd_list_entry {
        int  tap_fd;
        int  io_fd[MAX_IOFD];
        struct td_state *s;
-       void *prev;
-       void *next;
+       struct fd_list_entry **pprev, *next;
 } fd_list_entry_t;
 
 int qcow_create(const char *filename, uint64_t total_size,
diff -r d246b79986d1 -r 3e26719ab827 tools/firmware/acpi/acpi_fadt.h
--- a/tools/firmware/acpi/acpi_fadt.h   Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/firmware/acpi/acpi_fadt.h   Wed Oct 25 12:12:01 2006 -0600
@@ -17,6 +17,8 @@
  */
 #ifndef _FADT_H_
 #define _FADT_H_
+
+#include <xen/hvm/ioreq.h>
 
 //
 // FADT Definitions, see ACPI 2.0 specification for details.
@@ -51,7 +53,9 @@
 //
 // Fixed Feature Flags
 // 
-#define ACPI_FIXED_FEATURE_FLAGS 
(ACPI_PROC_C1|ACPI_SLP_BUTTON|ACPI_WBINVD|ACPI_PWR_BUTTON|ACPI_FIX_RTC)
+#define ACPI_FIXED_FEATURE_FLAGS (ACPI_PROC_C1 | ACPI_SLP_BUTTON | \
+                                  ACPI_WBINVD | ACPI_PWR_BUTTON | \
+                                  ACPI_FIX_RTC | ACPI_TMR_VAL_EXT)
 
 //
 // PM1A Event Register Block Generic Address Information
@@ -59,7 +63,6 @@
 #define ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID  ACPI_SYSTEM_IO
 #define ACPI_PM1A_EVT_BLK_BIT_WIDTH         0x20
 #define ACPI_PM1A_EVT_BLK_BIT_OFFSET        0x00
-#define ACPI_PM1A_EVT_BLK_ADDRESS           0x000000000000c010
 
 //
 // PM1B Event Register Block Generic Address Information
@@ -75,7 +78,6 @@
 #define ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID  ACPI_SYSTEM_IO
 #define ACPI_PM1A_CNT_BLK_BIT_WIDTH         0x10
 #define ACPI_PM1A_CNT_BLK_BIT_OFFSET        0x00
-#define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
 
 //
 // PM1B Control Register Block Generic Address Information
@@ -100,7 +102,6 @@
 #define ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID    ACPI_SYSTEM_IO
 #define ACPI_PM_TMR_BLK_BIT_WIDTH           0x20
 #define ACPI_PM_TMR_BLK_BIT_OFFSET          0x00
-#define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
 
 //
 // General Purpose Event 0 Register Block Generic Address
diff -r d246b79986d1 -r 3e26719ab827 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/ioemu/vl.c  Wed Oct 25 12:12:01 2006 -0600
@@ -6448,7 +6448,6 @@ int main(int argc, char **argv)
     fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
             shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
 
-    /* not yet add for IA64 */
     buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
                                             PROT_READ|PROT_WRITE,
                                             page_array[shared_page_nr - 2]);
@@ -6465,7 +6464,7 @@ int main(int argc, char **argv)
 #elif defined(__ia64__)
   
     if (xc_ia64_get_pfn_list(xc_handle, domid, page_array,
-                             IO_PAGE_START >> PAGE_SHIFT, 1) != 1) {
+                             IO_PAGE_START >> PAGE_SHIFT, 3) != 3) {
         fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
         exit(-1);
     }
@@ -6476,6 +6475,12 @@ int main(int argc, char **argv)
 
     fprintf(logfile, "shared page at pfn:%lx, mfn: %016lx\n",
             IO_PAGE_START >> PAGE_SHIFT, page_array[0]);
+
+    buffered_io_page =xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                       PROT_READ|PROT_WRITE,
+                                       page_array[2]);
+    fprintf(logfile, "Buffered IO page at pfn:%lx, mfn: %016lx\n",
+            BUFFER_IO_PAGE_START >> PAGE_SHIFT, page_array[2]);
 
     if (xc_ia64_get_pfn_list(xc_handle, domid,
                              page_array, 0, nr_pages) != nr_pages) {
@@ -6496,6 +6501,7 @@ int main(int argc, char **argv)
         fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
         exit(-1);
     }
+    free(page_array);
 #endif
 #else  /* !CONFIG_DM */
 
diff -r d246b79986d1 -r 3e26719ab827 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/ioemu/vnc.c Wed Oct 25 12:12:01 2006 -0600
@@ -203,6 +203,8 @@ static void set_bits_in_row(VncState *vs
        mask = ~(0ULL);
 
     h += y;
+    if (h > vs->ds->height)
+        h = vs->ds->height;
     for (; y < h; y++)
        row[y] |= mask;
 }
diff -r d246b79986d1 -r 3e26719ab827 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/libxc/Makefile      Wed Oct 25 12:12:01 2006 -0600
@@ -31,7 +31,7 @@ GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build
 
 -include $(XEN_TARGET_ARCH)/Makefile
 
-CFLAGS   += -Werror
+CFLAGS   += -Werror -Wmissing-prototypes
 CFLAGS   += -fno-strict-aliasing
 CFLAGS   += $(INCLUDES) -I.
 
diff -r d246b79986d1 -r 3e26719ab827 tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c      Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c      Wed Oct 25 12:12:01 2006 -0600
@@ -551,8 +551,9 @@ setup_guest(int xc_handle, uint32_t dom,
             char *image, unsigned long image_size, uint32_t vcpus,
             unsigned int store_evtchn, unsigned long *store_mfn)
 {
-    unsigned long page_array[2];
+    unsigned long page_array[3];
     shared_iopage_t *sp;
+    void *ioreq_buffer_page;
     unsigned long dom_memsize = (memsize << 20);
     DECLARE_DOMCTL;
 
@@ -587,7 +588,7 @@ setup_guest(int xc_handle, uint32_t dom,
 
     /* Retrieve special pages like io, xenstore, etc. */
     if (xc_ia64_get_pfn_list(xc_handle, dom, page_array,
-                             IO_PAGE_START>>PAGE_SHIFT, 2) != 2) {
+                             IO_PAGE_START>>PAGE_SHIFT, 3) != 3) {
         PERROR("Could not get the page frame list");
         goto error_out;
     }
@@ -604,7 +605,10 @@ setup_guest(int xc_handle, uint32_t dom,
 
     memset(sp, 0, PAGE_SIZE);
     munmap(sp, PAGE_SIZE);
-
+    ioreq_buffer_page = xc_map_foreign_range(xc_handle, dom,
+                               PAGE_SIZE, PROT_READ|PROT_WRITE, 
page_array[2]); 
+    memset(ioreq_buffer_page,0,PAGE_SIZE);
+    munmap(ioreq_buffer_page, PAGE_SIZE);
     return 0;
 
 error_out:
diff -r d246b79986d1 -r 3e26719ab827 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/libxc/xc_linux_build.c      Wed Oct 25 12:12:01 2006 -0600
@@ -128,7 +128,7 @@ static int probeimageformat(const char *
     return 0;
 }
 
-int load_initrd(int xc_handle, domid_t dom,
+static int load_initrd(int xc_handle, domid_t dom,
                 struct initrd_info *initrd,
                 unsigned long physbase,
                 xen_pfn_t *phys_to_mach)
diff -r d246b79986d1 -r 3e26719ab827 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/libxc/xc_linux_restore.c    Wed Oct 25 12:12:01 2006 -0600
@@ -57,7 +57,7 @@ read_exact(int fd, void *buf, size_t cou
 ** This function inverts that operation, replacing the pfn values with
 ** the (now known) appropriate mfn values.
 */
-int uncanonicalize_pagetable(unsigned long type, void *page)
+static int uncanonicalize_pagetable(unsigned long type, void *page)
 {
     int i, pte_last;
     unsigned long pfn;
diff -r d246b79986d1 -r 3e26719ab827 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/libxc/xc_linux_save.c       Wed Oct 25 12:12:01 2006 -0600
@@ -413,7 +413,7 @@ static int suspend_and_state(int (*suspe
 ** which entries do not require canonicalization (in particular, those
 ** entries which map the virtual address reserved for the hypervisor).
 */
-int canonicalize_pagetable(unsigned long type, unsigned long pfn,
+static int canonicalize_pagetable(unsigned long type, unsigned long pfn,
                            const void *spage, void *dpage)
 {
 
diff -r d246b79986d1 -r 3e26719ab827 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/libxc/xc_private.c  Wed Oct 25 12:12:01 2006 -0600
@@ -6,6 +6,7 @@
 
 #include <inttypes.h>
 #include "xc_private.h"
+#include "xg_private.h"
 
 int lock_pages(void *addr, size_t len)
 {
@@ -33,23 +34,6 @@ int xc_get_pfn_type_batch(int xc_handle,
     domctl.u.getpageframeinfo2.num    = num;
     set_xen_guest_handle(domctl.u.getpageframeinfo2.array, arr);
     return do_domctl(xc_handle, &domctl);
-}
-
-#define GETPFN_ERR (~0U)
-unsigned int get_pfn_type(int xc_handle,
-                          unsigned long mfn,
-                          uint32_t dom)
-{
-    DECLARE_DOMCTL;
-    domctl.cmd = XEN_DOMCTL_getpageframeinfo;
-    domctl.u.getpageframeinfo.gmfn   = mfn;
-    domctl.domain = (domid_t)dom;
-    if ( do_domctl(xc_handle, &domctl) < 0 )
-    {
-        PERROR("Unexpected failure when getting page frame info!");
-        return GETPFN_ERR;
-    }
-    return domctl.u.getpageframeinfo.type;
 }
 
 int xc_mmuext_op(
diff -r d246b79986d1 -r 3e26719ab827 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/python/xen/xend/image.py    Wed Oct 25 12:12:01 2006 -0600
@@ -471,7 +471,7 @@ class IA64_HVM_ImageHandler(HVMImageHand
     def getRequiredAvailableMemory(self, mem_kb):
         page_kb = 16
         # ROM size for guest firmware, ioreq page and xenstore page
-        extra_pages = 1024 + 2
+        extra_pages = 1024 + 3
         return mem_kb + extra_pages * page_kb
 
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
@@ -500,9 +500,12 @@ class X86_HVM_ImageHandler(HVMImageHandl
         # overhead due to getRequiredInitialReservation.
         maxmem_kb = self.getRequiredInitialReservation(maxmem_kb)
 
-        # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
-        # the minimum that Xen would allocate if no value were given.
-        return max(1024 * self.vm.getVCpuCount() + maxmem_kb / 256,
+        # 256 pages (1MB) per vcpu,
+        # plus 1 page per MiB of RAM for the P2M map,
+        # plus 1 page per MiB of RAM to shadow the resident processes.  
+        # This is higher than the minimum that Xen would allocate if no value 
+        # were given (but the Xen minimum is for safety, not performance).
+        return max(4 * (256 * self.vm.getVCpuCount() + 2 * (maxmem_kb / 1024)),
                    shadow_mem_kb)
 
 
diff -r d246b79986d1 -r 3e26719ab827 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/python/xen/xend/server/SrvDaemon.py Wed Oct 25 12:12:01 2006 -0600
@@ -9,6 +9,7 @@ import signal
 import signal
 import sys
 import threading
+import time
 import linecache
 import pwd
 import re
@@ -106,12 +107,14 @@ class Daemon:
         os.close(2)
         if XEND_DEBUG:
             os.open('/dev/null', os.O_RDONLY)
-            os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT)
+            os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND)
             os.dup(1)
         else:
             os.open('/dev/null', os.O_RDWR)
             os.dup(0)
-            os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT)
+            os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND)
+        print >>sys.stderr, ("Xend started at %s." %
+                             time.asctime(time.localtime()))
 
         
     def start(self, trace=0):
diff -r d246b79986d1 -r 3e26719ab827 tools/xenstat/xentop/xentop.1
--- a/tools/xenstat/xentop/xentop.1     Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/xenstat/xentop/xentop.1     Wed Oct 25 12:12:01 2006 -0600
@@ -47,6 +47,9 @@ seconds between updates (default 3)
 \fB\-n\fR, \fB\-\-networks\fR
 output network information
 .TP
+\fB\-x\fR, \fB\-\-vbds\fR
+output vbd block device data
+.TP
 \fB\-r\fR, \fB\-\-repeat\-header\fR
 repeat table header before each domain
 .TP
diff -r d246b79986d1 -r 3e26719ab827 tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c     Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/xenstat/xentop/xentop.c     Wed Oct 25 12:12:01 2006 -0600
@@ -204,7 +204,7 @@ static void usage(const char *program)
               "-V, --version        output version information and exit\n"
               "-d, --delay=SECONDS  seconds between updates (default 3)\n"
               "-n, --networks       output vif network data\n"
-              "-b, --vbds           output vbd block device data\n"
+              "-x, --vbds           output vbd block device data\n"
               "-r, --repeat-header  repeat table header before each domain\n"
               "-v, --vcpus          output vcpu data\n"
               "-b, --batch          output in batch mode, no user input 
accepted\n"
@@ -976,7 +976,7 @@ int main(int argc, char **argv)
                { "help",          no_argument,       NULL, 'h' },
                { "version",       no_argument,       NULL, 'V' },
                { "networks",      no_argument,       NULL, 'n' },
-               { "vbds",          no_argument,       NULL, 'x' },
+               { "vbds",          no_argument,       NULL, 'x' },
                { "repeat-header", no_argument,       NULL, 'r' },
                { "vcpus",         no_argument,       NULL, 'v' },
                { "delay",         required_argument, NULL, 'd' },
@@ -1065,7 +1065,7 @@ int main(int argc, char **argv)
                                        break;
                        } while (1);
        }
-       
+
        /* Cleanup occurs in cleanup(), so no work to do here. */
 
        return 0;
diff -r d246b79986d1 -r 3e26719ab827 tools/xm-test/lib/XmTestLib/arch.py
--- a/tools/xm-test/lib/XmTestLib/arch.py       Tue Oct 24 11:21:48 2006 -0600
+++ b/tools/xm-test/lib/XmTestLib/arch.py       Wed Oct 25 12:12:01 2006 -0600
@@ -124,6 +124,7 @@ _uname_to_arch_map = {
     "i486"  : "x86",
     "i586"  : "x86",
     "i686"  : "x86",
+    "x86_64": "x86_64",
     "ia64"  : "ia64",
     "ppc"   : "powerpc",
     "ppc64" : "powerpc",
@@ -131,7 +132,7 @@ _uname_to_arch_map = {
 
 # Lookup current platform.
 _arch = _uname_to_arch_map.get(os.uname()[4], "Unknown")
-if _arch == "x86" or _arch == "ia64":
+if _arch == "x86" or _arch == "x86_64" or _arch == "ia64":
     minSafeMem = ia_minSafeMem
     getDefaultKernel = ia_getDefaultKernel
     checkBuffer = ia_checkBuffer
diff -r d246b79986d1 -r 3e26719ab827 unmodified_drivers/linux-2.6/overrides.mk
--- a/unmodified_drivers/linux-2.6/overrides.mk Tue Oct 24 11:21:48 2006 -0600
+++ b/unmodified_drivers/linux-2.6/overrides.mk Wed Oct 25 12:12:01 2006 -0600
@@ -9,4 +9,4 @@ EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRAN
 EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRANT -DXEN_EVTCHN_MASK_OPS
 EXTRA_CFLAGS += -DCONFIG_XEN_NETDEV_GRANT_RX -DCONFIG_XEN_NETDEV_GRANT_TX
 EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202
-EXTRA_CFLAGS += -I$(M)/include
+EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include 
-DHAVE_XEN_PLATFORM_COMPAT_H
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/platform-pci/Kbuild
--- a/unmodified_drivers/linux-2.6/platform-pci/Kbuild  Tue Oct 24 11:21:48 
2006 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/Kbuild  Wed Oct 25 12:12:01 
2006 -0600
@@ -4,7 +4,7 @@ obj-m := xen-platform-pci.o
 
 EXTRA_CFLAGS += -I$(M)/platform-pci
 
-xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o 
features.o
+xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o 
features.o platform-compat.o
 
 # Can we do better ?
 ifeq ($(ARCH),ia64)
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/platform-pci/evtchn.c
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c        Tue Oct 24 
11:21:48 2006 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c        Wed Oct 25 
12:12:01 2006 -0600
@@ -35,6 +35,10 @@
 #include <xen/interface/hvm/ioreq.h>
 #include <xen/features.h>
 #include "platform-pci.h"
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
 
 void *shared_info_area;
 
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Tue Oct 24 
11:21:48 2006 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Wed Oct 25 
12:12:01 2006 -0600
@@ -33,6 +33,7 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/hypervisor.h>
+#include <asm/pgtable.h>
 #include <xen/interface/memory.h>
 #include <xen/features.h>
 #ifdef __ia64__
@@ -40,6 +41,10 @@
 #endif
 
 #include "platform-pci.h"
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
 
 #define DRV_NAME    "xen-platform-pci"
 #define DRV_VERSION "0.10"
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/platform-pci/xen_support.c
--- a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c   Tue Oct 24 
11:21:48 2006 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c   Wed Oct 25 
12:12:01 2006 -0600
@@ -26,6 +26,10 @@
 #include <asm/hypervisor.h>
 #include "platform-pci.h"
 
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
 void xen_machphys_update(unsigned long mfn, unsigned long pfn)
 {
        BUG();
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c  Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/ia64/vmx/mmio.c  Wed Oct 25 12:12:01 2006 -0600
@@ -52,6 +52,70 @@ struct mmio_list *lookup_mmio(u64 gpa, s
 #define PIB_OFST_INTA           0x1E0000
 #define PIB_OFST_XTP            0x1E0008
 
+#define HVM_BUFFERED_IO_RANGE_NR 1
+
+struct hvm_buffered_io_range {
+    unsigned long start_addr;
+    unsigned long length;
+};
+
+static struct hvm_buffered_io_range buffered_stdvga_range = {0xA0000, 0x20000};
+static struct hvm_buffered_io_range
+*hvm_buffered_io_ranges[HVM_BUFFERED_IO_RANGE_NR] =
+{
+    &buffered_stdvga_range
+};
+
+int hvm_buffered_io_intercept(ioreq_t *p)
+{
+    struct vcpu *v = current;
+    spinlock_t  *buffered_io_lock;
+    buffered_iopage_t *buffered_iopage =
+        (buffered_iopage_t *)(v->domain->arch.hvm_domain.buffered_io_va);
+    unsigned long tmp_write_pointer = 0;
+    int i;
+
+    /* ignore READ ioreq_t! */
+    if ( p->dir == IOREQ_READ )
+        return 0;
+
+    for ( i = 0; i < HVM_BUFFERED_IO_RANGE_NR; i++ ) {
+        if ( p->addr >= hvm_buffered_io_ranges[i]->start_addr &&
+             p->addr + p->size - 1 < hvm_buffered_io_ranges[i]->start_addr +
+                                     hvm_buffered_io_ranges[i]->length )
+            break;
+    }
+
+    if ( i == HVM_BUFFERED_IO_RANGE_NR )
+        return 0;
+
+    buffered_io_lock = &v->domain->arch.hvm_domain.buffered_io_lock;
+    spin_lock(buffered_io_lock);
+
+    if ( buffered_iopage->write_pointer - buffered_iopage->read_pointer ==
+         (unsigned long)IOREQ_BUFFER_SLOT_NUM ) {
+        /* the queue is full.
+         * send the iopacket through the normal path.
+         * NOTE: The arithimetic operation could handle the situation for
+         * write_pointer overflow.
+         */
+        spin_unlock(buffered_io_lock);
+        return 0;
+    }
+
+    tmp_write_pointer = buffered_iopage->write_pointer % IOREQ_BUFFER_SLOT_NUM;
+
+    memcpy(&buffered_iopage->ioreq[tmp_write_pointer], p, sizeof(ioreq_t));
+
+    /*make the ioreq_t visible before write_pointer*/
+    wmb();
+    buffered_iopage->write_pointer++;
+
+    spin_unlock(buffered_io_lock);
+
+    return 1;
+}
+
 static void write_ipi (VCPU *vcpu, uint64_t addr, uint64_t value);
 
 static void pib_write(VCPU *vcpu, void *src, uint64_t pib_off, size_t s, int 
ma)
@@ -156,7 +220,11 @@ static void low_mmio_access(VCPU *vcpu, 
     p->df = 0;
 
     p->io_count++;
-
+    if(hvm_buffered_io_intercept(p)){
+        p->state = STATE_IORESP_READY;
+        vmx_io_assist(v);
+        return ;
+    }else 
     vmx_send_assist_req(v);
     if(dir==IOREQ_READ){ //read
         *val=p->u.data;
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_init.c      Wed Oct 25 12:12:01 2006 -0600
@@ -362,8 +362,8 @@ static const io_range_t io_ranges[] = {
        {PIB_START, PIB_SIZE, GPFN_PIB},
 };
 
-/* Reseve 1 page for shared I/O and 1 page for xenstore.  */
-#define VMX_SYS_PAGES  (2 + (GFW_SIZE >> PAGE_SHIFT))
+/* Reseve 1 page for shared I/O ,1 page for xenstore and 1 page for buffer 
I/O.  */
+#define VMX_SYS_PAGES  (3 + (GFW_SIZE >> PAGE_SHIFT))
 #define VMX_CONFIG_PAGES(d) ((d)->max_pages - VMX_SYS_PAGES)
 
 static void vmx_build_physmap_table(struct domain *d)
@@ -425,8 +425,12 @@ static void vmx_build_physmap_table(stru
        mfn = page_to_mfn(list_entry(list_ent, struct page_info, list));
        assign_domain_page(d, STORE_PAGE_START, mfn << PAGE_SHIFT);
        list_ent = mfn_to_page(mfn)->list.next;
+       ASSERT(list_ent != &d->page_list);
+    
+    mfn = page_to_mfn(list_entry(list_ent, struct page_info, list));
+    assign_domain_page(d, BUFFER_IO_PAGE_START, mfn << PAGE_SHIFT);
+    list_ent = mfn_to_page(mfn)->list.next;
        ASSERT(list_ent == &d->page_list);
-
 }
 
 void vmx_setup_platform(struct domain *d)
@@ -437,6 +441,10 @@ void vmx_setup_platform(struct domain *d
 
        d->arch.vmx_platform.shared_page_va =
                (unsigned long)__va(__gpa_to_mpa(d, IO_PAGE_START));
+    //For buffered IO requests.
+    spin_lock_init(&d->arch.hvm_domain.buffered_io_lock);
+    d->arch.hvm_domain.buffered_io_va =
+        (unsigned long)__va(__gpa_to_mpa(d, BUFFER_IO_PAGE_START));
        /* TEMP */
        d->arch.vmx_platform.pib_base = 0xfee00000UL;
 
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/Makefile     Wed Oct 25 12:12:01 2006 -0600
@@ -28,12 +28,14 @@ obj-y += mm.o
 obj-y += mm.o
 obj-y += mpparse.o
 obj-y += nmi.o
+obj-y += numa.o
 obj-y += physdev.o
 obj-y += rwlock.o
 obj-y += setup.o
 obj-y += shutdown.o
 obj-y += smp.o
 obj-y += smpboot.o
+obj-y += srat.o
 obj-y += string.o
 obj-y += sysctl.o
 obj-y += time.o
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/Makefile
--- a/xen/arch/x86/hvm/Makefile Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/hvm/Makefile Wed Oct 25 12:12:01 2006 -0600
@@ -5,6 +5,7 @@ obj-y += i8254.o
 obj-y += i8254.o
 obj-y += i8259.o
 obj-y += rtc.o
+obj-y += pmtimer.o
 obj-y += instrlen.o
 obj-y += intercept.o
 obj-y += io.o
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Wed Oct 25 12:12:01 2006 -0600
@@ -43,7 +43,7 @@
 #include <asm/mc146818rtc.h>
 #include <asm/spinlock.h>
 #include <asm/hvm/hvm.h>
-#include <asm/hvm/vpit.h>
+#include <asm/hvm/vpt.h>
 #include <asm/hvm/support.h>
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
@@ -285,6 +285,7 @@ void hvm_setup_platform(struct domain* d
                pt_timer_fn, v, v->processor);
     pit_init(v, cpu_khz);
     rtc_init(v, RTC_PORT(0), RTC_IRQ);
+    pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS); 
 }
 
 void pic_irq_request(void *data, int level)
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c  Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/hvm/i8254.c  Wed Oct 25 12:12:01 2006 -0600
@@ -38,7 +38,7 @@
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
-#include <asm/hvm/vpit.h>
+#include <asm/hvm/vpt.h>
 #include <asm/current.h>
 
 /* Enable DEBUG_PIT may cause guest calibration inaccuracy */
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/hvm/io.c     Wed Oct 25 12:12:01 2006 -0600
@@ -35,7 +35,7 @@
 #include <asm/shadow.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
-#include <asm/hvm/vpit.h>
+#include <asm/hvm/vpt.h>
 #include <asm/hvm/vpic.h>
 #include <asm/hvm/vlapic.h>
 
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/hvm/rtc.c    Wed Oct 25 12:12:01 2006 -0600
@@ -23,7 +23,7 @@
  */
 
 #include <asm/mc146818rtc.h>
-#include <asm/hvm/vpit.h>
+#include <asm/hvm/vpt.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
 #include <asm/current.h>
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed Oct 25 12:12:01 2006 -0600
@@ -922,6 +922,7 @@ static void svm_relinquish_guest_resourc
 
     kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
     rtc_deinit(d);
+    pmtimer_deinit(d);
 
     if ( d->arch.hvm_domain.shared_page_va )
         unmap_domain_page_global(
@@ -937,6 +938,7 @@ static void svm_migrate_timers(struct vc
     struct periodic_time *pt = 
         &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
     struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
 
     if ( pt->enabled )
     {
@@ -947,6 +949,7 @@ static void svm_migrate_timers(struct vc
         migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
     migrate_timer(&vrtc->second_timer, v->processor);
     migrate_timer(&vrtc->second_timer2, v->processor);
+    migrate_timer(&vpmt->timer, v->processor);
 }
 
 
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Oct 25 12:12:01 2006 -0600
@@ -147,6 +147,7 @@ static void vmx_relinquish_guest_resourc
 
     kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
     rtc_deinit(d);
+    pmtimer_deinit(d);
 
     if ( d->arch.hvm_domain.shared_page_va )
         unmap_domain_page_global(
@@ -489,6 +490,7 @@ void vmx_migrate_timers(struct vcpu *v)
 {
     struct periodic_time *pt = 
&(v->domain->arch.hvm_domain.pl_time.periodic_tm);
     struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
 
     if ( pt->enabled )
     {
@@ -499,6 +501,7 @@ void vmx_migrate_timers(struct vcpu *v)
         migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
     migrate_timer(&vrtc->second_timer, v->processor);
     migrate_timer(&vrtc->second_timer2, v->processor);
+    migrate_timer(&vpmt->timer, v->processor);
 }
 
 static void vmx_store_cpu_guest_regs(
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/setup.c      Wed Oct 25 12:12:01 2006 -0600
@@ -16,6 +16,7 @@
 #include <xen/percpu.h>
 #include <xen/hypercall.h>
 #include <xen/keyhandler.h>
+#include <xen/numa.h>
 #include <public/version.h>
 #include <asm/bitops.h>
 #include <asm/smp.h>
@@ -29,6 +30,7 @@
 
 extern void dmi_scan_machine(void);
 extern void generic_apic_probe(void);
+extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn);
 
 /*
  * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
@@ -255,6 +257,20 @@ static void __init init_idle_domain(void
     idle_vcpu[0] = this_cpu(curr_vcpu) = current;
 
     setup_idle_pagetable();
+}
+
+static void srat_detect_node(int cpu)
+{
+    unsigned node;
+    u8 apicid = x86_cpu_to_apicid[cpu];
+
+    node = apicid_to_node[apicid];
+    if ( node == NUMA_NO_NODE )
+        node = 0;
+    numa_set_node(cpu, node);
+
+    if ( acpi_numa > 0 )
+        printk(KERN_INFO "CPU %d APIC %d -> Node %d\n", cpu, apicid, node);
 }
 
 void __init __start_xen(multiboot_info_t *mbi)
@@ -485,6 +501,12 @@ void __init __start_xen(multiboot_info_t
 
     init_frametable();
 
+    acpi_boot_table_init();
+
+    acpi_numa_init();
+
+    numa_initmem_init(0, max_page);
+
     end_boot_allocator();
 
     /* Initialise the Xen heap, skipping RAM holes. */
@@ -536,8 +558,9 @@ void __init __start_xen(multiboot_info_t
 
     generic_apic_probe();
 
-    acpi_boot_table_init();
     acpi_boot_init();
+
+    init_cpu_to_node();
 
     if ( smp_found_config )
         get_smp_config();
@@ -589,6 +612,11 @@ void __init __start_xen(multiboot_info_t
             break;
         if ( !cpu_online(i) )
             __cpu_up(i);
+
+        /* Set up cpu_to_node[]. */
+        srat_detect_node(i);
+        /* Set up node_to_cpumask based on cpu_to_node[]. */
+        numa_add_cpu(i);        
     }
 
     printk("Brought up %ld CPUs\n", (long)num_online_cpus());
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/arch/x86/smpboot.c    Wed Oct 25 12:12:01 2006 -0600
@@ -43,6 +43,7 @@
 #include <xen/delay.h>
 #include <xen/softirq.h>
 #include <xen/serial.h>
+#include <xen/numa.h>
 #include <asm/current.h>
 #include <asm/mc146818rtc.h>
 #include <asm/desc.h>
@@ -628,7 +629,7 @@ static void map_cpu_to_logical_apicid(vo
 static void map_cpu_to_logical_apicid(void)
 {
        int cpu = smp_processor_id();
-       int apicid = logical_smp_processor_id();
+       int apicid = hard_smp_processor_id();
 
        cpu_2_logical_apicid[cpu] = apicid;
        map_cpu_to_node(cpu, apicid_to_node(apicid));
diff -r d246b79986d1 -r 3e26719ab827 xen/common/memory.c
--- a/xen/common/memory.c       Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/common/memory.c       Wed Oct 25 12:12:01 2006 -0600
@@ -41,6 +41,8 @@ increase_reservation(
     struct page_info *page;
     unsigned long i;
     xen_pfn_t mfn;
+    /* use domain's first processor for locality parameter */
+    unsigned int cpu = d->vcpu[0]->processor;
 
     if ( !guest_handle_is_null(extent_list) &&
          !guest_handle_okay(extent_list, nr_extents) )
@@ -58,8 +60,8 @@ increase_reservation(
             return i;
         }
 
-        if ( unlikely((page = alloc_domheap_pages(
-            d, extent_order, memflags)) == NULL) )
+        if ( unlikely((page = __alloc_domheap_pages( d, cpu, 
+            extent_order, memflags )) == NULL) ) 
         {
             DPRINTK("Could not allocate order=%d extent: "
                     "id=%d memflags=%x (%ld of %d)\n",
@@ -92,6 +94,8 @@ populate_physmap(
     unsigned long i, j;
     xen_pfn_t gpfn;
     xen_pfn_t mfn;
+    /* use domain's first processor for locality parameter */
+    unsigned int cpu = d->vcpu[0]->processor;
 
     if ( !guest_handle_okay(extent_list, nr_extents) )
         return 0;
@@ -111,8 +115,8 @@ populate_physmap(
         if ( unlikely(__copy_from_guest_offset(&gpfn, extent_list, i, 1)) )
             goto out;
 
-        if ( unlikely((page = alloc_domheap_pages(
-            d, extent_order, memflags)) == NULL) )
+        if ( unlikely((page = __alloc_domheap_pages( d, cpu, 
+            extent_order, memflags )) == NULL) ) 
         {
             DPRINTK("Could not allocate order=%d extent: "
                     "id=%d memflags=%x (%ld of %d)\n",
@@ -294,7 +298,7 @@ memory_exchange(XEN_GUEST_HANDLE(xen_mem
     unsigned long in_chunk_order, out_chunk_order;
     xen_pfn_t     gpfn, gmfn, mfn;
     unsigned long i, j, k;
-    unsigned int  memflags = 0;
+    unsigned int  memflags = 0, cpu;
     long          rc = 0;
     struct domain *d;
     struct page_info *page;
@@ -368,6 +372,9 @@ memory_exchange(XEN_GUEST_HANDLE(xen_mem
     }
     d = current->domain;
 
+    /* use domain's first processor for locality parameter */
+    cpu = d->vcpu[0]->processor;
+
     for ( i = 0; i < (exch.in.nr_extents >> in_chunk_order); i++ )
     {
         if ( hypercall_preempt_check() )
@@ -413,8 +420,8 @@ memory_exchange(XEN_GUEST_HANDLE(xen_mem
         /* Allocate a chunk's worth of anonymous output pages. */
         for ( j = 0; j < (1UL << out_chunk_order); j++ )
         {
-            page = alloc_domheap_pages(
-                NULL, exch.out.extent_order, memflags);
+            page = __alloc_domheap_pages( NULL, cpu, 
+                  exch.out.extent_order, memflags);
             if ( unlikely(page == NULL) )
             {
                 rc = -ENOMEM;
diff -r d246b79986d1 -r 3e26719ab827 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/common/page_alloc.c   Wed Oct 25 12:12:01 2006 -0600
@@ -4,6 +4,7 @@
  * Simple buddy heap allocator for Xen.
  * 
  * Copyright (c) 2002-2004 K A Fraser
+ * Copyright (c) 2006 IBM Ryan Harper <ryanh@xxxxxxxxxx>
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,6 +34,8 @@
 #include <xen/domain_page.h>
 #include <xen/keyhandler.h>
 #include <xen/perfc.h>
+#include <xen/numa.h>
+#include <xen/nodemask.h>
 #include <asm/page.h>
 
 /*
@@ -247,22 +250,23 @@ unsigned long alloc_boot_pages(unsigned 
 #define pfn_dom_zone_type(_pfn)                                 \
     (((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM)
 
-static struct list_head heap[NR_ZONES][MAX_ORDER+1];
-
-static unsigned long avail[NR_ZONES];
+static struct list_head heap[NR_ZONES][MAX_NUMNODES][MAX_ORDER+1];
+
+static unsigned long avail[NR_ZONES][MAX_NUMNODES];
 
 static DEFINE_SPINLOCK(heap_lock);
 
 void end_boot_allocator(void)
 {
-    unsigned long i, j;
+    unsigned long i, j, k;
     int curr_free = 0, next_free = 0;
 
     memset(avail, 0, sizeof(avail));
 
     for ( i = 0; i < NR_ZONES; i++ )
-        for ( j = 0; j <= MAX_ORDER; j++ )
-            INIT_LIST_HEAD(&heap[i][j]);
+        for ( j = 0; j < MAX_NUMNODES; j++ )
+            for ( k = 0; k <= MAX_ORDER; k++ )
+                INIT_LIST_HEAD(&heap[i][j][k]);
 
     /* Pages that are free now go to the domain sub-allocator. */
     for ( i = 0; i < max_page; i++ )
@@ -272,29 +276,59 @@ void end_boot_allocator(void)
         if ( next_free )
             map_alloc(i+1, 1); /* prevent merging in free_heap_pages() */
         if ( curr_free )
-            free_heap_pages(pfn_dom_zone_type(i), mfn_to_page(i), 0);
-    }
-}
-
-/* Hand the specified arbitrary page range to the specified heap zone. */
+            init_heap_pages(pfn_dom_zone_type(i), mfn_to_page(i), 1);
+    }
+}
+
+/* 
+ * Hand the specified arbitrary page range to the specified heap zone
+ * checking the node_id of the previous page.  If they differ and the
+ * latter is not on a MAX_ORDER boundary, then we reserve the page by
+ * not freeing it to the buddy allocator.
+ */
+#define MAX_ORDER_ALIGNED (1UL << (MAX_ORDER))
 void init_heap_pages(
     unsigned int zone, struct page_info *pg, unsigned long nr_pages)
 {
+    unsigned int nid_curr,nid_prev;
     unsigned long i;
 
     ASSERT(zone < NR_ZONES);
 
+    if ( likely(page_to_mfn(pg) != 0) )
+        nid_prev = phys_to_nid(page_to_maddr(pg-1));
+    else
+        nid_prev = phys_to_nid(page_to_maddr(pg));
+
     for ( i = 0; i < nr_pages; i++ )
-        free_heap_pages(zone, pg+i, 0);
-}
-
+    {
+        nid_curr = phys_to_nid(page_to_maddr(pg+i));
+
+        /*
+         * free pages of the same node, or if they differ, but are on a
+         * MAX_ORDER alignement boundary (which already get reserved)
+         */
+         if ( (nid_curr == nid_prev) || (page_to_maddr(pg+i) &
+                                         MAX_ORDER_ALIGNED) )
+             free_heap_pages(zone, pg+i, 0);
+         else
+             printk("Reserving non-aligned node boundary @ mfn %lu\n",
+                    page_to_mfn(pg+i));
+
+        nid_prev = nid_curr;
+    }
+}
 
 /* Allocate 2^@order contiguous pages. */
-struct page_info *alloc_heap_pages(unsigned int zone, unsigned int order)
-{
-    int i;
+struct page_info *alloc_heap_pages(unsigned int zone, unsigned int cpu,
+                                   unsigned int order)
+{
+    unsigned int i,j, node = cpu_to_node(cpu), num_nodes = num_online_nodes();
+    unsigned int request = (1UL << order);
     struct page_info *pg;
 
+    ASSERT(node >= 0);
+    ASSERT(node < num_nodes);
     ASSERT(zone < NR_ZONES);
 
     if ( unlikely(order > MAX_ORDER) )
@@ -302,29 +336,46 @@ struct page_info *alloc_heap_pages(unsig
 
     spin_lock(&heap_lock);
 
-    /* Find smallest order which can satisfy the request. */
-    for ( i = order; i <= MAX_ORDER; i++ )
-        if ( !list_empty(&heap[zone][i]) )
-            goto found;
+    /* start with requested node, but exhaust all node memory
+     * in requested zone before failing, only calc new node
+     * value if we fail to find memory in target node, this avoids
+     * needless computation on fast-path */
+    for ( i = 0; i < num_nodes; i++ )
+    {
+        /* check if target node can support the allocation */
+        if ( avail[zone][node] >= request )
+        {
+            /* Find smallest order which can satisfy the request. */
+            for ( j = order; j <= MAX_ORDER; j++ )
+            {
+                if ( !list_empty(&heap[zone][node][j]) )
+                    goto found;
+            }
+        }
+        /* pick next node, wrapping around if needed */
+        if ( ++node == num_nodes )
+            node = 0;
+    }
 
     /* No suitable memory blocks. Fail the request. */
     spin_unlock(&heap_lock);
     return NULL;
 
  found: 
-    pg = list_entry(heap[zone][i].next, struct page_info, list);
+    pg = list_entry(heap[zone][node][j].next, struct page_info, list);
     list_del(&pg->list);
 
     /* We may have to halve the chunk a number of times. */
-    while ( i != order )
-    {
-        PFN_ORDER(pg) = --i;
-        list_add_tail(&pg->list, &heap[zone][i]);
-        pg += 1 << i;
+    while ( j != order )
+    {
+        PFN_ORDER(pg) = --j;
+        list_add_tail(&pg->list, &heap[zone][node][j]);
+        pg += 1 << j;
     }
     
-    map_alloc(page_to_mfn(pg), 1 << order);
-    avail[zone] -= 1 << order;
+    map_alloc(page_to_mfn(pg), request);
+    ASSERT(avail[zone][node] >= request);
+    avail[zone][node] -= request;
 
     spin_unlock(&heap_lock);
 
@@ -337,14 +388,17 @@ void free_heap_pages(
     unsigned int zone, struct page_info *pg, unsigned int order)
 {
     unsigned long mask;
+    int node = phys_to_nid(page_to_maddr(pg));
 
     ASSERT(zone < NR_ZONES);
     ASSERT(order <= MAX_ORDER);
+    ASSERT(node >= 0);
+    ASSERT(node < num_online_nodes());
 
     spin_lock(&heap_lock);
 
     map_free(page_to_mfn(pg), 1 << order);
-    avail[zone] += 1 << order;
+    avail[zone][node] += 1 << order;
     
     /* Merge chunks as far as possible. */
     while ( order < MAX_ORDER )
@@ -370,10 +424,13 @@ void free_heap_pages(
         }
         
         order++;
+
+        /* after merging, pg should be in the same node */
+        ASSERT(phys_to_nid(page_to_maddr(pg)) == node );
     }
 
     PFN_ORDER(pg) = order;
-    list_add_tail(&pg->list, &heap[zone][order]);
+    list_add_tail(&pg->list, &heap[zone][node][order]);
 
     spin_unlock(&heap_lock);
 }
@@ -466,7 +523,7 @@ void *alloc_xenheap_pages(unsigned int o
     int i;
 
     local_irq_save(flags);
-    pg = alloc_heap_pages(MEMZONE_XEN, order);
+    pg = alloc_heap_pages(MEMZONE_XEN, smp_processor_id(), order);
     local_irq_restore(flags);
 
     if ( unlikely(pg == NULL) )
@@ -580,8 +637,9 @@ int assign_pages(
 }
 
 
-struct page_info *alloc_domheap_pages(
-    struct domain *d, unsigned int order, unsigned int memflags)
+struct page_info *__alloc_domheap_pages(
+    struct domain *d, unsigned int cpu, unsigned int order, 
+    unsigned int memflags)
 {
     struct page_info *pg = NULL;
     cpumask_t mask;
@@ -591,17 +649,17 @@ struct page_info *alloc_domheap_pages(
 
     if ( !(memflags & MEMF_dma) )
     {
-        pg = alloc_heap_pages(MEMZONE_DOM, order);
+        pg = alloc_heap_pages(MEMZONE_DOM, cpu, order);
         /* Failure? Then check if we can fall back to the DMA pool. */
         if ( unlikely(pg == NULL) &&
              ((order > MAX_ORDER) ||
-              (avail[MEMZONE_DMADOM] <
+              (avail_heap_pages(MEMZONE_DMADOM,-1) <
                (lowmem_emergency_pool_pages + (1UL << order)))) )
             return NULL;
     }
 
     if ( pg == NULL )
-        if ( (pg = alloc_heap_pages(MEMZONE_DMADOM, order)) == NULL )
+        if ( (pg = alloc_heap_pages(MEMZONE_DMADOM, cpu, order)) == NULL )
             return NULL;
 
     mask = pg->u.free.cpumask;
@@ -640,6 +698,11 @@ struct page_info *alloc_domheap_pages(
     return pg;
 }
 
+inline struct page_info *alloc_domheap_pages(
+    struct domain *d, unsigned int order, unsigned int flags)
+{
+    return __alloc_domheap_pages(d, smp_processor_id(), order, flags);
+}
 
 void free_domheap_pages(struct page_info *pg, unsigned int order)
 {
@@ -714,13 +777,27 @@ void free_domheap_pages(struct page_info
 }
 
 
+unsigned long avail_heap_pages(int zone, int node)
+{
+    int i,j, num_nodes = num_online_nodes();
+    unsigned long free_pages = 0;
+   
+    for (i=0; i<NR_ZONES; i++)
+        if ( (zone == -1) || (zone == i) )
+            for (j=0; j < num_nodes; j++)
+                if ( (node == -1) || (node == j) )
+                    free_pages += avail[i][j];            
+
+    return free_pages;
+}
+
 unsigned long avail_domheap_pages(void)
 {
     unsigned long avail_nrm, avail_dma;
-
-    avail_nrm = avail[MEMZONE_DOM];
-
-    avail_dma = avail[MEMZONE_DMADOM];
+    
+    avail_nrm = avail_heap_pages(MEMZONE_DOM,-1);
+
+    avail_dma = avail_heap_pages(MEMZONE_DMADOM,-1);
     if ( avail_dma > lowmem_emergency_pool_pages )
         avail_dma -= lowmem_emergency_pool_pages;
     else
@@ -729,6 +806,10 @@ unsigned long avail_domheap_pages(void)
     return avail_nrm + avail_dma;
 }
 
+unsigned long avail_nodeheap_pages(int node)
+{
+    return avail_heap_pages(-1, node);
+}
 
 static void pagealloc_keyhandler(unsigned char key)
 {
@@ -736,9 +817,9 @@ static void pagealloc_keyhandler(unsigne
     printk("    Xen heap: %lukB free\n"
            "    DMA heap: %lukB free\n"
            "    Dom heap: %lukB free\n",
-           avail[MEMZONE_XEN]<<(PAGE_SHIFT-10),
-           avail[MEMZONE_DMADOM]<<(PAGE_SHIFT-10),
-           avail[MEMZONE_DOM]<<(PAGE_SHIFT-10));
+           avail_heap_pages(MEMZONE_XEN, -1) << (PAGE_SHIFT-10), 
+           avail_heap_pages(MEMZONE_DMADOM, -1) <<(PAGE_SHIFT-10), 
+           avail_heap_pages(MEMZONE_DOM, -1) <<(PAGE_SHIFT-10));
 }
 
 
@@ -805,6 +886,46 @@ unsigned long avail_scrub_pages(void)
 {
     return scrub_pages;
 }
+
+static unsigned long count_bucket(struct list_head* l, int order)
+{
+    unsigned long total_pages = 0;
+    int pages = 1 << order;
+    struct page_info *pg;
+
+    list_for_each_entry(pg, l, list)
+        total_pages += pages;
+
+    return total_pages;
+}
+
+static void dump_heap(unsigned char key)
+{
+    s_time_t       now = NOW();
+    int i,j,k;
+    unsigned long total;
+
+    printk("'%c' pressed -> dumping heap info (now-0x%X:%08X)\n", key,
+           (u32)(now>>32), (u32)now);
+
+    for (i=0; i<NR_ZONES; i++ )
+        for (j=0;j<MAX_NUMNODES;j++)
+            for (k=0;k<=MAX_ORDER;k++)
+                if ( !list_empty(&heap[i][j][k]) )
+                {
+                    total = count_bucket(&heap[i][j][k], k);
+                    printk("heap[%d][%d][%d]-> %lu pages\n",
+                            i, j, k, total);
+                }
+}
+
+static __init int register_heap_trigger(void)
+{
+    register_keyhandler('H', dump_heap, "dump heap info");
+    return 0;
+}
+__initcall(register_heap_trigger);
+
 
 static __init int page_scrub_init(void)
 {
diff -r d246b79986d1 -r 3e26719ab827 xen/drivers/acpi/Makefile
--- a/xen/drivers/acpi/Makefile Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/drivers/acpi/Makefile Wed Oct 25 12:12:01 2006 -0600
@@ -1,1 +1,2 @@ obj-y += tables.o
 obj-y += tables.o
+obj-y += numa.o
diff -r d246b79986d1 -r 3e26719ab827 xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h       Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/asm-ia64/vmx_platform.h       Wed Oct 25 12:12:01 2006 -0600
@@ -24,6 +24,8 @@
 #include <asm/hvm/vioapic.h>
 struct mmio_list;
 typedef struct virtual_platform_def {
+    unsigned long          buffered_io_va;
+    spinlock_t             buffered_io_lock;
     unsigned long       shared_page_va;
     unsigned long       pib_base;
     unsigned char       xtp;
diff -r d246b79986d1 -r 3e26719ab827 xen/include/asm-x86/acpi.h
--- a/xen/include/asm-x86/acpi.h        Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/asm-x86/acpi.h        Wed Oct 25 12:12:01 2006 -0600
@@ -157,6 +157,9 @@ static inline void check_acpi_pci(void) 
 
 static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
 static inline int acpi_irq_balance_set(char *str) { return 0; }
+extern int acpi_scan_nodes(u64 start, u64 end);
+extern int acpi_numa;
+#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
 
 #ifdef CONFIG_ACPI_SLEEP
 
@@ -173,5 +176,6 @@ extern void acpi_reserve_bootmem(void);
 #endif /*CONFIG_ACPI_SLEEP*/
 
 extern u8 x86_acpiid_to_apicid[];
+#define MAX_LOCAL_APIC 256
 
 #endif /*_ASM_ACPI_H*/
diff -r d246b79986d1 -r 3e26719ab827 xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h      Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/asm-x86/config.h      Wed Oct 25 12:12:01 2006 -0600
@@ -24,6 +24,11 @@
 #define CONFIG_X86_IO_APIC 1
 #define CONFIG_HPET_TIMER 1
 #define CONFIG_X86_MCE_P4THERMAL 1
+#define CONFIG_ACPI_NUMA 1
+#define CONFIG_NUMA 1
+#define CONFIG_ACPI_SRAT 1
+#define CONFIG_DISCONTIGMEM 1
+#define CONFIG_NUMA_EMU 1
 
 /* Intel P4 currently has largest cache line (L2 line size is 128 bytes). */
 #define CONFIG_X86_L1_CACHE_SHIFT 7
diff -r d246b79986d1 -r 3e26719ab827 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h  Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/asm-x86/hvm/domain.h  Wed Oct 25 12:12:01 2006 -0600
@@ -23,7 +23,7 @@
 #define __ASM_X86_HVM_DOMAIN_H__
 
 #include <asm/hvm/vpic.h>
-#include <asm/hvm/vpit.h>
+#include <asm/hvm/vpt.h>
 #include <asm/hvm/vlapic.h>
 #include <asm/hvm/vioapic.h>
 #include <public/hvm/params.h>
diff -r d246b79986d1 -r 3e26719ab827 
xen/include/asm-x86/mach-generic/mach_apic.h
--- a/xen/include/asm-x86/mach-generic/mach_apic.h      Tue Oct 24 11:21:48 
2006 -0600
+++ b/xen/include/asm-x86/mach-generic/mach_apic.h      Wed Oct 25 12:12:01 
2006 -0600
@@ -22,11 +22,7 @@ static inline void enable_apic_mode(void
        return;
 }
 
-/* No sane NUMA support right now. We should parse ACPI SRAT. */
-static inline int apicid_to_node(int logical_apicid)
-{
-       return 0;
-}
+#define apicid_to_node(apicid) ((int)apicid_to_node[(u8)apicid])
 
 extern u8 bios_cpu_apicid[];
 static inline int cpu_present_to_apicid(int mps_cpu)
diff -r d246b79986d1 -r 3e26719ab827 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/public/arch-ia64.h    Wed Oct 25 12:12:01 2006 -0600
@@ -67,6 +67,9 @@ typedef unsigned long xen_ulong_t;
 
 #define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
 #define STORE_PAGE_SIZE         PAGE_SIZE
+
+#define BUFFER_IO_PAGE_START (STORE_PAGE_START+PAGE_SIZE)
+#define BUFFER_IO_PAGE_SIZE PAGE_SIZE
 
 #define IO_SAPIC_START   0xfec00000UL
 #define IO_SAPIC_SIZE    0x100000
diff -r d246b79986d1 -r 3e26719ab827 xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h    Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/public/hvm/ioreq.h    Wed Oct 25 12:12:01 2006 -0600
@@ -86,6 +86,10 @@ struct buffered_iopage {
 };            /* sizeof this structure must be in one page */
 typedef struct buffered_iopage buffered_iopage_t;
 
+#define ACPI_PM1A_EVT_BLK_ADDRESS           0x000000000000c010
+#define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
+#define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
+
 #endif /* _IOREQ_H_ */
 
 /*
diff -r d246b79986d1 -r 3e26719ab827 xen/include/xen/config.h
--- a/xen/include/xen/config.h  Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/xen/config.h  Wed Oct 25 12:12:01 2006 -0600
@@ -50,5 +50,7 @@
 #endif /* !__ASSEMBLY__ */
 
 #define fastcall
+#define __cpuinitdata
+#define __cpuinit
 
 #endif /* __XEN_CONFIG_H__ */
diff -r d246b79986d1 -r 3e26719ab827 xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Tue Oct 24 11:21:48 2006 -0600
+++ b/xen/include/xen/mm.h      Wed Oct 25 12:12:01 2006 -0600
@@ -45,7 +45,8 @@ void end_boot_allocator(void);
 /* Generic allocator. These functions are *not* interrupt-safe. */
 void init_heap_pages(
     unsigned int zone, struct page_info *pg, unsigned long nr_pages);
-struct page_info *alloc_heap_pages(unsigned int zone, unsigned int order);
+struct page_info *alloc_heap_pages(
+    unsigned int zone, unsigned int cpu, unsigned int order);
 void free_heap_pages(
     unsigned int zone, struct page_info *pg, unsigned int order);
 void scrub_heap_pages(void);
@@ -61,8 +62,12 @@ void init_domheap_pages(paddr_t ps, padd
 void init_domheap_pages(paddr_t ps, paddr_t pe);
 struct page_info *alloc_domheap_pages(
     struct domain *d, unsigned int order, unsigned int memflags);
+struct page_info *__alloc_domheap_pages(
+    struct domain *d, unsigned int cpu, unsigned int order, 
+    unsigned int memflags);
 void free_domheap_pages(struct page_info *pg, unsigned int order);
 unsigned long avail_domheap_pages(void);
+unsigned long avail_heap_pages(int zone, int node);
 #define alloc_domheap_page(d) (alloc_domheap_pages(d,0,0))
 #define free_domheap_page(p)  (free_domheap_pages(p,0))
 
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h    Wed Oct 25 
12:12:01 2006 -0600
@@ -0,0 +1,77 @@
+/******************************************************************************
+ * xenbus_probe.h
+ *
+ * Talks to Xen Store to figure out what devices we have.
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 XenSource Ltd.
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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 _XENBUS_PROBE_H
+#define _XENBUS_PROBE_H
+
+#ifdef CONFIG_XEN_BACKEND
+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 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 void xenbus_backend_bus_register(void) {}
+static inline void xenbus_backend_device_register(void) {}
+#endif
+
+struct xen_bus_type
+{
+       char *root;
+       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);
+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 dev_changed(const char *node, struct xen_bus_type *bus);
+
+/* Simplified asprintf. Probably belongs in lib */
+extern char *kasprintf(const char *fmt, ...);
+
+#endif
+
diff -r d246b79986d1 -r 3e26719ab827 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c    Wed Oct 
25 12:12:01 2006 -0600
@@ -0,0 +1,271 @@
+/******************************************************************************
+ * Talks to Xen Store to figure out what devices we have (backend half).
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard
+ * Copyright (C) 2005, 2006 XenSource Ltd
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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.
+ */
+
+#define DPRINTK(fmt, args...)                          \
+       pr_debug("xenbus_probe (%s:%d) " fmt ".\n",     \
+                __FUNCTION__, __LINE__, ##args)
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/notifier.h>
+#include <linux/kthread.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/maddr.h>
+#include <asm/pgtable.h>
+#include <asm/hypervisor.h>
+#include <xen/xenbus.h>
+#include <xen/xen_proc.h>
+#include <xen/evtchn.h>
+#include <xen/features.h>
+#include <xen/hvm.h>
+
+#include "xenbus_comms.h"
+#include "xenbus_probe.h"
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
+static int xenbus_uevent_backend(struct device *dev, char **envp,
+                                int num_envp, char *buffer, int buffer_size);
+static int xenbus_probe_backend(const char *type, const char *domid);
+
+extern int read_otherend_details(struct xenbus_device *xendev,
+                                char *id_node, char *path_node);
+
+static int read_frontend_details(struct xenbus_device *xendev)
+{
+       return read_otherend_details(xendev, "frontend-id", "frontend");
+}
+
+/* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
+static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
+{
+       int domid, err;
+       const char *devid, *type, *frontend;
+       unsigned int typelen;
+
+       type = strchr(nodename, '/');
+       if (!type)
+               return -EINVAL;
+       type++;
+       typelen = strcspn(type, "/");
+       if (!typelen || type[typelen] != '/')
+               return -EINVAL;
+
+       devid = strrchr(nodename, '/') + 1;
+
+       err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
+                           "frontend", NULL, &frontend,
+                           NULL);
+       if (err)
+               return err;
+       if (strlen(frontend) == 0)
+               err = -ERANGE;
+       if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
+               err = -ENOENT;
+       kfree(frontend);
+
+       if (err)
+               return err;
+
+       if (snprintf(bus_id, BUS_ID_SIZE,
+                    "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
+               return -ENOSPC;
+       return 0;
+}
+
+static struct xen_bus_type xenbus_backend = {
+       .root = "backend",
+       .levels = 3,            /* backend/type/<frontend>/<id> */
+       .get_bus_id = backend_bus_id,
+       .probe = xenbus_probe_backend,
+       .bus = {
+               .name     = "xen-backend",
+               .match    = xenbus_match,
+               .probe    = xenbus_dev_probe,
+               .remove   = xenbus_dev_remove,
+//             .shutdown = xenbus_dev_shutdown,
+               .uevent   = xenbus_uevent_backend,
+       },
+       .dev = {
+               .bus_id = "xen-backend",
+       },
+};
+
+static int xenbus_uevent_backend(struct device *dev, char **envp,
+                                int num_envp, char *buffer, int buffer_size)
+{
+       struct xenbus_device *xdev;
+       struct xenbus_driver *drv;
+       int i = 0;
+       int length = 0;
+
+       DPRINTK("");
+
+       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,
+                      "XENBUS_BASE_PATH=%s", xenbus_backend.root);
+
+       /* terminate, set to next free slot, shrink available space */
+       envp[i] = NULL;
+       envp = &envp[i];
+       num_envp -= i;
+       buffer = &buffer[length];
+       buffer_size -= length;
+
+       if (dev->driver) {
+               drv = to_xenbus_driver(dev->driver);
+               if (drv && drv->uevent)
+                       return drv->uevent(xdev, envp, num_envp, buffer,
+                                          buffer_size);
+       }
+
+       return 0;
+}
+
+int xenbus_register_backend(struct xenbus_driver *drv)
+{
+       drv->read_otherend_details = read_frontend_details;
+
+       return xenbus_register_driver_common(drv, &xenbus_backend);
+}
+EXPORT_SYMBOL_GPL(xenbus_register_backend);
+
+/* backend/<typename>/<frontend-uuid>/<name> */
+static int xenbus_probe_backend_unit(const char *dir,
+                                    const char *type,
+                                    const char *name)
+{
+       char *nodename;
+       int err;
+
+       nodename = kasprintf("%s/%s", dir, name);
+       if (!nodename)
+               return -ENOMEM;
+
+       DPRINTK("%s\n", nodename);
+
+       err = xenbus_probe_node(&xenbus_backend, type, nodename);
+       kfree(nodename);
+       return err;
+}
+
+/* backend/<typename>/<frontend-domid> */
+static int xenbus_probe_backend(const char *type, const char *domid)
+{
+       char *nodename;
+       int err = 0;
+       char **dir;
+       unsigned int i, dir_n = 0;
+
+       DPRINTK("");
+
+       nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
+       if (!nodename)
+               return -ENOMEM;
+
+       dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
+       if (IS_ERR(dir)) {
+               kfree(nodename);
+               return PTR_ERR(dir);
+       }
+
+       for (i = 0; i < dir_n; i++) {
+               err = xenbus_probe_backend_unit(nodename, type, dir[i]);
+               if (err)
+                       break;
+       }
+       kfree(dir);
+       kfree(nodename);
+       return err;
+}
+
+static void backend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
+{
+       DPRINTK("");
+
+       dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
+}
+
+static struct xenbus_watch be_watch = {
+       .node = "backend",
+       .callback = backend_changed,
+};
+
+void xenbus_backend_suspend(int (*fn)(struct device *, void *))
+{
+       DPRINTK("");
+       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+}
+
+void xenbus_backend_resume(int (*fn)(struct device *, void *))
+{
+       DPRINTK("");
+       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+}
+
+void xenbus_backend_probe_and_watch(void)
+{
+       xenbus_probe_devices(&xenbus_backend);
+       register_xenbus_watch(&be_watch);
+}
+
+void xenbus_backend_bus_register(void)
+{
+       bus_register(&xenbus_backend.bus);
+}
+
+void xenbus_backend_device_register(void)
+{
+       device_register(&xenbus_backend.dev);
+}
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/blkfront/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/blkfront/Makefile    Wed Oct 25 12:12:01 
2006 -0600
@@ -0,0 +1,3 @@
+ifneq ($(KERNELRELEASE),)
+include $(src)/Kbuild
+endif
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopmd.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopmd.h   
Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,14 @@
+#ifndef _PGTABLE_NOPMD_H
+#define _PGTABLE_NOPMD_H
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
+#error "This version of Linux should not need compat pgtable-nopmd.h"
+#endif
+
+#define pud_t             pgd_t
+#define pud_offset(d, va)     d
+#define pud_none(pud)         0
+#define pud_present(pud)      1
+#define PTRS_PER_PUD          1
+
+#endif /* _PGTABLE_NOPMD_H */
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h   
Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,14 @@
+#ifndef _PGTABLE_NOPUD_H
+#define _PGTABLE_NOPUD_H
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
+#error "This version of Linux should not need compat pgtable-nopud.h"
+#endif
+
+#define pud_t             pgd_t
+#define pud_offset(d, va)     d
+#define pud_none(pud)         0
+#define pud_present(pud)      1
+#define PTRS_PER_PUD          1
+
+#endif /* _PGTABLE_NOPUD_H */
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/compat-include/linux/io.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/io.h    Wed Oct 25 
12:12:01 2006 -0600
@@ -0,0 +1,10 @@
+#ifndef _LINUX_IO_H
+#define _LINUX_IO_H
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+#error "This version of Linux should not need compat linux/io.h"
+#endif
+
+#include <asm/io.h>
+
+#endif
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/compat-include/linux/mutex.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/mutex.h Wed Oct 25 
12:12:01 2006 -0600
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2006 Cisco Systems.  All rights reserved.
+ *
+ * This file is released under the GPLv2.
+ */
+
+/* mutex compatibility for pre-2.6.16 kernels */
+
+#ifndef __LINUX_MUTEX_H
+#define __LINUX_MUTEX_H
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+#error "This version of Linux should not need compat mutex.h"
+#endif
+
+#include <linux/version.h>
+#include <asm/semaphore.h>
+
+#define mutex semaphore
+#define DEFINE_MUTEX(foo) DECLARE_MUTEX(foo)
+#define mutex_init(foo) init_MUTEX(foo)
+#define mutex_lock(foo) down(foo)
+#define mutex_lock_interruptible(foo) down_interruptible(foo)
+/* this function follows the spin_trylock() convention, so        *
+ * it is negated to the down_trylock() return values! Be careful  */
+#define mutex_trylock(foo) !down_trylock(foo)
+#define mutex_unlock(foo) up(foo)
+
+#endif /* __LINUX_MUTEX_H */
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 
25 12:12:01 2006 -0600
@@ -0,0 +1,52 @@
+#ifndef COMPAT_INCLUDE_XEN_PLATFORM_COMPAT_H
+#define COMPAT_INCLUDE_XEN_PLATFORM_COMPAT_H
+
+#include <linux/version.h>
+
+#include <linux/spinlock.h>
+
+#if defined(__LINUX_COMPILER_H) && !defined(__always_inline)
+#define __always_inline inline
+#endif
+
+#if defined(__LINUX_SPINLOCK_H) && !defined(DEFINE_SPINLOCK)
+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
+#endif
+
+#if defined(_LINUX_INIT_H) && !defined(__init)
+#define __init
+#endif
+
+#if defined(__LINUX_CACHE_H) && !defined(__read_mostly)
+#define __read_mostly
+#endif
+
+#if defined(_LINUX_SKBUFF_H) && !defined(NET_IP_ALIGN)
+#define NET_IP_ALIGN 0
+#endif
+
+#if defined(_LINUX_FS_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
+#define nonseekable_open(inode, filp) /* Nothing to do */
+#endif
+
+#if defined(_LINUX_MM_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+unsigned long vmalloc_to_pfn(void *addr);
+#endif
+
+#if defined(__LINUX_COMPLETION_H) && LINUX_VERSION_CODE < 
KERNEL_VERSION(2,6,11)
+unsigned long wait_for_completion_timeout(struct completion *x, unsigned long 
timeout);
+#endif
+
+#if defined(_LINUX_SCHED_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+signed long schedule_timeout_interruptible(signed long timeout);
+#endif
+
+#if defined(_LINUX_SLAB_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+void *kzalloc(size_t size, int flags);
+#endif
+
+#if defined(_LINUX_BLKDEV_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
+#define end_that_request_last(req, uptodate) end_that_request_last(req)
+#endif
+
+#endif
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/netfront/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/netfront/Makefile    Wed Oct 25 12:12:01 
2006 -0600
@@ -0,0 +1,3 @@
+ifneq ($(KERNELRELEASE),)
+include $(src)/Kbuild
+endif
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/platform-pci/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/platform-pci/Makefile        Wed Oct 25 
12:12:01 2006 -0600
@@ -0,0 +1,3 @@
+ifneq ($(KERNELRELEASE),)
+include $(src)/Kbuild
+endif
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/platform-pci/platform-compat.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c       Wed Oct 
25 12:12:01 2006 -0600
@@ -0,0 +1,116 @@
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <xen/platform-compat.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
+static int system_state = 1;
+EXPORT_SYMBOL(system_state);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
+size_t strcspn(const char *s, const char *reject)
+{
+        const char *p;
+        const char *r;
+        size_t count = 0;
+
+        for (p = s; *p != '\0'; ++p) {
+                for (r = reject; *r != '\0'; ++r) {
+                        if (*p == *r)
+                                return count;
+                }
+                ++count;
+        }
+
+        return count;
+}
+EXPORT_SYMBOL(strcspn);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+/*
+ * Map a vmalloc()-space virtual address to the physical page frame number.
+ */
+unsigned long vmalloc_to_pfn(void * vmalloc_addr)
+{
+        return page_to_pfn(vmalloc_to_page(vmalloc_addr));
+}
+EXPORT_SYMBOL(vmalloc_to_pfn);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+unsigned long wait_for_completion_timeout(struct completion *x, unsigned long 
timeout)
+{
+        might_sleep();
+
+        spin_lock_irq(&x->wait.lock);
+        if (!x->done) {
+                DECLARE_WAITQUEUE(wait, current);
+
+                wait.flags |= WQ_FLAG_EXCLUSIVE;
+                __add_wait_queue_tail(&x->wait, &wait);
+                do {
+                        __set_current_state(TASK_UNINTERRUPTIBLE);
+                        spin_unlock_irq(&x->wait.lock);
+                        timeout = schedule_timeout(timeout);
+                        spin_lock_irq(&x->wait.lock);
+                        if (!timeout) {
+                                __remove_wait_queue(&x->wait, &wait);
+                                goto out;
+                        }
+                } while (!x->done);
+                __remove_wait_queue(&x->wait, &wait);
+        }
+        x->done--;
+out:
+        spin_unlock_irq(&x->wait.lock);
+        return timeout;
+}
+EXPORT_SYMBOL(wait_for_completion_timeout);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
+/*
+    fake do_exit using complete_and_exit
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+asmlinkage NORET_TYPE void do_exit(long code)
+#else
+fastcall NORET_TYPE void do_exit(long code)
+#endif
+{
+    complete_and_exit(NULL, code);
+}
+EXPORT_SYMBOL_GPL(do_exit);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+signed long schedule_timeout_interruptible(signed long timeout)
+{
+       __set_current_state(TASK_INTERRUPTIBLE);
+       return schedule_timeout(timeout);
+}
+EXPORT_SYMBOL(schedule_timeout_interruptible);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+/**
+ * kzalloc - allocate memory. The memory is set to zero.
+ * @size: how many bytes of memory are required.
+ * @flags: the type of memory to allocate.
+ */
+void *kzalloc(size_t size, int flags)
+{
+       void *ret = kmalloc(size, flags);
+       if (ret)
+               memset(ret, 0, size);
+       return ret;
+}
+EXPORT_SYMBOL(kzalloc);
+#endif
diff -r d246b79986d1 -r 3e26719ab827 
unmodified_drivers/linux-2.6/xenbus/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/xenbus/Makefile      Wed Oct 25 12:12:01 
2006 -0600
@@ -0,0 +1,3 @@
+ifneq ($(KERNELRELEASE),)
+include $(src)/Kbuild
+endif
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/hvm/pmtimer.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/hvm/pmtimer.c        Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,63 @@
+#include <asm/hvm/vpt.h>
+#include <asm/hvm/io.h>
+#include <asm/hvm/support.h>
+
+#define TMR_STS (1 << 0)
+static void pmt_update_status(void *opaque)
+{
+   PMTState *s = opaque;
+   s->pm1_status |= TMR_STS;
+
+   /* TODO: When TMR_EN == 1, generate a SCI event */
+
+   set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
+}
+
+static int handle_pmt_io(ioreq_t *p)
+{
+    struct vcpu *v = current;
+    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
+    uint64_t curr_gtime;
+
+    if (p->size != 4 ||
+        p->pdata_valid ||
+        p->type != IOREQ_TYPE_PIO){
+        printk("HVM_PMT: wrong PM timer IO\n");
+        return 1;
+    }
+    
+    if (p->dir == 0) { /* write */
+        /* PM_TMR_BLK is read-only */
+        return 1;
+    } else if (p->dir == 1) { /* read */
+        curr_gtime = hvm_get_guest_time(s->vcpu);
+        s->pm1_timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
+        p->u.data = s->pm1_timer;
+        s->last_gtime = curr_gtime;
+        return 1;
+    }
+    return 0;
+}
+
+void pmtimer_init(struct vcpu *v, int base)
+{
+    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
+
+    s->pm1_timer = 0;
+    s->pm1_status = 0;
+    s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
+    s->vcpu = v;
+
+    init_timer(&s->timer, pmt_update_status, s, v->processor);
+    /* ACPI supports a 32-bit power management timer */
+    set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
+    
+    register_portio_handler(base, 4, handle_pmt_io);
+}
+
+void pmtimer_deinit(struct domain *d)
+{
+    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+
+    kill_timer(&s->timer);
+}
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/numa.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/numa.c       Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,308 @@
+/* 
+ * Generic VM initialization for x86-64 NUMA setups.
+ * Copyright 2002,2003 Andi Kleen, SuSE Labs.
+ * Adapted for Xen: Ryan Harper <ryanh@xxxxxxxxxx>
+ */ 
+
+#include <xen/mm.h>
+#include <xen/string.h>
+#include <xen/init.h>
+#include <xen/ctype.h>
+#include <xen/nodemask.h>
+#include <xen/numa.h>
+#include <xen/keyhandler.h>
+#include <xen/time.h>
+#include <xen/smp.h>
+#include <asm/acpi.h>
+
+static int numa_setup(char *s);
+custom_param("numa", numa_setup);
+
+#ifndef Dprintk
+#define Dprintk(x...)
+#endif
+
+/* from proto.h */
+#define round_up(x,y) ((((x)+(y))-1) & (~((y)-1)))
+
+struct node_data node_data[MAX_NUMNODES];
+
+int memnode_shift;
+u8  memnodemap[NODEMAPSIZE];
+
+unsigned char cpu_to_node[NR_CPUS] __read_mostly = {
+       [0 ... NR_CPUS-1] = NUMA_NO_NODE
+};
+unsigned char apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = {
+       [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
+};
+cpumask_t node_to_cpumask[MAX_NUMNODES] __read_mostly;
+
+nodemask_t node_online_map = { { [0] = 1UL } };
+
+/* Default NUMA to off for now. acpi=on required to enable it. */
+int numa_off __initdata = 1;
+
+int acpi_numa __initdata;
+
+/*
+ * Given a shift value, try to populate memnodemap[]
+ * Returns :
+ * 1 if OK
+ * 0 if memnodmap[] too small (of shift too small)
+ * -1 if node overlap or lost ram (shift too big)
+ */
+static int __init
+populate_memnodemap(const struct node *nodes, int numnodes, int shift)
+{
+       int i; 
+       int res = -1;
+       unsigned long addr, end;
+
+       if (shift >= 64)
+               return -1;
+       memset(memnodemap, 0xff, sizeof(memnodemap));
+       for (i = 0; i < numnodes; i++) {
+               addr = nodes[i].start;
+               end = nodes[i].end;
+               if (addr >= end)
+                       continue;
+               if ((end >> shift) >= NODEMAPSIZE)
+                       return 0;
+               do {
+                       if (memnodemap[addr >> shift] != 0xff)
+                               return -1;
+                       memnodemap[addr >> shift] = i;
+                       addr += (1UL << shift);
+               } while (addr < end);
+               res = 1;
+       } 
+       return res;
+}
+
+int __init compute_hash_shift(struct node *nodes, int numnodes)
+{
+       int shift = 20;
+
+       while (populate_memnodemap(nodes, numnodes, shift + 1) >= 0)
+               shift++;
+
+       printk(KERN_DEBUG "NUMA: Using %d for the hash shift.\n",
+               shift);
+
+       if (populate_memnodemap(nodes, numnodes, shift) != 1) {
+               printk(KERN_INFO
+       "Your memory is not aligned you need to rebuild your kernel "
+       "with a bigger NODEMAPSIZE shift=%d\n",
+                       shift);
+               return -1;
+       }
+       return shift;
+}
+
+/* initialize NODE_DATA given nodeid and start/end */
+void __init setup_node_bootmem(int nodeid, u64 start, u64 end)
+{ 
+       unsigned long start_pfn, end_pfn;
+
+       start_pfn = start >> PAGE_SHIFT;
+       end_pfn = end >> PAGE_SHIFT;
+
+       NODE_DATA(nodeid)->node_id = nodeid;
+       NODE_DATA(nodeid)->node_start_pfn = start_pfn;
+       NODE_DATA(nodeid)->node_spanned_pages = end_pfn - start_pfn;
+
+       node_set_online(nodeid);
+} 
+
+void __init numa_init_array(void)
+{
+       int rr, i;
+       /* There are unfortunately some poorly designed mainboards around
+          that only connect memory to a single CPU. This breaks the 1:1 
cpu->node
+          mapping. To avoid this fill in the mapping for all possible
+          CPUs, as the number of CPUs is not known yet. 
+          We round robin the existing nodes. */
+       rr = first_node(node_online_map);
+       for (i = 0; i < NR_CPUS; i++) {
+               if (cpu_to_node[i] != NUMA_NO_NODE)
+                       continue;
+               numa_set_node(i, rr);
+               rr = next_node(rr, node_online_map);
+               if (rr == MAX_NUMNODES)
+                       rr = first_node(node_online_map);
+       }
+
+}
+
+#ifdef CONFIG_NUMA_EMU
+static int numa_fake __initdata = 0;
+
+/* Numa emulation */
+static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
+{
+       int i;
+       struct node nodes[MAX_NUMNODES];
+       unsigned long sz = ((end_pfn - start_pfn)<<PAGE_SHIFT) / numa_fake;
+
+       /* Kludge needed for the hash function */
+       if (hweight64(sz) > 1) {
+               unsigned long x = 1;
+               while ((x << 1) < sz)
+                       x <<= 1;
+               if (x < sz/2)
+                       printk(KERN_ERR "Numa emulation unbalanced. Complain to 
maintainer\n");
+               sz = x;
+       }
+
+       memset(&nodes,0,sizeof(nodes));
+       for (i = 0; i < numa_fake; i++) {
+               nodes[i].start = (start_pfn<<PAGE_SHIFT) + i*sz;
+               if (i == numa_fake-1)
+                       sz = (end_pfn<<PAGE_SHIFT) - nodes[i].start;
+               nodes[i].end = nodes[i].start + sz;
+               printk(KERN_INFO "Faking node %d at %"PRIx64"-%"PRIx64" 
(%"PRIu64"MB)\n",
+                      i,
+                      nodes[i].start, nodes[i].end,
+                      (nodes[i].end - nodes[i].start) >> 20);
+               node_set_online(i);
+       }
+       memnode_shift = compute_hash_shift(nodes, numa_fake);
+       if (memnode_shift < 0) {
+               memnode_shift = 0;
+               printk(KERN_ERR "No NUMA hash function found. Emulation 
disabled.\n");
+               return -1;
+       }
+       for_each_online_node(i)
+               setup_node_bootmem(i, nodes[i].start, nodes[i].end);
+       numa_init_array();
+       return 0;
+}
+#endif
+
+void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+{ 
+       int i;
+
+#ifdef CONFIG_NUMA_EMU
+       if (numa_fake && !numa_emulation(start_pfn, end_pfn))
+               return;
+#endif
+
+#ifdef CONFIG_ACPI_NUMA
+       if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
+                                         end_pfn << PAGE_SHIFT))
+               return;
+#endif
+
+       printk(KERN_INFO "%s\n",
+              numa_off ? "NUMA turned off" : "No NUMA configuration found");
+
+       printk(KERN_INFO "Faking a node at %016lx-%016lx\n", 
+              start_pfn << PAGE_SHIFT,
+              end_pfn << PAGE_SHIFT); 
+       /* setup dummy node covering all memory */ 
+       memnode_shift = 63; 
+       memnodemap[0] = 0;
+       nodes_clear(node_online_map);
+       node_set_online(0);
+       for (i = 0; i < NR_CPUS; i++)
+               numa_set_node(i, 0);
+       node_to_cpumask[0] = cpumask_of_cpu(0);
+       setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
+}
+
+__cpuinit void numa_add_cpu(int cpu)
+{
+       set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
+} 
+
+void __cpuinit numa_set_node(int cpu, int node)
+{
+       cpu_to_node[cpu] = node;
+}
+
+/* [numa=off] */
+static __init int numa_setup(char *opt) 
+{ 
+       if (!strncmp(opt,"off",3))
+               numa_off = 1;
+       if (!strncmp(opt,"on",2))
+               numa_off = 0;
+#ifdef CONFIG_NUMA_EMU
+       if(!strncmp(opt, "fake=", 5)) {
+               numa_off = 0;
+               numa_fake = simple_strtoul(opt+5,NULL,0); ;
+               if (numa_fake >= MAX_NUMNODES)
+                       numa_fake = MAX_NUMNODES;
+       }
+#endif
+#ifdef CONFIG_ACPI_NUMA
+       if (!strncmp(opt,"noacpi",6)) {
+               numa_off = 0;
+               acpi_numa = -1;
+       }
+#endif
+       return 1;
+} 
+
+/*
+ * Setup early cpu_to_node.
+ *
+ * Populate cpu_to_node[] only if x86_cpu_to_apicid[],
+ * and apicid_to_node[] tables have valid entries for a CPU.
+ * This means we skip cpu_to_node[] initialisation for NUMA
+ * emulation and faking node case (when running a kernel compiled
+ * for NUMA on a non NUMA box), which is OK as cpu_to_node[]
+ * is already initialized in a round robin manner at numa_init_array,
+ * prior to this call, and this initialization is good enough
+ * for the fake NUMA cases.
+ */
+void __init init_cpu_to_node(void)
+{
+       int i;
+       for (i = 0; i < NR_CPUS; i++) {
+               u8 apicid = x86_cpu_to_apicid[i];
+               if (apicid == BAD_APICID)
+                       continue;
+               if (apicid_to_node[apicid] == NUMA_NO_NODE)
+                       continue;
+               numa_set_node(i,apicid_to_node[apicid]);
+       }
+}
+
+EXPORT_SYMBOL(cpu_to_node);
+EXPORT_SYMBOL(node_to_cpumask);
+EXPORT_SYMBOL(memnode_shift);
+EXPORT_SYMBOL(memnodemap);
+EXPORT_SYMBOL(node_data);
+
+static void dump_numa(unsigned char key)
+{
+       s_time_t now = NOW();
+       int i;
+
+       printk("'%c' pressed -> dumping numa info (now-0x%X:%08X)\n", key,
+                 (u32)(now>>32), (u32)now);
+
+       for_each_online_node(i) {
+               unsigned long pa = (NODE_DATA(i)->node_start_pfn + 1)<< 
PAGE_SHIFT;
+               printk("idx%d -> NODE%d start->%lu size->%lu\n",
+                         i, NODE_DATA(i)->node_id,
+                         NODE_DATA(i)->node_start_pfn,
+                         NODE_DATA(i)->node_spanned_pages);
+               /* sanity check phys_to_nid() */
+               printk("phys_to_nid(%lx) -> %d should be %d\n", pa, 
phys_to_nid(pa),
+                         NODE_DATA(i)->node_id);
+       }
+       for_each_online_cpu(i)
+               printk("CPU%d -> NODE%d\n", i, cpu_to_node[i]);
+}
+
+static __init int register_numa_trigger(void)
+{
+       register_keyhandler('u', dump_numa, "dump numa info");
+       return 0;
+}
+__initcall(register_numa_trigger);
+
diff -r d246b79986d1 -r 3e26719ab827 xen/arch/x86/srat.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/srat.c       Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,315 @@
+/*
+ * ACPI 3.0 based NUMA setup
+ * Copyright 2004 Andi Kleen, SuSE Labs.
+ *
+ * Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
+ *
+ * Called from acpi_numa_init while reading the SRAT and SLIT tables.
+ * Assumes all memory regions belonging to a single proximity domain
+ * are in one chunk. Holes between them will be included in the node.
+ * 
+ * Adapted for Xen: Ryan Harper <ryanh@xxxxxxxxxx>
+ */
+
+#include <xen/init.h>
+#include <xen/mm.h>
+#include <xen/inttypes.h>
+#include <xen/nodemask.h>
+#include <xen/acpi.h>
+#include <xen/numa.h>
+#include <asm/page.h>
+
+static struct acpi_table_slit *acpi_slit;
+
+static nodemask_t nodes_parsed __initdata;
+static nodemask_t nodes_found __initdata;
+static struct node nodes[MAX_NUMNODES] __initdata;
+static u8 pxm2node[256] = { [0 ... 255] = 0xff };
+
+/* Too small nodes confuse the VM badly. Usually they result
+   from BIOS bugs. */
+#define NODE_MIN_SIZE (4*1024*1024)
+
+static int node_to_pxm(int n);
+
+int pxm_to_node(int pxm)
+{
+       if ((unsigned)pxm >= 256)
+               return -1;
+       /* Extend 0xff to (int)-1 */
+       return (signed char)pxm2node[pxm];
+}
+
+static __init int setup_node(int pxm)
+{
+       unsigned node = pxm2node[pxm];
+       if (node == 0xff) {
+               if (nodes_weight(nodes_found) >= MAX_NUMNODES)
+                       return -1;
+               node = first_unset_node(nodes_found); 
+               node_set(node, nodes_found);
+               pxm2node[pxm] = node;
+       }
+       return pxm2node[pxm];
+}
+
+static __init int conflicting_nodes(u64 start, u64 end)
+{
+       int i;
+       for_each_node_mask(i, nodes_parsed) {
+               struct node *nd = &nodes[i];
+               if (nd->start == nd->end)
+                       continue;
+               if (nd->end > start && nd->start < end)
+                       return i;
+               if (nd->end == end && nd->start == start)
+                       return i;
+       }
+       return -1;
+}
+
+static __init void cutoff_node(int i, u64 start, u64 end)
+{
+       struct node *nd = &nodes[i];
+       if (nd->start < start) {
+               nd->start = start;
+               if (nd->end < nd->start)
+                       nd->start = nd->end;
+       }
+       if (nd->end > end) {
+               nd->end = end;
+               if (nd->start > nd->end)
+                       nd->start = nd->end;
+       }
+}
+
+static __init void bad_srat(void)
+{
+       int i;
+       printk(KERN_ERR "SRAT: SRAT not used.\n");
+       acpi_numa = -1;
+       for (i = 0; i < MAX_LOCAL_APIC; i++)
+               apicid_to_node[i] = NUMA_NO_NODE;
+}
+
+static __init inline int srat_disabled(void)
+{
+       return numa_off || acpi_numa < 0;
+}
+
+/*
+ * A lot of BIOS fill in 10 (= no distance) everywhere. This messes
+ * up the NUMA heuristics which wants the local node to have a smaller
+ * distance than the others.
+ * Do some quick checks here and only use the SLIT if it passes.
+ */
+static __init int slit_valid(struct acpi_table_slit *slit)
+{
+       int i, j;
+       int d = slit->localities;
+       for (i = 0; i < d; i++) {
+               for (j = 0; j < d; j++)  {
+                       u8 val = slit->entry[d*i + j];
+                       if (i == j) {
+                               if (val != 10)
+                                       return 0;
+                       } else if (val <= 10)
+                               return 0;
+               }
+       }
+       return 1;
+}
+
+/* Callback for SLIT parsing */
+void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
+{
+       if (!slit_valid(slit)) {
+               printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n");
+               return;
+       }
+       acpi_slit = slit;
+}
+
+/* Callback for Proximity Domain -> LAPIC mapping */
+void __init
+acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
+{
+       int pxm, node;
+       if (srat_disabled())
+               return;
+       if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) 
{                bad_srat();
+               return;
+       }
+       if (pa->flags.enabled == 0)
+               return;
+       pxm = pa->proximity_domain;
+       node = setup_node(pxm);
+       if (node < 0) {
+               printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+               bad_srat();
+               return;
+       }
+       apicid_to_node[pa->apic_id] = node;
+       acpi_numa = 1;
+       printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+              pxm, pa->apic_id, node);
+}
+
+/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
+void __init
+acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
+{
+       struct node *nd;
+       u64 start, end;
+       int node, pxm;
+       int i;
+
+       if (srat_disabled())
+               return;
+       if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) {
+               bad_srat();
+               return;
+       }
+       if (ma->flags.enabled == 0)
+               return;
+       start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
+       end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
+       pxm = ma->proximity_domain;
+       node = setup_node(pxm);
+       if (node < 0) {
+               printk(KERN_ERR "SRAT: Too many proximity domains.\n");
+               bad_srat();
+               return;
+       }
+       /* It is fine to add this area to the nodes data it will be used later*/
+       if (ma->flags.hot_pluggable == 1)
+               printk(KERN_INFO "SRAT: hot plug zone found %"PRIx64" - 
%"PRIx64" \n",
+                               start, end);
+       i = conflicting_nodes(start, end);
+       if (i == node) {
+               printk(KERN_WARNING
+               "SRAT: Warning: PXM %d (%"PRIx64"-%"PRIx64") overlaps with 
itself (%"
+               PRIx64"-%"PRIx64")\n", pxm, start, end, nodes[i].start, 
nodes[i].end);
+       } else if (i >= 0) {
+               printk(KERN_ERR
+                      "SRAT: PXM %d (%"PRIx64"-%"PRIx64") overlaps with PXM %d 
(%"
+                      PRIx64"-%"PRIx64")\n", pxm, start, end, node_to_pxm(i),
+                          nodes[i].start, nodes[i].end);
+               bad_srat();
+               return;
+       }
+       nd = &nodes[node];
+       if (!node_test_and_set(node, nodes_parsed)) {
+               nd->start = start;
+               nd->end = end;
+       } else {
+               if (start < nd->start)
+                       nd->start = start;
+               if (nd->end < end)
+                       nd->end = end;
+       }
+       printk(KERN_INFO "SRAT: Node %u PXM %u %"PRIx64"-%"PRIx64"\n", node, 
pxm,
+              nd->start, nd->end);
+}
+
+/* Sanity check to catch more bad SRATs (they are amazingly common).
+   Make sure the PXMs cover all memory. */
+static int nodes_cover_memory(void)
+{
+       int i;
+       u64 pxmram, e820ram;
+
+       pxmram = 0;
+       for_each_node_mask(i, nodes_parsed) {
+               u64 s = nodes[i].start >> PAGE_SHIFT;
+               u64 e = nodes[i].end >> PAGE_SHIFT;
+               pxmram += e - s;
+       }
+
+       e820ram = max_page;
+       /* We seem to lose 3 pages somewhere. Allow a bit of slack. */
+       if ((long)(e820ram - pxmram) >= 1*1024*1024) {
+               printk(KERN_ERR "SRAT: PXMs only cover %"PRIu64"MB of your %"
+                       PRIu64"MB e820 RAM. Not used.\n",
+                       (pxmram << PAGE_SHIFT) >> 20,
+                       (e820ram << PAGE_SHIFT) >> 20);
+               return 0;
+       }
+       return 1;
+}
+
+static void unparse_node(int node)
+{
+       int i;
+       node_clear(node, nodes_parsed);
+       for (i = 0; i < MAX_LOCAL_APIC; i++) {
+               if (apicid_to_node[i] == node)
+                       apicid_to_node[i] = NUMA_NO_NODE;
+       }
+}
+
+void __init acpi_numa_arch_fixup(void) {}
+
+/* Use the information discovered above to actually set up the nodes. */
+int __init acpi_scan_nodes(u64 start, u64 end)
+{
+       int i;
+
+       /* First clean up the node list */
+       for (i = 0; i < MAX_NUMNODES; i++) {
+               cutoff_node(i, start, end);
+               if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE)
+                       unparse_node(i);
+       }
+
+       if (acpi_numa <= 0)
+               return -1;
+
+       if (!nodes_cover_memory()) {
+               bad_srat();
+               return -1;
+       }
+
+       memnode_shift = compute_hash_shift(nodes, MAX_NUMNODES);
+       if (memnode_shift < 0) {
+               printk(KERN_ERR
+                    "SRAT: No NUMA node hash function found. Contact 
maintainer\n");
+               bad_srat();
+               return -1;
+       }
+
+       /* Finally register nodes */
+       for_each_node_mask(i, nodes_parsed)
+               setup_node_bootmem(i, nodes[i].start, nodes[i].end);
+       for (i = 0; i < NR_CPUS; i++) { 
+               if (cpu_to_node[i] == NUMA_NO_NODE)
+                       continue;
+               if (!node_isset(cpu_to_node[i], nodes_parsed))
+                       numa_set_node(i, NUMA_NO_NODE);
+       }
+       numa_init_array();
+       return 0;
+}
+
+static int node_to_pxm(int n)
+{
+       int i;
+       if (pxm2node[n] == n)
+               return n;
+       for (i = 0; i < 256; i++)
+               if (pxm2node[i] == n)
+                       return i;
+       return 0;
+}
+
+int __node_distance(int a, int b)
+{
+       int index;
+
+       if (!acpi_slit)
+               return a == b ? 10 : 20;
+       index = acpi_slit->localities * node_to_pxm(a);
+       return acpi_slit->entry[index + node_to_pxm(b)];
+}
+
+EXPORT_SYMBOL(__node_distance);
diff -r d246b79986d1 -r 3e26719ab827 xen/drivers/acpi/numa.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/drivers/acpi/numa.c   Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,216 @@
+/*
+ *  acpi_numa.c - ACPI NUMA support
+ *
+ *  Copyright (C) 2002 Takayoshi Kochi <t-kochi@xxxxxxxxxxxxx>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#if 0
+#include <linux/module.h>
+#include <linux/kernel.h>
+#endif
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/types.h>
+#include <xen/errno.h>
+#include <xen/acpi.h>
+#include <xen/numa.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acmacros.h>
+#include <asm/page.h> /* __va() */
+
+#define ACPI_NUMA      0x80000000
+#define _COMPONENT     ACPI_NUMA
+ACPI_MODULE_NAME("numa")
+
+extern int __init acpi_table_parse_madt_family(enum acpi_table_id id,
+                                              unsigned long madt_size,
+                                              int entry_id,
+                                              acpi_madt_entry_handler handler,
+                                              unsigned int max_entries);
+
+void __init acpi_table_print_srat_entry(acpi_table_entry_header * header)
+{
+
+       ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
+
+       if (!header)
+               return;
+
+       switch (header->type) {
+
+       case ACPI_SRAT_PROCESSOR_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+               {
+                       struct acpi_table_processor_affinity *p =
+                           (struct acpi_table_processor_affinity *)header;
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                         "SRAT Processor (id[0x%02x] 
eid[0x%02x]) in proximity domain %d %s\n",
+                                         p->apic_id, p->lsapic_eid,
+                                         p->proximity_domain,
+                                         p->flags.
+                                         enabled ? "enabled" : "disabled"));
+               }
+#endif                         /* ACPI_DEBUG_OUTPUT */
+               break;
+
+       case ACPI_SRAT_MEMORY_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+               {
+                       struct acpi_table_memory_affinity *p =
+                           (struct acpi_table_memory_affinity *)header;
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                         "SRAT Memory (0x%08x%08x length 
0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
+                                         p->base_addr_hi, p->base_addr_lo,
+                                         p->length_hi, p->length_lo,
+                                         p->memory_type, p->proximity_domain,
+                                         p->flags.
+                                         enabled ? "enabled" : "disabled",
+                                         p->flags.
+                                         hot_pluggable ? " hot-pluggable" :
+                                         ""));
+               }
+#endif                         /* ACPI_DEBUG_OUTPUT */
+               break;
+
+       default:
+               printk(KERN_WARNING PREFIX
+                      "Found unsupported SRAT entry (type = 0x%x)\n",
+                      header->type);
+               break;
+       }
+}
+
+static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size)
+{
+       struct acpi_table_slit *slit;
+       u32 localities;
+
+       if (!phys_addr || !size)
+               return -EINVAL;
+
+       slit = (struct acpi_table_slit *)__va(phys_addr);
+
+       /* downcast just for %llu vs %lu for i386/ia64  */
+       localities = (u32) slit->localities;
+
+       acpi_numa_slit_init(slit);
+
+       return 0;
+}
+
+static int __init
+acpi_parse_processor_affinity(acpi_table_entry_header * header,
+                             const unsigned long end)
+{
+       struct acpi_table_processor_affinity *processor_affinity;
+
+       processor_affinity = (struct acpi_table_processor_affinity *)header;
+       if (!processor_affinity)
+               return -EINVAL;
+
+       acpi_table_print_srat_entry(header);
+
+       /* let architecture-dependent part to do it */
+       acpi_numa_processor_affinity_init(processor_affinity);
+
+       return 0;
+}
+
+static int __init
+acpi_parse_memory_affinity(acpi_table_entry_header * header,
+                          const unsigned long end)
+{
+       struct acpi_table_memory_affinity *memory_affinity;
+
+       memory_affinity = (struct acpi_table_memory_affinity *)header;
+       if (!memory_affinity)
+               return -EINVAL;
+
+       acpi_table_print_srat_entry(header);
+
+       /* let architecture-dependent part to do it */
+       acpi_numa_memory_affinity_init(memory_affinity);
+
+       return 0;
+}
+
+static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size)
+{
+       struct acpi_table_srat *srat;
+
+       if (!phys_addr || !size)
+               return -EINVAL;
+
+       srat = (struct acpi_table_srat *)__va(phys_addr);
+
+       return 0;
+}
+
+int __init
+acpi_table_parse_srat(enum acpi_srat_entry_id id,
+                     acpi_madt_entry_handler handler, unsigned int max_entries)
+{
+       return acpi_table_parse_madt_family(ACPI_SRAT,
+                                           sizeof(struct acpi_table_srat), id,
+                                           handler, max_entries);
+}
+
+int __init acpi_numa_init(void)
+{
+       int result;
+
+       /* SRAT: Static Resource Affinity Table */
+       result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat);
+
+       if (result > 0) {
+               result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY,
+                                              acpi_parse_processor_affinity,
+                                              NR_CPUS);
+               result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY, 
acpi_parse_memory_affinity, NR_NODE_MEMBLKS); // IA64 specific
+       }
+
+       /* SLIT: System Locality Information Table */
+       result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit);
+
+       acpi_numa_arch_fixup();
+       return 0;
+}
+
+#if 0
+int acpi_get_pxm(acpi_handle h)
+{
+       unsigned long pxm;
+       acpi_status status;
+       acpi_handle handle;
+       acpi_handle phandle = h;
+
+       do {
+               handle = phandle;
+               status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
+               if (ACPI_SUCCESS(status))
+                       return (int)pxm;
+               status = acpi_get_parent(handle, &phandle);
+       } while (ACPI_SUCCESS(status));
+       return -1;
+}
+
+EXPORT_SYMBOL(acpi_get_pxm);
+#endif
diff -r d246b79986d1 -r 3e26719ab827 xen/include/asm-x86/hvm/vpt.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h     Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,151 @@
+/*
+ * vpt.h: Virtual Platform Timer definitions
+ *
+ * Copyright (c) 2004, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef __ASM_X86_HVM_VPT_H__
+#define __ASM_X86_HVM_VPT_H__
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/time.h>
+#include <xen/errno.h>
+#include <xen/time.h>
+#include <xen/timer.h>
+#include <asm/hvm/vpic.h>
+
+#define PIT_FREQ 1193181
+#define PIT_BASE 0x40
+
+typedef struct PITChannelState {
+    int count; /* can be 65536 */
+    u16 latched_count;
+    u8 count_latched;
+    u8 status_latched;
+    u8 status;
+    u8 read_state;
+    u8 write_state;
+    u8 write_latch;
+    u8 rw_mode;
+    u8 mode;
+    u8 bcd; /* not supported */
+    u8 gate; /* timer start */
+    s64 count_load_time;
+    /* irq handling */
+    struct vcpu      *vcpu;
+    struct periodic_time *pt;
+} PITChannelState;
+
+typedef struct PITState {
+    PITChannelState channels[3];
+    int speaker_data_on;
+    int dummy_refresh_clock;
+} PITState;
+
+#define RTC_SIZE 14
+typedef struct RTCState {
+    uint8_t cmos_data[RTC_SIZE];  /* Only handle time/interrupt part in HV */
+    uint8_t cmos_index;
+    struct tm current_tm;
+    int irq;
+    /* second update */
+    int64_t next_second_time;
+    struct timer second_timer;
+    struct timer second_timer2;
+    struct vcpu      *vcpu;
+    struct periodic_time *pt;
+} RTCState;
+
+#define FREQUENCE_PMTIMER  3579545
+typedef struct PMTState {
+    uint32_t pm1_timer;
+    uint32_t pm1_status;
+    uint64_t last_gtime;
+    struct timer timer;
+    uint64_t scale;
+    struct vcpu *vcpu;
+} PMTState;
+
+/*
+ * Abstract layer of periodic time, one short time.
+ */
+typedef void time_cb(struct vcpu *v, void *opaque);
+
+struct periodic_time {
+    char enabled;               /* enabled */
+    char one_shot;              /* one shot time */
+    char irq;
+    char first_injected;        /* flag to prevent shadow window */
+    u32 pending_intr_nr;        /* the couner for pending timer interrupts */
+    u32 period;                 /* frequency in ns */
+    u64 period_cycles;          /* frequency in cpu cycles */
+    s_time_t scheduled;         /* scheduled timer interrupt */
+    u64 last_plt_gtime;         /* platform time when last IRQ is injected */
+    struct timer timer;         /* ac_timer */
+    time_cb *cb;
+    void *priv;                 /* ponit back to platform time source */
+};
+
+struct pl_time {    /* platform time */
+    struct periodic_time periodic_tm;
+    struct PITState      vpit;
+    struct RTCState      vrtc;
+    struct PMTState      vpmt;
+};
+
+static __inline__ s_time_t get_scheduled(
+    struct vcpu *v, int irq,
+    struct periodic_time *pt)
+{
+    if ( is_irq_enabled(v, irq) ) {
+        return pt->scheduled;
+    }
+    else
+        return -1;
+}
+
+extern u64 hvm_get_guest_time(struct vcpu *v);
+/*
+ * get processor time.
+ * unit: TSC
+ */
+static __inline__ int64_t hvm_get_clock(struct vcpu *v)
+{
+    uint64_t  gtsc;
+
+    gtsc = hvm_get_guest_time(v);
+    return gtsc;
+}
+
+#define ticks_per_sec(v)      (v->domain->arch.hvm_domain.tsc_frequency)
+
+/* to hook the ioreq packet to get the PIT initialization info */
+extern void hvm_hooks_assist(struct vcpu *v);
+extern void pickup_deactive_ticks(struct periodic_time *vpit);
+extern struct periodic_time *create_periodic_time(u32 period, char irq, char 
one_shot, time_cb *cb, void *data);
+extern void destroy_periodic_time(struct periodic_time *pt);
+void pit_init(struct vcpu *v, unsigned long cpu_khz);
+void rtc_init(struct vcpu *v, int base, int irq);
+void rtc_deinit(struct domain *d);
+void pmtimer_init(struct vcpu *v, int base);
+void pmtimer_deinit(struct domain *d);
+int is_rtc_periodic_irq(void *opaque);
+void pt_timer_fn(void *data);
+void pit_time_fired(struct vcpu *v, void *priv);
+
+#endif /* __ASM_X86_HVM_VPT_H__ */
diff -r d246b79986d1 -r 3e26719ab827 xen/include/asm-x86/numa.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/numa.h        Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,78 @@
+#ifndef _ASM_X8664_NUMA_H 
+#define _ASM_X8664_NUMA_H 1
+
+#include <xen/cpumask.h>
+
+#define NODES_SHIFT 6
+
+extern unsigned char cpu_to_node[];
+extern cpumask_t     node_to_cpumask[];
+
+#define cpu_to_node(cpu)               (cpu_to_node[cpu])
+#define parent_node(node)              (node)
+#define node_to_first_cpu(node)  (__ffs(node_to_cpumask[node]))
+#define node_to_cpumask(node)    (node_to_cpumask[node])
+
+struct node { 
+       u64 start,end; 
+};
+
+extern int compute_hash_shift(struct node *nodes, int numnodes);
+extern int pxm_to_node(int nid);
+
+#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
+#define VIRTUAL_BUG_ON(x) 
+#define NODEMAPSIZE 0xfff
+
+extern void numa_add_cpu(int cpu);
+extern void numa_init_array(void);
+extern int numa_off;
+
+extern void numa_set_node(int cpu, int node);
+
+extern void setup_node_bootmem(int nodeid, u64 start, u64 end);
+extern unsigned char apicid_to_node[256];
+#ifdef CONFIG_NUMA
+extern void __init init_cpu_to_node(void);
+
+static inline void clear_node_cpumask(int cpu)
+{
+       clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
+}
+
+/* Simple perfect hash to map physical addresses to node numbers */
+extern int memnode_shift; 
+extern u8  memnodemap[NODEMAPSIZE]; 
+
+struct node_data {
+    unsigned long node_start_pfn;
+    unsigned long node_spanned_pages;
+    unsigned int  node_id;
+};
+
+extern struct node_data node_data[];
+
+static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) 
+{ 
+       unsigned nid; 
+       VIRTUAL_BUG_ON((addr >> memnode_shift) >= NODEMAPSIZE);
+       nid = memnodemap[addr >> memnode_shift]; 
+       VIRTUAL_BUG_ON(nid >= MAX_NUMNODES || !node_data[nid]); 
+       return nid; 
+} 
+
+#define NODE_DATA(nid)         (&(node_data[nid]))
+
+#define node_start_pfn(nid)    (NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid)       (NODE_DATA(nid)->node_start_pfn + \
+                                NODE_DATA(nid)->node_spanned_pages)
+
+
+#else
+#define init_cpu_to_node() do {} while (0)
+#define clear_node_cpumask(cpu) do {} while (0)
+#endif
+
+#define NUMA_NO_NODE 0xff
+
+#endif
diff -r d246b79986d1 -r 3e26719ab827 xen/include/xen/nodemask.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xen/nodemask.h        Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,338 @@
+#ifndef __LINUX_NODEMASK_H
+#define __LINUX_NODEMASK_H
+
+/*
+ * Nodemasks provide a bitmap suitable for representing the
+ * set of Node's in a system, one bit position per Node number.
+ *
+ * See detailed comments in the file linux/bitmap.h describing the
+ * data type on which these nodemasks are based.
+ *
+ * For details of nodemask_scnprintf() and nodemask_parse(),
+ * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
+ *
+ * The available nodemask operations are:
+ *
+ * void node_set(node, mask)           turn on bit 'node' in mask
+ * void node_clear(node, mask)         turn off bit 'node' in mask
+ * void nodes_setall(mask)             set all bits
+ * void nodes_clear(mask)              clear all bits
+ * int node_isset(node, mask)          true iff bit 'node' set in mask
+ * int node_test_and_set(node, mask)   test and set bit 'node' in mask
+ *
+ * void nodes_and(dst, src1, src2)     dst = src1 & src2  [intersection]
+ * void nodes_or(dst, src1, src2)      dst = src1 | src2  [union]
+ * void nodes_xor(dst, src1, src2)     dst = src1 ^ src2
+ * void nodes_andnot(dst, src1, src2)  dst = src1 & ~src2
+ * void nodes_complement(dst, src)     dst = ~src
+ *
+ * int nodes_equal(mask1, mask2)       Does mask1 == mask2?
+ * int nodes_intersects(mask1, mask2)  Do mask1 and mask2 intersect?
+ * int nodes_subset(mask1, mask2)      Is mask1 a subset of mask2?
+ * int nodes_empty(mask)               Is mask empty (no bits sets)?
+ * int nodes_full(mask)                        Is mask full (all bits sets)?
+ * int nodes_weight(mask)              Hamming weight - number of set bits
+ *
+ * void nodes_shift_right(dst, src, n) Shift right
+ * void nodes_shift_left(dst, src, n)  Shift left
+ *
+ * int first_node(mask)                        Number lowest set bit, or 
MAX_NUMNODES
+ * int next_node(node, mask)           Next node past 'node', or MAX_NUMNODES
+ * int first_unset_node(mask)          First node not set in mask, or 
+ *                                     MAX_NUMNODES.
+ *
+ * nodemask_t nodemask_of_node(node)   Return nodemask with bit 'node' set
+ * NODE_MASK_ALL                       Initializer - all bits set
+ * NODE_MASK_NONE                      Initializer - no bits set
+ * unsigned long *nodes_addr(mask)     Array of unsigned long's in mask
+ *
+ * int nodemask_scnprintf(buf, len, mask) Format nodemask for printing
+ * int nodemask_parse(ubuf, ulen, mask)        Parse ascii string as nodemask
+ *
+ * for_each_node_mask(node, mask)      for-loop node over mask
+ *
+ * int num_online_nodes()              Number of online Nodes
+ * int num_possible_nodes()            Number of all possible Nodes
+ *
+ * int node_online(node)               Is some node online?
+ * int node_possible(node)             Is some node possible?
+ *
+ * int any_online_node(mask)           First online node in mask
+ *
+ * node_set_online(node)               set bit 'node' in node_online_map
+ * node_set_offline(node)              clear bit 'node' in node_online_map
+ *
+ * for_each_node(node)                 for-loop node over node_possible_map
+ * for_each_online_node(node)          for-loop node over node_online_map
+ *
+ * Subtlety:
+ * 1) The 'type-checked' form of node_isset() causes gcc (3.3.2, anyway)
+ *    to generate slightly worse code.  So use a simple one-line #define
+ *    for node_isset(), instead of wrapping an inline inside a macro, the
+ *    way we do the other calls.
+ */
+
+#include <xen/kernel.h>
+#include <xen/bitmap.h>
+#include <xen/numa.h>
+
+typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
+extern nodemask_t _unused_nodemask_arg_;
+
+#define node_set(node, dst) __node_set((node), &(dst))
+static inline void __node_set(int node, volatile nodemask_t *dstp)
+{
+       set_bit(node, dstp->bits);
+}
+
+#define node_clear(node, dst) __node_clear((node), &(dst))
+static inline void __node_clear(int node, volatile nodemask_t *dstp)
+{
+       clear_bit(node, dstp->bits);
+}
+
+#define nodes_setall(dst) __nodes_setall(&(dst), MAX_NUMNODES)
+static inline void __nodes_setall(nodemask_t *dstp, int nbits)
+{
+       bitmap_fill(dstp->bits, nbits);
+}
+
+#define nodes_clear(dst) __nodes_clear(&(dst), MAX_NUMNODES)
+static inline void __nodes_clear(nodemask_t *dstp, int nbits)
+{
+       bitmap_zero(dstp->bits, nbits);
+}
+
+/* No static inline type checking - see Subtlety (1) above. */
+#define node_isset(node, nodemask) test_bit((node), (nodemask).bits)
+
+#define node_test_and_set(node, nodemask) \
+                       __node_test_and_set((node), &(nodemask))
+static inline int __node_test_and_set(int node, nodemask_t *addr)
+{
+       return test_and_set_bit(node, addr->bits);
+}
+
+#define nodes_and(dst, src1, src2) \
+                       __nodes_and(&(dst), &(src1), &(src2), MAX_NUMNODES)
+static inline void __nodes_and(nodemask_t *dstp, const nodemask_t *src1p,
+                                       const nodemask_t *src2p, int nbits)
+{
+       bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
+}
+
+#define nodes_or(dst, src1, src2) \
+                       __nodes_or(&(dst), &(src1), &(src2), MAX_NUMNODES)
+static inline void __nodes_or(nodemask_t *dstp, const nodemask_t *src1p,
+                                       const nodemask_t *src2p, int nbits)
+{
+       bitmap_or(dstp->bits, src1p->bits, src2p->bits, nbits);
+}
+
+#define nodes_xor(dst, src1, src2) \
+                       __nodes_xor(&(dst), &(src1), &(src2), MAX_NUMNODES)
+static inline void __nodes_xor(nodemask_t *dstp, const nodemask_t *src1p,
+                                       const nodemask_t *src2p, int nbits)
+{
+       bitmap_xor(dstp->bits, src1p->bits, src2p->bits, nbits);
+}
+
+#define nodes_andnot(dst, src1, src2) \
+                       __nodes_andnot(&(dst), &(src1), &(src2), MAX_NUMNODES)
+static inline void __nodes_andnot(nodemask_t *dstp, const nodemask_t *src1p,
+                                       const nodemask_t *src2p, int nbits)
+{
+       bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
+}
+
+#define nodes_complement(dst, src) \
+                       __nodes_complement(&(dst), &(src), MAX_NUMNODES)
+static inline void __nodes_complement(nodemask_t *dstp,
+                                       const nodemask_t *srcp, int nbits)
+{
+       bitmap_complement(dstp->bits, srcp->bits, nbits);
+}
+
+#define nodes_equal(src1, src2) \
+                       __nodes_equal(&(src1), &(src2), MAX_NUMNODES)
+static inline int __nodes_equal(const nodemask_t *src1p,
+                                       const nodemask_t *src2p, int nbits)
+{
+       return bitmap_equal(src1p->bits, src2p->bits, nbits);
+}
+
+#define nodes_intersects(src1, src2) \
+                       __nodes_intersects(&(src1), &(src2), MAX_NUMNODES)
+static inline int __nodes_intersects(const nodemask_t *src1p,
+                                       const nodemask_t *src2p, int nbits)
+{
+       return bitmap_intersects(src1p->bits, src2p->bits, nbits);
+}
+
+#define nodes_subset(src1, src2) \
+                       __nodes_subset(&(src1), &(src2), MAX_NUMNODES)
+static inline int __nodes_subset(const nodemask_t *src1p,
+                                       const nodemask_t *src2p, int nbits)
+{
+       return bitmap_subset(src1p->bits, src2p->bits, nbits);
+}
+
+#define nodes_empty(src) __nodes_empty(&(src), MAX_NUMNODES)
+static inline int __nodes_empty(const nodemask_t *srcp, int nbits)
+{
+       return bitmap_empty(srcp->bits, nbits);
+}
+
+#define nodes_full(nodemask) __nodes_full(&(nodemask), MAX_NUMNODES)
+static inline int __nodes_full(const nodemask_t *srcp, int nbits)
+{
+       return bitmap_full(srcp->bits, nbits);
+}
+
+#define nodes_weight(nodemask) __nodes_weight(&(nodemask), MAX_NUMNODES)
+static inline int __nodes_weight(const nodemask_t *srcp, int nbits)
+{
+       return bitmap_weight(srcp->bits, nbits);
+}
+
+#define nodes_shift_right(dst, src, n) \
+                       __nodes_shift_right(&(dst), &(src), (n), MAX_NUMNODES)
+static inline void __nodes_shift_right(nodemask_t *dstp,
+                                       const nodemask_t *srcp, int n, int 
nbits)
+{
+       bitmap_shift_right(dstp->bits, srcp->bits, n, nbits);
+}
+
+#define nodes_shift_left(dst, src, n) \
+                       __nodes_shift_left(&(dst), &(src), (n), MAX_NUMNODES)
+static inline void __nodes_shift_left(nodemask_t *dstp,
+                                       const nodemask_t *srcp, int n, int 
nbits)
+{
+       bitmap_shift_left(dstp->bits, srcp->bits, n, nbits);
+}
+
+/* FIXME: better would be to fix all architectures to never return
+          > MAX_NUMNODES, then the silly min_ts could be dropped. */
+
+#define first_node(src) __first_node(&(src))
+static inline int __first_node(const nodemask_t *srcp)
+{
+       return min_t(int, MAX_NUMNODES, find_first_bit(srcp->bits, 
MAX_NUMNODES));
+}
+
+#define next_node(n, src) __next_node((n), &(src))
+static inline int __next_node(int n, const nodemask_t *srcp)
+{
+       return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, 
n+1));
+}
+
+#define nodemask_of_node(node)                                         \
+({                                                                     \
+       typeof(_unused_nodemask_arg_) m;                                \
+       if (sizeof(m) == sizeof(unsigned long)) {                       \
+               m.bits[0] = 1UL<<(node);                                \
+       } else {                                                        \
+               nodes_clear(m);                                         \
+               node_set((node), m);                                    \
+       }                                                               \
+       m;                                                              \
+})
+
+#define first_unset_node(mask) __first_unset_node(&(mask))
+static inline int __first_unset_node(const nodemask_t *maskp)
+{
+       return min_t(int,MAX_NUMNODES,
+                       find_first_zero_bit(maskp->bits, MAX_NUMNODES));
+}
+
+#define NODE_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(MAX_NUMNODES)
+
+#if MAX_NUMNODES <= BITS_PER_LONG
+
+#define NODE_MASK_ALL                                                  \
+((nodemask_t) { {                                                      \
+       [BITS_TO_LONGS(MAX_NUMNODES)-1] = NODE_MASK_LAST_WORD           \
+} })
+
+#else
+
+#define NODE_MASK_ALL                                                  \
+((nodemask_t) { {                                                      \
+       [0 ... BITS_TO_LONGS(MAX_NUMNODES)-2] = ~0UL,                   \
+       [BITS_TO_LONGS(MAX_NUMNODES)-1] = NODE_MASK_LAST_WORD           \
+} })
+
+#endif
+
+#define NODE_MASK_NONE                                                 \
+((nodemask_t) { {                                                      \
+       [0 ... BITS_TO_LONGS(MAX_NUMNODES)-1] =  0UL                    \
+} })
+
+#define nodes_addr(src) ((src).bits)
+
+#if 0
+#define nodemask_scnprintf(buf, len, src) \
+                       __nodemask_scnprintf((buf), (len), &(src), MAX_NUMNODES)
+static inline int __nodemask_scnprintf(char *buf, int len,
+                                       const nodemask_t *srcp, int nbits)
+{
+       return bitmap_scnprintf(buf, len, srcp->bits, nbits);
+}
+
+#define nodemask_parse(ubuf, ulen, dst) \
+                       __nodemask_parse((ubuf), (ulen), &(dst), MAX_NUMNODES)
+static inline int __nodemask_parse(const char __user *buf, int len,
+                                       nodemask_t *dstp, int nbits)
+{
+       return bitmap_parse(buf, len, dstp->bits, nbits);
+}
+#endif
+
+#if MAX_NUMNODES > 1
+#define for_each_node_mask(node, mask)                 \
+       for ((node) = first_node(mask);                 \
+               (node) < MAX_NUMNODES;                  \
+               (node) = next_node((node), (mask)))
+#else /* MAX_NUMNODES == 1 */
+#define for_each_node_mask(node, mask)                 \
+       if (!nodes_empty(mask))                         \
+               for ((node) = 0; (node) < 1; (node)++)
+#endif /* MAX_NUMNODES */
+
+/*
+ * The following particular system nodemasks and operations
+ * on them manage all possible and online nodes.
+ */
+
+extern nodemask_t node_online_map;
+extern nodemask_t node_possible_map;
+
+#if MAX_NUMNODES > 1
+#define num_online_nodes()     nodes_weight(node_online_map)
+#define num_possible_nodes()   nodes_weight(node_possible_map)
+#define node_online(node)      node_isset((node), node_online_map)
+#define node_possible(node)    node_isset((node), node_possible_map)
+#else
+#define num_online_nodes()     1
+#define num_possible_nodes()   1
+#define node_online(node)      ((node) == 0)
+#define node_possible(node)    ((node) == 0)
+#endif
+
+#define any_online_node(mask)                  \
+({                                             \
+       int node;                               \
+       for_each_node_mask(node, (mask))        \
+               if (node_online(node))          \
+                       break;                  \
+       node;                                   \
+})
+
+#define node_set_online(node)     set_bit((node), node_online_map.bits)
+#define node_set_offline(node)    clear_bit((node), node_online_map.bits)
+
+#define for_each_node(node)       for_each_node_mask((node), node_possible_map)
+#define for_each_online_node(node) for_each_node_mask((node), node_online_map)
+
+#endif /* __LINUX_NODEMASK_H */
diff -r d246b79986d1 -r 3e26719ab827 xen/include/xen/numa.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xen/numa.h    Wed Oct 25 12:12:01 2006 -0600
@@ -0,0 +1,13 @@
+#ifndef _XEN_NUMA_H
+#define _XEN_NUMA_H
+
+#include <xen/config.h>
+#include <asm/numa.h>
+
+#ifndef NODES_SHIFT
+#define NODES_SHIFT     0
+#endif
+
+#define MAX_NUMNODES    (1 << NODES_SHIFT)
+
+#endif /* _XEN_NUMA_H */
diff -r d246b79986d1 -r 3e26719ab827 xen/include/asm-x86/hvm/vpit.h
--- a/xen/include/asm-x86/hvm/vpit.h    Tue Oct 24 11:21:48 2006 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * vpit.h: Virtual PIT definitions
- *
- * Copyright (c) 2004, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef __ASM_X86_HVM_VPIT_H__
-#define __ASM_X86_HVM_VPIT_H__
-
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/lib.h>
-#include <xen/time.h>
-#include <xen/errno.h>
-#include <xen/time.h>
-#include <xen/timer.h>
-#include <asm/hvm/vpic.h>
-
-#define PIT_FREQ 1193181
-#define PIT_BASE 0x40
-
-typedef struct PITChannelState {
-    int count; /* can be 65536 */
-    u16 latched_count;
-    u8 count_latched;
-    u8 status_latched;
-    u8 status;
-    u8 read_state;
-    u8 write_state;
-    u8 write_latch;
-    u8 rw_mode;
-    u8 mode;
-    u8 bcd; /* not supported */
-    u8 gate; /* timer start */
-    s64 count_load_time;
-    /* irq handling */
-    struct vcpu      *vcpu;
-    struct periodic_time *pt;
-} PITChannelState;
-
-typedef struct PITState {
-    PITChannelState channels[3];
-    int speaker_data_on;
-    int dummy_refresh_clock;
-} PITState;
-
-#define RTC_SIZE 14
-typedef struct RTCState {
-    uint8_t cmos_data[RTC_SIZE];  /* Only handle time/interrupt part in HV */
-    uint8_t cmos_index;
-    struct tm current_tm;
-    int irq;
-    /* second update */
-    int64_t next_second_time;
-    struct timer second_timer;
-    struct timer second_timer2;
-    struct vcpu      *vcpu;
-    struct periodic_time *pt;
-} RTCState;
-   
-/*
- * Abstract layer of periodic time, one short time.
- */
-typedef void time_cb(struct vcpu *v, void *opaque);
-
-struct periodic_time {
-    char enabled;               /* enabled */
-    char one_shot;              /* one shot time */
-    char irq;
-    char first_injected;        /* flag to prevent shadow window */
-    u32 pending_intr_nr;        /* the couner for pending timer interrupts */
-    u32 period;                 /* frequency in ns */
-    u64 period_cycles;          /* frequency in cpu cycles */
-    s_time_t scheduled;         /* scheduled timer interrupt */
-    u64 last_plt_gtime;         /* platform time when last IRQ is injected */
-    struct timer timer;         /* ac_timer */
-    time_cb *cb;
-    void *priv;                 /* ponit back to platform time source */
-};
-
-struct pl_time {    /* platform time */
-    struct periodic_time periodic_tm;
-    struct PITState      vpit;
-    struct RTCState      vrtc;
-    /* TODO: ACPI time */
-};
-
-static __inline__ s_time_t get_scheduled(
-    struct vcpu *v, int irq,
-    struct periodic_time *pt)
-{
-    if ( is_irq_enabled(v, irq) ) {
-        return pt->scheduled;
-    }
-    else
-        return -1;
-}
-
-extern u64 hvm_get_guest_time(struct vcpu *v);
-/*
- * get processor time.
- * unit: TSC
- */
-static __inline__ int64_t hvm_get_clock(struct vcpu *v)
-{
-    uint64_t  gtsc;
-
-    gtsc = hvm_get_guest_time(v);
-    return gtsc;
-}
-
-#define ticks_per_sec(v)      (v->domain->arch.hvm_domain.tsc_frequency)
-
-/* to hook the ioreq packet to get the PIT initialization info */
-extern void hvm_hooks_assist(struct vcpu *v);
-extern void pickup_deactive_ticks(struct periodic_time *vpit);
-extern struct periodic_time *create_periodic_time(u32 period, char irq, char 
one_shot, time_cb *cb, void *data);
-extern void destroy_periodic_time(struct periodic_time *pt);
-void pit_init(struct vcpu *v, unsigned long cpu_khz);
-void rtc_init(struct vcpu *v, int base, int irq);
-void rtc_deinit(struct domain *d);
-int is_rtc_periodic_irq(void *opaque);
-void pt_timer_fn(void *data);
-void pit_time_fired(struct vcpu *v, void *priv);
-
-#endif /* __ASM_X86_HVM_VPIT_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog