[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.