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

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



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID d75a6cc5e68abe8541c326afa2a614bf1973c609
# Parent  7e3cbc40967620fb6b89eff6d931269d21416546
# Parent  4109c4e7804abeabe3b222673f2ba4dd1375be53
merge with xen-unstable.hg

diff -r 7e3cbc409676 -r d75a6cc5e68a .hgtags
--- a/.hgtags   Mon Mar 27 15:36:47 2006 -0700
+++ b/.hgtags   Tue Mar 28 08:54:58 2006 -0700
@@ -13,3 +13,4 @@ 30c521db4c71960b0cf1d9c9e1b658e77b535a3e
 30c521db4c71960b0cf1d9c9e1b658e77b535a3e split-1.0
 3d330e41f41ce1bc118c02346e18949ad5d67f6b split-1.1
 c8fdb0caa77b429cf47f9707926e83947778cb48 RELEASE-3.0.0
+af0573e9e5258db0a9d28aa954dd302ddd2c2d23 3.0.2-rc
diff -r 7e3cbc409676 -r d75a6cc5e68a Makefile
--- a/Makefile  Mon Mar 27 15:36:47 2006 -0700
+++ b/Makefile  Tue Mar 28 08:54:58 2006 -0700
@@ -2,7 +2,7 @@
 # Grand Unified Makefile for Xen.
 #
 
-KERNELS ?= linux-2.6-xen0 linux-2.6-xenU
+KERNELS ?= linux-2.6-xen
 # You may use wildcards in the above e.g. KERNELS=*2.6*
 
 XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst 
buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) )
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Mon Mar 27 15:36:47 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Tue Mar 28 08:54:58 2006 -0700
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen0
-# Thu Feb 16 13:20:46 2006
+# Linux kernel version: 2.6.16-xen0
+# Mon Mar 27 14:46:03 2006
 #
 
 #
@@ -95,8 +95,7 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_BLKDEV_GRANT=y
 CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_VT=y
-CONFIG_VT=y
+CONFIG_XEN_BLKDEV_BACKEND=y
 CONFIG_XEN_SYSFS=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_IS_DMA32=y
@@ -378,7 +377,7 @@ CONFIG_BLK_DEV_IDESCSI=y
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
@@ -706,6 +705,7 @@ CONFIG_GAMEPORT=y
 #
 # Character devices
 #
+CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_NONSTANDARD=y
@@ -1252,11 +1252,7 @@ CONFIG_USB_MON=y
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64    Mon Mar 27 15:36:47 2006 -0700
+++ b/buildconfigs/linux-defconfig_xenU_ia64    Tue Mar 28 08:54:58 2006 -0700
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xenU
-# Thu Feb 16 13:47:59 2006
+# Linux kernel version: 2.6.16-xenU
+# Mon Mar 27 14:01:13 2006
 #
 
 #
@@ -92,8 +92,7 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_BLKDEV_GRANT=y
 CONFIG_XEN_BLKDEV_FRONTEND=y
-# CONFIG_XEN_VT is not set
-# CONFIG_VT is not set
+CONFIG_XEN_BLKDEV_BACKEND=y
 CONFIG_XEN_SYSFS=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_IS_DMA32=y
@@ -607,6 +606,9 @@ CONFIG_SERIO=y
 #
 # Character devices
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -863,6 +865,13 @@ CONFIG_FB_RADEON_DEBUG=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
 
 #
 # Logo configuration
@@ -1122,11 +1131,7 @@ CONFIG_USB_MON=y
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Mon Mar 27 15:36:47 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Tue Mar 28 08:54:58 2006 -0700
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen
-# Mon Feb 20 11:37:11 2006
+# Linux kernel version: 2.6.16-xen
+# Mon Mar 27 09:43:44 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -102,6 +102,8 @@ CONFIG_X86_PC=y
 # CONFIG_MPSC is not set
 CONFIG_GENERIC_CPU=y
 CONFIG_X86_64_XEN=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
 CONFIG_X86_L1_CACHE_BYTES=128
 CONFIG_X86_L1_CACHE_SHIFT=7
 CONFIG_X86_GOOD_APIC=y
@@ -1138,7 +1140,7 @@ CONFIG_AMD8111E_NAPI=y
 CONFIG_AMD8111E_NAPI=y
 CONFIG_ADAPTEC_STARFIRE=m
 CONFIG_ADAPTEC_STARFIRE_NAPI=y
-CONFIG_B44=m
+# CONFIG_B44 is not set
 CONFIG_FORCEDETH=m
 CONFIG_DGRS=m
 CONFIG_EEPRO100=m
@@ -1782,8 +1784,8 @@ CONFIG_VIDEO_HEXIUM_ORION=m
 CONFIG_VIDEO_HEXIUM_ORION=m
 CONFIG_VIDEO_HEXIUM_GEMINI=m
 CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
 CONFIG_VIDEO_CX88_DVB=m
-CONFIG_VIDEO_CX88_ALSA=m
 CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
 CONFIG_VIDEO_CX88_VP3054=m
 CONFIG_VIDEO_EM28XX=m
@@ -2331,11 +2333,7 @@ CONFIG_INFINIBAND_SRP=m
 CONFIG_INFINIBAND_SRP=m
 
 #
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 CONFIG_EDAC=m
 
diff -r 7e3cbc409676 -r d75a6cc5e68a docs/src/user.tex
--- a/docs/src/user.tex Mon Mar 27 15:36:47 2006 -0700
+++ b/docs/src/user.tex Tue Mar 28 08:54:58 2006 -0700
@@ -51,6 +51,40 @@ are licensed under the terms of the GNU 
 are licensed under the terms of the GNU Lesser General Public License, the
 Zope Public License 2.0, or under ``BSD-style'' licenses.  Please refer to the
 COPYING file for details.
+
+Xen includes software by Christopher Clark.  This software is covered by the
+following licence:
+
+\begin{quote}
+Copyright (c) 2002, Christopher Clark.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+\begin{itemize}
+\item Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+\item Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+\item Neither the name of the original author; nor the names of any
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+\end{itemize}
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\end{quote}
 
 \cleardoublepage
 
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/Makefile
--- a/extras/mini-os/Makefile   Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/Makefile   Tue Mar 28 08:54:58 2006 -0700
@@ -41,8 +41,7 @@ default: $(TARGET)
 
 links:
        [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
-       [ -e xenbus/xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h 
xenbus/xenstored.h
-       
+
 $(TARGET): links $(OBJS)
        $(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
        gzip -f -9 -c $@.elf >$@.gz
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/console/console.c
--- a/extras/mini-os/console/console.c  Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/console/console.c  Tue Mar 28 08:54:58 2006 -0700
@@ -116,12 +116,12 @@ void print(int direct, const char *fmt, 
     {
         (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
         return;
+    } else {
+        if(!console_initialised)
+            (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
+        
+        console_print(buf, strlen(buf));
     }
-    
-    if(!console_initialised)
-        (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
-        
-    console_print(buf, strlen(buf));
 }
 
 void printk(const char *fmt, ...)
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c     Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/console/xencons_ring.c     Tue Mar 28 08:54:58 2006 -0700
@@ -10,7 +10,6 @@
 
 
 /* TODO - need to define BUG_ON for whole mini-os, need crash-dump as well */
-extern void do_exit(void);
 #define BUG_ON(_cond)   do{if(_cond) do_exit();} while(0);
 
 static inline struct xencons_interface *xencons_interface(void)
@@ -29,7 +28,6 @@ int xencons_ring_send_no_notify(const ch
     int sent = 0;
        struct xencons_interface *intf = xencons_interface();
        XENCONS_RING_IDX cons, prod;
-
        cons = intf->out_cons;
        prod = intf->out_prod;
        mb();
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/events.c
--- a/extras/mini-os/events.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/events.c   Tue Mar 28 08:54:58 2006 -0700
@@ -74,9 +74,9 @@ int bind_evtchn( u32 port, void (*handle
 
 void unbind_evtchn( u32 port )
 {
-       if (ev_actions[port].handler)
+       if (ev_actions[port].handler == default_handler)
                printk("WARN: No handler for port %d when unbinding\n", port);
-       ev_actions[port].handler = NULL;
+       ev_actions[port].handler = default_handler;
        ev_actions[port].status |= EVS_DISABLED;
 }
 
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/os.h
--- a/extras/mini-os/include/os.h       Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/include/os.h       Tue Mar 28 08:54:58 2006 -0700
@@ -9,6 +9,7 @@
 
 #define NULL 0
 
+
 #if __GNUC__ == 2 && __GNUC_MINOR__ < 96
 #define __builtin_expect(x, expected_value) (x)
 #endif
@@ -20,6 +21,10 @@
 #ifndef __ASSEMBLY__
 #include <types.h>
 #include <hypervisor.h>
+
+extern void do_exit(void);
+#define BUG do_exit
+
 #endif
 #include <xen/xen.h>
 
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/wait.h
--- a/extras/mini-os/include/wait.h     Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/include/wait.h     Tue Mar 28 08:54:58 2006 -0700
@@ -66,6 +66,14 @@ static inline void wake_up(struct wait_q
     }
 }
 
+#define add_waiter(w, wq) do {  \
+    unsigned long flags;        \
+    local_irq_save(flags);      \
+    add_wait_queue(&wq, &w);    \
+    block(current);             \
+    local_irq_restore(flags);   \
+} while (0)
+
 #define wait_event(wq, condition) do{             \
     unsigned long flags;                          \
     if(condition)                                 \
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/xenbus.h
--- a/extras/mini-os/include/xenbus.h   Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/include/xenbus.h   Tue Mar 28 08:54:58 2006 -0700
@@ -1,224 +1,6 @@
-/******************************************************************************
- * xenbus.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 file may be 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_H__
+#define XENBUS_H__
 
-#ifndef _ASM_XEN_XENBUS_H
-#define _ASM_XEN_XENBUS_H
+void init_xenbus(void);
 
-#include <errno.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/xs_wire.h>
-
-/* Register callback to watch this node. */
-struct xenbus_watch
-{
-       struct list_head list;
-
-       /* Path being watched. */
-       const char *node;
-
-       /* Callback (executed in a process context with no locks held). */
-       void (*callback)(struct xenbus_watch *,
-                        const char **vec, unsigned int len);
-};
-
-
-/* A xenbus device. */
-struct xenbus_device {
-       const char *devicetype;
-       const char *nodename;
-       const char *otherend;
-       int otherend_id;
-       struct xenbus_watch otherend_watch;
-       int has_error;
-       void *data;
-};
-
-struct xenbus_device_id
-{
-       /* .../device/<device_type>/<identifier> */
-       char devicetype[32];    /* General class of device. */
-};
-
-/* A xenbus driver. */
-struct xenbus_driver {
-       char *name;
-       struct module *owner;
-       const struct xenbus_device_id *ids;
-       int (*probe)(struct xenbus_device *dev,
-                    const struct xenbus_device_id *id);
-       void (*otherend_changed)(struct xenbus_device *dev,
-                                XenbusState backend_state);
-       int (*remove)(struct xenbus_device *dev);
-       int (*suspend)(struct xenbus_device *dev);
-       int (*resume)(struct xenbus_device *dev);
-       int (*hotplug)(struct xenbus_device *, char **, int, char *, int);
-       int (*read_otherend_details)(struct xenbus_device *dev);
-};
-
-int xenbus_register_frontend(struct xenbus_driver *drv);
-int xenbus_register_backend(struct xenbus_driver *drv);
-void xenbus_unregister_driver(struct xenbus_driver *drv);
-
-struct xenbus_transaction;
-
-char **xenbus_directory(struct xenbus_transaction *t,
-                       const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(struct xenbus_transaction *t,
-                 const char *dir, const char *node, unsigned int *len);
-int xenbus_write(struct xenbus_transaction *t,
-                const char *dir, const char *node, const char *string);
-int xenbus_mkdir(struct xenbus_transaction *t,
-                const char *dir, const char *node);
-int xenbus_exists(struct xenbus_transaction *t,
-                 const char *dir, const char *node);
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
-struct xenbus_transaction *xenbus_transaction_start(void);
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
-
-/* Single read and scanf: returns -errno or num scanned if > 0. */
-int xenbus_scanf(struct xenbus_transaction *t,
-                const char *dir, const char *node, const char *fmt, ...)
-       __attribute__((format(scanf, 4, 5)));
-
-/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
-                 const char *dir, const char *node, const char *fmt, ...)
-       __attribute__((format(printf, 4, 5)));
-
-/* Generic read function: NULL-terminated triples of name,
- * sprintf-style type string, and pointer. Returns 0 or errno.*/
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
-
-int register_xenbus_watch(struct xenbus_watch *watch);
-void unregister_xenbus_watch(struct xenbus_watch *watch);
-void xs_suspend(void);
-void xs_resume(void);
-
-/* Used by xenbus_dev to borrow kernel's store connection. */
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
-
-/* Called from xen core code. */
-void xenbus_suspend(void);
-void xenbus_resume(void);
-
-#define XENBUS_IS_ERR_READ(str) ({                     \
-       if (!IS_ERR(str) && strlen(str) == 0) {         \
-               kfree(str);                             \
-               str = ERR_PTR(-ERANGE);                 \
-       }                                               \
-       IS_ERR(str);                                    \
-})
-
-#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
-
-
-/**
- * Register a watch on the given path, using the given xenbus_watch structure
- * for storage, and the given callback function as the callback.  Return 0 on
- * success, or -errno on error.  On success, the given path will be saved as
- * watch->node, and remains the caller's to free.  On error, watch->node will
- * be NULL, the device will switch to XenbusStateClosing, and the error will
- * be saved in the store.
- */
-int xenbus_watch_path(struct xenbus_device *dev, const char *path,
-                     struct xenbus_watch *watch, 
-                     void (*callback)(struct xenbus_watch *,
-                                      const char **, unsigned int));
-
-
-/**
- * Register a watch on the given path/path2, using the given xenbus_watch
- * structure for storage, and the given callback function as the callback.
- * Return 0 on success, or -errno on error.  On success, the watched path
- * (path/path2) will be saved as watch->node, and becomes the caller's to
- * kfree().  On error, watch->node will be NULL, so the caller has nothing to
- * free, the device will switch to XenbusStateClosing, and the error will be
- * saved in the store.
- */
-int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
-                      const char *path2, struct xenbus_watch *watch, 
-                      void (*callback)(struct xenbus_watch *,
-                                       const char **, unsigned int));
-
-
-/**
- * Advertise in the store a change of the given driver to the given new_state.
- * Perform the change inside the given transaction xbt.  xbt may be NULL, in
- * which case this is performed inside its own transaction.  Return 0 on
- * success, or -errno on error.  On error, the device will switch to
- * XenbusStateClosing, and the error will be saved in the store.
- */
-int xenbus_switch_state(struct xenbus_device *dev,
-                       struct xenbus_transaction *xbt,
-                       XenbusState new_state);
-
-
-/**
- * Grant access to the given ring_mfn to the peer of the given device.  Return
- * 0 on success, or -errno on error.  On error, the device will switch to
- * XenbusStateClosing, and the error will be saved in the store.
- */
-int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
-
-
-/**
- * Allocate an event channel for the given xenbus_device, assigning the newly
- * created local port to *port.  Return 0 on success, or -errno on error.  On
- * error, the device will switch to XenbusStateClosing, and the error will be
- * saved in the store.
- */
-int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
-
-
-/**
- * Return the state of the driver rooted at the given store path, or
- * XenbusStateClosed if no state can be read.
- */
-XenbusState xenbus_read_driver_state(const char *path);
-
-
-/***
- * Report the given negative errno into the store, along with the given
- * formatted message.
- */
-void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
-                     ...);
-
-
-/***
- * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
- * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
- * closedown of this driver and its peer.
- */
-void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
-                     ...);
-
-
-#endif /* _ASM_XEN_XENBUS_H */
+#endif /* XENBUS_H__ */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/kernel.c   Tue Mar 28 08:54:58 2006 -0700
@@ -35,7 +35,6 @@
 #include <lib.h>
 #include <sched.h>
 #include <xenbus.h>
-#include "xenbus/xenbus_comms.h"
 
 /*
  * Shared page for communicating with the hypervisor.
@@ -76,7 +75,15 @@ static shared_info_t *map_shared_info(un
 }
 
 
-extern void init_console(void);
+void test_xenbus(void);
+
+/* Do initialisation from a thread once the scheduler's available */
+static void init_xs(void *ign)
+{
+    init_xenbus();
+
+    test_xenbus();
+}
 
 /*
  * INITIAL C ENTRY POINT.
@@ -84,11 +91,13 @@ void start_kernel(start_info_t *si)
 void start_kernel(start_info_t *si)
 {
     static char hello[] = "Bootstrapping...\n";
+
     (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
 
     /* Copy the start_info struct to a globally-accessible area. */
+    /* WARN: don't do printk before here, it uses information from
+       shared_info. Use xprintk instead. */
     memcpy(&start_info, si, sizeof(*si));
-
     /* Grab the shared_info pointer and put it in a safe place. */
     HYPERVISOR_shared_info = map_shared_info(start_info.shared_info);
 
@@ -120,28 +129,24 @@ void start_kernel(start_info_t *si)
            si->cmd_line ? (const char *)si->cmd_line : "NULL");
 
 
-    /*
-     * If used for porting another OS, start here to figure out your
-     * guest os entry point. Otherwise continue below...
-     */
-    /* init memory management */
+    /* Init memory management. */
     init_mm();
 
-    /* set up events */
+    /* Set up events. */
     init_events();
     
-    /* init time and timers */
+    /* Init time and timers. */
     init_time();
 
-    /* init the console driver */
+    /* Init the console driver. */
     init_console();
-
-    /* init scheduler */
+ 
+   /* Init scheduler. */
     init_sched();
-
-    /* init xenbus */
-    xs_init();
-   
+ 
+    /* Init XenBus from a separate thread */
+    create_thread("init_xs", init_xs, NULL);
+    
     /* Everything initialised, start idle thread */
     run_idle_thread();
 }
@@ -156,6 +161,6 @@ void start_kernel(start_info_t *si)
 
 void do_exit(void)
 {
-    printk("do_exit called!\n");
+    printk("Do_exit called!\n");
     for ( ;; ) HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
 }
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/minios-x86_32.lds
--- a/extras/mini-os/minios-x86_32.lds  Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/minios-x86_32.lds  Tue Mar 28 08:54:58 2006 -0700
@@ -21,15 +21,6 @@ SECTIONS
 
   _edata = .;                  /* End of data section */
 
-  . = ALIGN(8192);             /* init_task */
-  .data.init_task : { *(.data.init_task) }
-
-  . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
-
-  . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
   __bss_start = .;             /* BSS */
   .bss : {
        *(.bss)
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/mm.c
--- a/extras/mini-os/mm.c       Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/mm.c       Tue Mar 28 08:54:58 2006 -0700
@@ -51,7 +51,6 @@ unsigned long *phys_to_machine_mapping;
 unsigned long *phys_to_machine_mapping;
 extern char *stack;
 extern char _text, _etext, _edata, _end;
-extern void do_exit(void);
 extern void page_walk(unsigned long virt_addr);
 
 /*********************
@@ -373,7 +372,7 @@ void new_pt_frame(unsigned long *pt_pfn,
     unsigned long *tab = (unsigned long *)start_info.pt_base;
     unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); 
     unsigned long prot_e, prot_t, pincmd;
-    mmu_update_t mmu_updates[0];
+    mmu_update_t mmu_updates[1];
     struct mmuext_op pin_request;
     
     DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/sched.c
--- a/extras/mini-os/sched.c    Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/sched.c    Tue Mar 28 08:54:58 2006 -0700
@@ -64,6 +64,8 @@
 
 struct thread *idle_thread = NULL;
 LIST_HEAD(exited_threads);
+
+void idle_thread_fn(void *unused);
 
 void dump_stack(struct thread *thread)
 {
@@ -132,7 +134,7 @@ void schedule(void)
             xfree(thread);
         }
     }
-    next = idle_thread;    
+    next = idle_thread;   
     /* Thread list needs to be protected */
     list_for_each(iterator, &idle_thread->thread_list)
     {
@@ -203,8 +205,13 @@ struct thread* create_thread(char *name,
     set_runnable(thread);
     
     local_irq_save(flags);
-    if(idle_thread != NULL)
+    if(idle_thread != NULL) {
         list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
+    } else if(function != idle_thread_fn)
+    {
+        printk("BUG: Not allowed to create thread before initialising 
scheduler.\n");
+        BUG();
+    }
     local_irq_restore(flags);
 
     return thread;
@@ -282,19 +289,9 @@ void th_f2(void *data)
 
 void init_sched(void)
 {
-    printk("Initialising scheduler\n");
-       
+    printk("Initialising scheduler, idle_thread %p\n", idle_thread);
+
     idle_thread = create_thread("Idle", idle_thread_fn, NULL);
     INIT_LIST_HEAD(&idle_thread->thread_list);
-
-    
-/*    create_thread("1", th_f1, (void *)0x1234);    
-    create_thread("2", th_f1, (void *)0x1234);    
-    create_thread("3", th_f1, (void *)0x1234);    
-    create_thread("4", th_f1, (void *)0x1234);    
-    create_thread("5", th_f1, (void *)0x1234);    
-    create_thread("6", th_f1, (void *)0x1234);    
-    create_thread("second", th_f2, NULL);
-*/   
-}
-
+}
+
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/traps.c
--- a/extras/mini-os/traps.c    Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/traps.c    Tue Mar 28 08:54:58 2006 -0700
@@ -29,11 +29,18 @@ void machine_check(void);
 void machine_check(void);
 
 
-extern void do_exit(void);
-
 void dump_regs(struct pt_regs *regs)
 {
-    printk("FIXME: proper register dump (with the stack dump)\n");
+    printk("EIP: %x, EFLAGS %x.\n", regs->eip, regs->eflags);
+    printk("EBX: %08x ECX: %08x EDX: %08x\n",
+          regs->ebx, regs->ecx, regs->edx);
+    printk("ESI: %08x EDI: %08x EBP: %08x EAX: %08x\n",
+          regs->esi, regs->edi, regs->ebp, regs->eax);
+    printk("DS: %04x ES: %04x orig_eax: %08x, eip: %08x\n",
+          regs->xds, regs->xes, regs->orig_eax, regs->eip);
+    printk("CS: %04x EFLAGS: %08x esp: %08x ss: %04x\n",
+          regs->xcs, regs->eflags, regs->esp, regs->xss);
+
 }      
 
 
@@ -94,10 +101,14 @@ void page_walk(unsigned long virt_addres
 
 }
 
-void do_page_fault(struct pt_regs *regs, unsigned long error_code,
-                                                                               
     unsigned long addr)
-{
-    printk("Page fault at linear address %p\n", addr);
+#define read_cr2() \
+        (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
+
+void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+    unsigned long addr = read_cr2();
+    printk("Page fault at linear address %p, regs %p, code %lx\n", addr, regs,
+          error_code);
     dump_regs(regs);
 #ifdef __x86_64__
     /* FIXME: _PAGE_PSE */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S   Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/x86_32.S   Tue Mar 28 08:54:58 2006 -0700
@@ -30,10 +30,10 @@ hypercall_page:
 hypercall_page:
         .org 0x3000
 
-ES             = 0x20
-ORIG_EAX       = 0x24
-EIP            = 0x28
-CS             = 0x2C
+ES             = 0x1c
+ORIG_EAX       = 0x20
+EIP            = 0x24
+CS             = 0x28
 
 #define ENTRY(X) .globl X ; X :
 
@@ -94,32 +94,6 @@ do_exception:
        call *%edi
     addl $8,%esp
     
-/*    pushl %ds
-       pushl %eax
-       xorl %eax,%eax
-       pushl %ebp
-       pushl %edi
-       pushl %esi
-       pushl %edx
-       decl %eax                       # eax = -1
-       pushl %ecx
-       pushl %ebx
-       cld
-       movl %es,%ecx
-       movl ORIG_EAX(%esp), %esi       # get the error code
-       movl ES(%esp), %edi             # get the function address
-       movl %eax, ORIG_EAX(%esp)
-       movl %ecx, ES(%esp)
-       movl %esp,%edx
-       pushl %esi                      # push the error code
-       pushl %edx                      # push the pt_regs pointer
-       movl $(__KERNEL_DS),%edx
-       movl %edx,%ds
-       movl %edx,%es
-       call *%edi
-       addl $8,%esp  */
-
-        
 ret_from_exception:
         movb CS(%esp),%cl
        test $2,%cl          # slow return to ring 2 or 3
@@ -290,15 +264,16 @@ ENTRY(page_fault)
        pushl %ecx
        pushl %ebx
        cld
-       movl %es,%edi
-       movl ES(%esp), %ecx             /* get the faulting address */
-       movl ORIG_EAX(%esp), %edx       /* get the error code */
+       movl ORIG_EAX(%esp), %edi
        movl %eax, ORIG_EAX(%esp)
-       movl %edi, ES(%esp)
+       movl %es, %ecx
+       movl %ecx, ES(%esp)
        movl $(__KERNEL_DS),%eax
        movl %eax, %ds
        movl %eax, %es
-       movl %esp,%eax                  /* pt_regs pointer */
+       pushl %edi
+       movl %esp, %eax
+       pushl %eax
        call do_page_fault
        jmp ret_from_exception
 
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c    Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c    Tue Mar 28 
08:54:58 2006 -0700
@@ -33,8 +33,6 @@ static int disable_x86_serial_nr __devin
 static int disable_x86_serial_nr __devinitdata = 1;
 
 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
-
-extern void machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c);
 
 extern int disable_pse;
 
@@ -425,8 +423,6 @@ void __devinit identify_cpu(struct cpuin
                                c->x86_vendor, c->x86_model);
        }
 
-       machine_specific_modify_cpu_capabilities(c);
-
        /* Now the feature flags better reflect actual CPU features! */
 
        printk(KERN_DEBUG "CPU: After all inits, caps:");
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Tue Mar 28 08:54:58 
2006 -0700
@@ -462,7 +462,7 @@ ENTRY(irq_entries_start)
 ENTRY(irq_entries_start)
 .rept NR_IRQS
        ALIGN
-1:     pushl $vector-256
+1:     pushl 0x80000000+$vector
        jmp common_interrupt
 .data
        .long 1b
@@ -479,7 +479,7 @@ common_interrupt:
 
 #define BUILD_INTERRUPT(name, nr)      \
 ENTRY(name)                            \
-       pushl $nr-256;                  \
+       pushl 0x80000000+$nr;           \
        SAVE_ALL                        \
        movl %esp,%eax;                 \
        call smp_/**/name;              \
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Tue Mar 28 08:54:58 
2006 -0700
@@ -32,14 +32,14 @@ ENTRY(startup_32)
 
        /* get vendor info */
        xorl %eax,%eax                  # call CPUID with 0 -> return vendor ID
-       cpuid
+       XEN_CPUID
        movl %eax,X86_CPUID             # save CPUID level
        movl %ebx,X86_VENDOR_ID         # lo 4 chars
        movl %edx,X86_VENDOR_ID+4       # next 4 chars
        movl %ecx,X86_VENDOR_ID+8       # last 4 chars
 
        movl $1,%eax            # Use the CPUID instruction to get CPU type
-       cpuid
+       XEN_CPUID
        movb %al,%cl            # save reg for future use
        andb $0x0f,%ah          # mask processor family
        movb %ah,X86
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c   Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c   Tue Mar 28 08:54:58 
2006 -0700
@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
  */
 fastcall unsigned int do_IRQ(struct pt_regs *regs)
 {      
-       /* high bits used in ret_from_ code */
-       int irq = regs->orig_eax & __IRQ_MASK(HARDIRQ_BITS);
+       /* high bit used in ret_from_ code */
+       int irq = regs->orig_eax & __IRQ_MASK(BITS_PER_LONG - 1);
 #ifdef CONFIG_4KSTACKS
        union irq_ctx *curctx, *irqctx;
        u32 *isp;
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Tue Mar 28 08:54:58 
2006 -0700
@@ -32,13 +32,13 @@
 #endif
 
 static int direct_remap_area_pte_fn(pte_t *pte, 
-                                   struct page *pte_page,
+                                   struct page *pmd_page,
                                    unsigned long address, 
                                    void *data)
 {
        mmu_update_t **v = (mmu_update_t **)data;
 
-       (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pte_page)) <<
+       (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
                     PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
        (*v)++;
 
@@ -67,9 +67,9 @@ static int __direct_remap_pfn_range(stru
        for (i = 0; i < size; i += PAGE_SIZE) {
                if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
                        /* Fill in the PTE pointers. */
-                       rc = generic_page_range(mm, start_address, 
-                                               address - start_address,
-                                               direct_remap_area_pte_fn, &w);
+                       rc = apply_to_page_range(mm, start_address, 
+                                                address - start_address,
+                                                direct_remap_area_pte_fn, &w);
                        if (rc)
                                goto out;
                        w = u;
@@ -93,8 +93,9 @@ static int __direct_remap_pfn_range(stru
 
        if (v != u) {
                /* get the ptep's filled in */
-               rc = generic_page_range(mm, start_address, address - 
start_address,
-                                  direct_remap_area_pte_fn, &w);
+               rc = apply_to_page_range(mm, start_address,
+                                        address - start_address,
+                                        direct_remap_area_pte_fn, &w);
                if (rc)
                        goto out;
                rc = -EFAULT;
@@ -142,11 +143,11 @@ EXPORT_SYMBOL(direct_kernel_remap_pfn_ra
 EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
 
 static int lookup_pte_fn(
-       pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+       pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
        uint64_t *ptep = (uint64_t *)data;
        if (ptep)
-               *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pte_page)) <<
+               *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
                         PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
        return 0;
 }
@@ -155,13 +156,14 @@ int create_lookup_pte_addr(struct mm_str
                           unsigned long address,
                           uint64_t *ptep)
 {
-       return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep);
+       return apply_to_page_range(mm, address, PAGE_SIZE,
+                                  lookup_pte_fn, ptep);
 }
 
 EXPORT_SYMBOL(create_lookup_pte_addr);
 
 static int noop_fn(
-       pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+       pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
        return 0;
 }
@@ -170,7 +172,7 @@ int touch_pte_range(struct mm_struct *mm
                    unsigned long address,
                    unsigned long size)
 {
-       return generic_page_range(mm, address, size, noop_fn, NULL);
+       return apply_to_page_range(mm, address, size, noop_fn, NULL);
 } 
 
 EXPORT_SYMBOL(touch_pte_range);
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Tue Mar 28 08:54:58 2006 -0700
@@ -83,19 +83,6 @@ config XEN_BLKDEV_BACKEND
        depends on XEN
        bool
        default y
-
-config XEN_VT
-       bool "Override for turning on CONFIG_VT for domU"
-       default y
-       help
-         Hack to turn off CONFIG_VT for domU
-
-config VT
-       bool
-       default y if XEN && XEN_VT
-       default n if XEN && !XEN_VT
-       help
-         Hack to turn off CONFIG_VT for domU
 
 config XEN_SYSFS
        bool "Export Xen attributes in sysfs"
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Tue Mar 28 08:54:58 
2006 -0700
@@ -506,6 +506,22 @@ setup_arch (char **cmdline_p)
                        conswitchp = &vga_con;
 # endif
        }
+#ifdef CONFIG_XEN
+       if (running_on_xen) {
+               extern shared_info_t *HYPERVISOR_shared_info;
+
+               /* xen_start_info isn't setup yet, get the flags manually */
+               if (HYPERVISOR_shared_info->arch.flags & SIF_INITDOMAIN) {
+                       if (!(HYPERVISOR_shared_info->arch.flags & 
SIF_PRIVILEGED))
+                               panic("Xen granted us console access "
+                                     "but not privileged status");
+               } else {
+                       extern int console_use_vt;
+                       conswitchp = NULL;
+                       console_use_vt = 0;
+               }
+       }
+#endif
 #endif
 
        /* enable IA-64 Machine Check Abort Handling unless disabled */
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c        Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c        Tue Mar 28 
08:54:58 2006 -0700
@@ -113,8 +113,6 @@ void smp_apic_timer_interrupt(struct pt_
        smp_local_timer_interrupt(regs);
        irq_exit();
 }
-
-int __initdata unsync_tsc_on_multicluster;
 
 /*
  * This interrupt should _never_ happen with our APIC/SMP architecture
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Tue Mar 28 
08:54:58 2006 -0700
@@ -584,7 +584,7 @@ retint_kernel:
  */            
        .macro apicinterrupt num,func
        INTR_FRAME
-       pushq $\num-256
+       pushq 0x8000000000000000+$\num
        CFI_ADJUST_CFA_OFFSET 8
        interrupt \func
        jmp error_entry
@@ -855,32 +855,12 @@ ecrit:  /**** END OF CRITICAL REGION ***
 # i.e. it just resumes from the next instruction interrupted with the same 
context. 
        
 # Hypervisor uses this for application faults while it executes.
+# Unlike i386 there is no need to reload the saved segment selectors:
+# Xen already reloaded all valid ones and zeroed the others.
 ENTRY(failsafe_callback)
-       addq $0x10,%rsp /* skip rcx and r11 */  
-1:     mov  (%rsp),%ds
-2:     mov  8(%rsp),%es
-3:     mov  16(%rsp),%fs
-4:     mov  24(%rsp),%gs
-       addq $0x20,%rsp /* skip the above selectors */          
+       addq $0x30,%rsp /* skip %rcx,%r11,%ds,%es,%fs,%gs */
        SAVE_ALL
        jmp  error_exit
-.section .fixup,"ax";  \
-6:     movq $0,(%rsp); \
-       jmp 1b;         \
-7:     movq $0,8(%rsp);        \
-       jmp 2b;         \
-8:     movq $0,16(%rsp);       \
-       jmp 3b;         \
-9:     movq $0,24(%rsp);       \
-       jmp 4b;         \
-.previous;             \
-.section __ex_table,"a";\
-       .align 16;      \
-       .quad 1b,6b;    \
-       .quad 2b,7b;    \
-       .quad 3b,8b;    \
-       .quad 4b,9b;    \
-.previous
  
 #if 0        
         .section __ex_table,"a"
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c Tue Mar 28 08:54:58 
2006 -0700
@@ -96,8 +96,8 @@ skip:
  */
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
 {      
-       /* high bits used in ret_from_ code  */
-        int irq = regs->orig_rax & __IRQ_MASK(HARDIRQ_BITS);
+       /* high bit used in ret_from_ code  */
+        int irq = regs->orig_rax & __IRQ_MASK(BITS_PER_LONG - 1);
 
        exit_idle();
        irq_enter();
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Tue Mar 28 
08:54:58 2006 -0700
@@ -82,8 +82,6 @@ extern unsigned long start_pfn;
 extern unsigned long start_pfn;
 extern struct edid_info edid_info;
 
-extern void machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c);
-
 shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
 EXPORT_SYMBOL(HYPERVISOR_shared_info);
 
@@ -1433,8 +1431,6 @@ void __cpuinit identify_cpu(struct cpuin
        select_idle_routine(c);
        detect_ht(c); 
 
-       machine_specific_modify_cpu_capabilities(c);
-
        /*
         * On SMP, boot_cpu_data holds the common feature set between
         * all CPUs; so make sure that we indicate which features are
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Tue Mar 28 
08:54:58 2006 -0700
@@ -517,7 +517,7 @@ void balloon_update_driver_allowance(lon
 }
 
 static int dealloc_pte_fn(
-       pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+       pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
        unsigned long mfn = pte_mfn(*pte);
        int ret;
@@ -547,8 +547,8 @@ struct page *balloon_alloc_empty_page_ra
        scrub_pages(vstart, 1 << order);
 
        balloon_lock(flags);
-       ret = generic_page_range(
-               &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL);
+       ret = apply_to_page_range(&init_mm, vstart,
+                                 PAGE_SIZE << order, dealloc_pte_fn, NULL);
        BUG_ON(ret);
        current_pages -= 1UL << order;
        totalram_pages = current_pages;
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Tue Mar 28 08:54:58 
2006 -0700
@@ -58,17 +58,37 @@ static int evtchn_to_irq[NR_EVENT_CHANNE
 
 /* Packed IRQ information: binding type, sub-type index, and event channel. */
 static u32 irq_info[NR_IRQS];
+
 /* Binding types. */
 enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
+
 /* Constructor for packed IRQ information. */
-#define mk_irq_info(type, index, evtchn)                               \
-       (((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn))
+static inline u32 mk_irq_info(u32 type, u32 index, u32 evtchn)
+{
+       return ((type << 24) | (index << 16) | evtchn);
+}
+
 /* Convenient shorthand for packed representation of an unbound IRQ. */
 #define IRQ_UNBOUND    mk_irq_info(IRQT_UNBOUND, 0, 0)
-/* Accessor macros for packed IRQ information. */
-#define evtchn_from_irq(irq) ((u16)(irq_info[irq]))
-#define index_from_irq(irq)  ((u8)(irq_info[irq] >> 16))
-#define type_from_irq(irq)   ((u8)(irq_info[irq] >> 24))
+
+/*
+ * Accessors for packed IRQ information.
+ */
+
+static inline unsigned int evtchn_from_irq(int irq)
+{
+       return (u16)(irq_info[irq]);
+}
+
+static inline unsigned int index_from_irq(int irq)
+{
+       return (u8)(irq_info[irq] >> 16);
+}
+
+static inline unsigned int type_from_irq(int irq)
+{
+       return (u8)(irq_info[irq] >> 24);
+}
 
 /* IRQ <-> VIRQ mapping. */
 DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]);
@@ -90,10 +110,13 @@ static u8 cpu_evtchn[NR_EVENT_CHANNELS];
 static u8 cpu_evtchn[NR_EVENT_CHANNELS];
 static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG];
 
-#define active_evtchns(cpu,sh,idx)             \
-       ((sh)->evtchn_pending[idx] &            \
-        cpu_evtchn_mask[cpu][idx] &            \
-        ~(sh)->evtchn_mask[idx])
+static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh,
+                                          unsigned int idx)
+{
+       return (sh->evtchn_pending[idx] &
+               cpu_evtchn_mask[cpu][idx] &
+               ~sh->evtchn_mask[idx]);
+}
 
 static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
 {
@@ -109,16 +132,31 @@ static void init_evtchn_cpu_bindings(voi
        memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
 }
 
-#define cpu_from_evtchn(evtchn)                (cpu_evtchn[evtchn])
+static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
+{
+       return cpu_evtchn[evtchn];
+}
 
 #else
 
-#define active_evtchns(cpu,sh,idx)             \
-       ((sh)->evtchn_pending[idx] &            \
-        ~(sh)->evtchn_mask[idx])
-#define bind_evtchn_to_cpu(chn,cpu)    ((void)0)
-#define init_evtchn_cpu_bindings()     ((void)0)
-#define cpu_from_evtchn(evtchn)                (0)
+static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh,
+                                          unsigned int idx)
+{
+       return (sh->evtchn_pending[idx] & ~sh->evtchn_mask[idx]);
+}
+
+static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+{
+}
+
+static void init_evtchn_cpu_bindings(void)
+{
+}
+
+static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
+{
+       return 0;
+}
 
 #endif
 
@@ -132,9 +170,9 @@ static inline void exit_idle(void) {}
 #include <asm/idle.h>
 #define IRQ_REG orig_rax
 #endif
-#define do_IRQ(irq, regs) do {                 \
-       (regs)->IRQ_REG = (irq);                \
-       do_IRQ((regs));                         \
+#define do_IRQ(irq, regs) do {                                 \
+       (regs)->IRQ_REG = (irq) | (1UL << (BITS_PER_LONG - 1)); \
+       do_IRQ((regs));                                         \
 } while (0)
 #endif
 
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Tue Mar 28 08:54:58 
2006 -0700
@@ -360,7 +360,7 @@ gnttab_request_free_callback(struct gntt
 }
 
 #ifndef __ia64__
-static int map_pte_fn(pte_t *pte, struct page *pte_page,
+static int map_pte_fn(pte_t *pte, struct page *pmd_page,
                      unsigned long addr, void *data)
 {
        unsigned long **frames = (unsigned long **)data;
@@ -370,7 +370,7 @@ static int map_pte_fn(pte_t *pte, struct
        return 0;
 }
 
-static int unmap_pte_fn(pte_t *pte, struct page *pte_page,
+static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
                      unsigned long addr, void *data)
 {
 
@@ -384,6 +384,7 @@ gnttab_resume(void)
 {
        gnttab_setup_table_t setup;
        unsigned long frames[NR_GRANT_FRAMES];
+       int rc;
 #ifndef __ia64__
        void *pframes = frames;
        struct vm_struct *area;
@@ -393,8 +394,8 @@ gnttab_resume(void)
        setup.nr_frames  = NR_GRANT_FRAMES;
        setup.frame_list = frames;
 
-       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
-       BUG_ON(setup.status != 0);
+       rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+       BUG_ON(rc || setup.status);
 
 #ifndef __ia64__
        if (shared == NULL) {
@@ -402,9 +403,10 @@ gnttab_resume(void)
                BUG_ON(area == NULL);
                shared = area->addr;
        }
-       BUG_ON(generic_page_range(&init_mm, (unsigned long)shared,
-                                 PAGE_SIZE * NR_GRANT_FRAMES,
-                                 map_pte_fn, &pframes));
+       rc = apply_to_page_range(&init_mm, (unsigned long)shared,
+                                PAGE_SIZE * NR_GRANT_FRAMES,
+                                map_pte_fn, &pframes);
+       BUG_ON(rc);
 #else
        shared = __va(frames[0] << PAGE_SHIFT);
        printk("grant table at %p\n", shared);
@@ -418,9 +420,9 @@ gnttab_suspend(void)
 {
 
 #ifndef __ia64__
-       generic_page_range(&init_mm, (unsigned long)shared,
-                          PAGE_SIZE * NR_GRANT_FRAMES,
-                          unmap_pte_fn, NULL);
+       apply_to_page_range(&init_mm, (unsigned long)shared,
+                           PAGE_SIZE * NR_GRANT_FRAMES,
+                           unmap_pte_fn, NULL);
 #endif
 
        return 0;
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Tue Mar 28 08:54:58 
2006 -0700
@@ -25,9 +25,10 @@ EXPORT_SYMBOL(pm_power_off);
 EXPORT_SYMBOL(pm_power_off);
 #endif
 
+extern void ctrl_alt_del(void);
+
 #define SHUTDOWN_INVALID  -1
 #define SHUTDOWN_POWEROFF  0
-#define SHUTDOWN_REBOOT    1
 #define SHUTDOWN_SUSPEND   2
 /* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
  * report a crash, not be instructed to crash!
@@ -234,33 +235,19 @@ static int shutdown_process(void *__unus
 {
        static char *envp[] = { "HOME=/", "TERM=linux",
                                "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
-       static char *restart_argv[]  = { "/sbin/reboot", NULL };
        static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
 
        extern asmlinkage long sys_reboot(int magic1, int magic2,
                                          unsigned int cmd, void *arg);
 
-       daemonize("shutdown");
-
-       switch (shutting_down) {
-       case SHUTDOWN_POWEROFF:
-       case SHUTDOWN_HALT:
+       if ((shutting_down == SHUTDOWN_POWEROFF) ||
+           (shutting_down == SHUTDOWN_HALT)) {
                if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
                        sys_reboot(LINUX_REBOOT_MAGIC1,
                                   LINUX_REBOOT_MAGIC2,
                                   LINUX_REBOOT_CMD_POWER_OFF,
                                   NULL);
                }
-               break;
-
-       case SHUTDOWN_REBOOT:
-               if (execve("/sbin/reboot", restart_argv, envp) < 0) {
-                       sys_reboot(LINUX_REBOOT_MAGIC1,
-                                  LINUX_REBOOT_MAGIC2,
-                                  LINUX_REBOOT_CMD_RESTART,
-                                  NULL);
-               }
-               break;
        }
 
        shutting_down = SHUTDOWN_INVALID; /* could try again */
@@ -331,7 +318,7 @@ static void shutdown_handler(struct xenb
        if (strcmp(str, "poweroff") == 0)
                shutting_down = SHUTDOWN_POWEROFF;
        else if (strcmp(str, "reboot") == 0)
-               shutting_down = SHUTDOWN_REBOOT;
+               ctrl_alt_del();
        else if (strcmp(str, "suspend") == 0)
                shutting_down = SHUTDOWN_SUSPEND;
        else if (strcmp(str, "halt") == 0)
@@ -391,8 +378,6 @@ static struct xenbus_watch sysrq_watch =
 };
 #endif
 
-static struct notifier_block xenstore_notifier;
-
 static int setup_shutdown_watcher(struct notifier_block *notifier,
                                   unsigned long event,
                                   void *data)
@@ -420,11 +405,10 @@ static int setup_shutdown_watcher(struct
 
 static int __init setup_shutdown_event(void)
 {
-
-       xenstore_notifier.notifier_call = setup_shutdown_watcher;
-
+       static struct notifier_block xenstore_notifier = {
+               .notifier_call = setup_shutdown_watcher
+       };
        register_xenstore_notifier(&xenstore_notifier);
-
        return 0;
 }
 
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue Mar 28 
08:54:58 2006 -0700
@@ -331,7 +331,7 @@ static void net_rx_action(unsigned long 
                if (make_rx_response(netif, id, status,
                                     (unsigned long)skb->data & ~PAGE_MASK,
                                     size, skb->proto_csum_valid ?
-                                    NETRXF_csum_valid : 0) &&
+                                    NETRXF_data_validated : 0) &&
                    (rx_notify[irq] == 0)) {
                        rx_notify[irq] = 1;
                        notify_list[notify_nr++] = irq;
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Mar 28 
08:54:58 2006 -0700
@@ -68,18 +68,12 @@
 #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
 
-#define alloc_xen_skb(_l) __dev_alloc_skb((_l), GFP_ATOMIC|__GFP_NOWARN)
-
-#define init_skb_shinfo(_skb)                         \
-    do {                                              \
-        atomic_set(&(skb_shinfo(_skb)->dataref), 1);  \
-        skb_shinfo(_skb)->nr_frags = 0;               \
-        skb_shinfo(_skb)->frag_list = NULL;           \
-    } while (0)
-
-static unsigned long rx_pfn_array[NET_RX_RING_SIZE];
-static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
-static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
+static inline void init_skb_shinfo(struct sk_buff *skb)
+{
+       atomic_set(&(skb_shinfo(skb)->dataref), 1);
+       skb_shinfo(skb)->nr_frags = 0;
+       skb_shinfo(skb)->frag_list = NULL;
+}
 
 struct netfront_info
 {
@@ -134,16 +128,28 @@ struct netfront_info
        int tx_ring_ref;
        int rx_ring_ref;
        u8 mac[ETH_ALEN];
+
+       unsigned long rx_pfn_array[NET_RX_RING_SIZE];
+       multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
+       mmu_update_t rx_mmu[NET_RX_RING_SIZE];
 };
 
-/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
-#define ADD_ID_TO_FREELIST(_list, _id)                 \
-       (_list)[(_id)] = (_list)[0];                    \
-       (_list)[0]     = (void *)(unsigned long)(_id);
-#define GET_ID_FROM_FREELIST(_list)                            \
-       ({ unsigned long _id = (unsigned long)(_list)[0];       \
-          (_list)[0]  = (_list)[_id];                          \
-          (unsigned short)_id; })
+/*
+ * Access macros for acquiring freeing slots in {tx,rx}_skbs[].
+ */
+
+static inline void add_id_to_freelist(struct sk_buff **list, unsigned short id)
+{
+       list[id] = list[0];
+       list[0]  = (void *)(unsigned long)id;
+}
+
+static inline unsigned short get_id_from_freelist(struct sk_buff **list)
+{
+       unsigned int id = (unsigned int)(unsigned long)list[0];
+       list[0] = list[id];
+       return id;
+}
 
 #ifdef DEBUG
 static char *be_state_name[] = {
@@ -484,7 +490,7 @@ static void network_tx_buf_gc(struct net
                        gnttab_release_grant_reference(
                                &np->gref_tx_head, np->grant_tx_ref[id]);
                        np->grant_tx_ref[id] = GRANT_INVALID_REF;
-                       ADD_ID_TO_FREELIST(np->tx_skbs, id);
+                       add_id_to_freelist(np->tx_skbs, id);
                        dev_kfree_skb_irq(skb);
                }
 
@@ -545,9 +551,10 @@ static void network_alloc_rx_buffers(str
                 * Subtract dev_alloc_skb headroom (16 bytes) and shared info
                 * tailroom then round down to SKB_DATA_ALIGN boundary.
                 */
-               skb = alloc_xen_skb(
+               skb = __dev_alloc_skb(
                        ((PAGE_SIZE - sizeof(struct skb_shared_info)) &
-                        (-SKB_DATA_ALIGN(1))) - 16);
+                        (-SKB_DATA_ALIGN(1))) - 16,
+                       GFP_ATOMIC|__GFP_NOWARN);
                if (skb == NULL) {
                        /* Any skbuffs queued for refill? Force them out. */
                        if (i != 0)
@@ -576,7 +583,7 @@ static void network_alloc_rx_buffers(str
 
                skb->dev = dev;
 
-               id = GET_ID_FROM_FREELIST(np->rx_skbs);
+               id = get_id_from_freelist(np->rx_skbs);
 
                np->rx_skbs[id] = skb;
 
@@ -588,13 +595,13 @@ static void network_alloc_rx_buffers(str
                                                  np->xbdev->otherend_id,
                                                  __pa(skb->head) >> 
PAGE_SHIFT);
                RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
-               rx_pfn_array[i] = virt_to_mfn(skb->head);
+               np->rx_pfn_array[i] = virt_to_mfn(skb->head);
 
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Remove this page before passing back to Xen. */
                        set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
                                            INVALID_P2M_ENTRY);
-                       MULTI_update_va_mapping(rx_mcl+i,
+                       MULTI_update_va_mapping(np->rx_mcl+i,
                                                (unsigned long)skb->head,
                                                __pte(0), 0);
                }
@@ -603,7 +610,7 @@ static void network_alloc_rx_buffers(str
        /* Tell the ballon driver what is going on. */
        balloon_update_driver_allowance(i);
 
-       reservation.extent_start = rx_pfn_array;
+       reservation.extent_start = np->rx_pfn_array;
        reservation.nr_extents   = i;
        reservation.extent_order = 0;
        reservation.address_bits = 0;
@@ -611,19 +618,19 @@ static void network_alloc_rx_buffers(str
 
        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                /* After all PTEs have been zapped, flush the TLB. */
-               rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
+               np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
                        UVMF_TLB_FLUSH|UVMF_ALL;
 
                /* Give away a batch of pages. */
-               rx_mcl[i].op = __HYPERVISOR_memory_op;
-               rx_mcl[i].args[0] = XENMEM_decrease_reservation;
-               rx_mcl[i].args[1] = (unsigned long)&reservation;
+               np->rx_mcl[i].op = __HYPERVISOR_memory_op;
+               np->rx_mcl[i].args[0] = XENMEM_decrease_reservation;
+               np->rx_mcl[i].args[1] = (unsigned long)&reservation;
 
                /* Zap PTEs and give away pages in one big multicall. */
-               (void)HYPERVISOR_multicall(rx_mcl, i+1);
+               (void)HYPERVISOR_multicall(np->rx_mcl, i+1);
 
                /* Check return status of HYPERVISOR_memory_op(). */
-               if (unlikely(rx_mcl[i].result != i))
+               if (unlikely(np->rx_mcl[i].result != i))
                        panic("Unable to reduce memory reservation\n");
        } else
                if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
@@ -656,7 +663,8 @@ static int network_start_xmit(struct sk_
        if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
                     PAGE_SIZE)) {
                struct sk_buff *nskb;
-               if (unlikely((nskb = alloc_xen_skb(skb->len)) == NULL))
+               nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC|__GFP_NOWARN);
+               if (unlikely(nskb == NULL))
                        goto drop;
                skb_put(nskb, skb->len);
                memcpy(nskb->data, skb->data, skb->len);
@@ -674,7 +682,7 @@ static int network_start_xmit(struct sk_
 
        i = np->tx.req_prod_pvt;
 
-       id = GET_ID_FROM_FREELIST(np->tx_skbs);
+       id = get_id_from_freelist(np->tx_skbs);
        np->tx_skbs[id] = skb;
 
        tx = RING_GET_REQUEST(&np->tx, i);
@@ -739,8 +747,8 @@ static int netif_poll(struct net_device 
        struct sk_buff *skb, *nskb;
        netif_rx_response_t *rx;
        RING_IDX i, rp;
-       mmu_update_t *mmu = rx_mmu;
-       multicall_entry_t *mcl = rx_mcl;
+       mmu_update_t *mmu = np->rx_mmu;
+       multicall_entry_t *mcl = np->rx_mcl;
        int work_done, budget, more_to_do = 1;
        struct sk_buff_head rxq;
        unsigned long flags;
@@ -796,14 +804,14 @@ static int netif_poll(struct net_device 
                np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
 
                skb = np->rx_skbs[rx->id];
-               ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
+               add_id_to_freelist(np->rx_skbs, rx->id);
 
                /* NB. We handle skb overflow later. */
                skb->data = skb->head + rx->offset;
                skb->len  = rx->status;
                skb->tail = skb->data + skb->len;
 
-               if (rx->flags & NETRXF_csum_valid)
+               if (rx->flags & NETRXF_data_validated)
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
 
                np->stats.rx_packets++;
@@ -831,14 +839,14 @@ static int netif_poll(struct net_device 
        balloon_update_driver_allowance(-work_done);
 
        /* Do all the remapping work, and M2P updates, in one big hypercall. */
-       if (likely((mcl - rx_mcl) != 0)) {
+       if (likely((mcl - np->rx_mcl) != 0)) {
                mcl->op = __HYPERVISOR_mmu_update;
-               mcl->args[0] = (unsigned long)rx_mmu;
-               mcl->args[1] = mmu - rx_mmu;
+               mcl->args[0] = (unsigned long)np->rx_mmu;
+               mcl->args[1] = mmu - np->rx_mmu;
                mcl->args[2] = 0;
                mcl->args[3] = DOMID_SELF;
                mcl++;
-               (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
+               (void)HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
        }
 
        while ((skb = __skb_dequeue(&rxq)) != NULL) {
@@ -871,7 +879,8 @@ static int netif_poll(struct net_device 
                                               16 - (skb->data - skb->head));
                        }
 
-                       nskb = alloc_xen_skb(skb->len + 2);
+                       nskb = __dev_alloc_skb(skb->len + 2,
+                                              GFP_ATOMIC|__GFP_NOWARN);
                        if (nskb != NULL) {
                                skb_reserve(nskb, 2);
                                skb_put(nskb, skb->len);
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pciback/passthrough.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/passthrough.c    Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/passthrough.c    Tue Mar 28 
08:54:58 2006 -0700
@@ -7,10 +7,13 @@
 
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/spinlock.h>
 #include "pciback.h"
 
 struct passthrough_dev_data {
+       /* Access to dev_list must be protected by lock */
        struct list_head dev_list;
+       spinlock_t lock;
 };
 
 struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
@@ -19,31 +22,64 @@ struct pci_dev *pciback_get_pci_dev(stru
 {
        struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
        struct pci_dev_entry *dev_entry;
+       struct pci_dev *dev = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev_data->lock, flags);
 
        list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
                if (domain == (unsigned int)pci_domain_nr(dev_entry->dev->bus)
                    && bus == (unsigned int)dev_entry->dev->bus->number
-                   && devfn == dev_entry->dev->devfn)
-                       return dev_entry->dev;
+                   && devfn == dev_entry->dev->devfn) {
+                       dev = dev_entry->dev;
+                       break;
+               }
        }
 
-       return NULL;
+       spin_unlock_irqrestore(&dev_data->lock, flags);
+
+       return dev;
 }
 
-/* Must hold pciback_device->dev_lock when calling this */
 int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
 {
        struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
        struct pci_dev_entry *dev_entry;
+       unsigned long flags;
 
        dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
        if (!dev_entry)
                return -ENOMEM;
        dev_entry->dev = dev;
 
+       spin_lock_irqsave(&dev_data->lock, flags);
        list_add_tail(&dev_entry->list, &dev_data->dev_list);
+       spin_unlock_irqrestore(&dev_data->lock, flags);
 
        return 0;
+}
+
+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
+{
+       struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
+       struct pci_dev_entry *dev_entry, *t;
+       struct pci_dev *found_dev = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev_data->lock, flags);
+
+       list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
+               if (dev_entry->dev == dev) {
+                       list_del(&dev_entry->list);
+                       found_dev = dev_entry->dev;
+                       kfree(dev_entry);
+               }
+       }
+
+       spin_unlock_irqrestore(&dev_data->lock, flags);
+
+       if (found_dev)
+               pcistub_put_pci_dev(found_dev);
 }
 
 int pciback_init_devices(struct pciback_device *pdev)
@@ -53,6 +89,8 @@ int pciback_init_devices(struct pciback_
        dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL);
        if (!dev_data)
                return -ENOMEM;
+
+       spin_lock_init(&dev_data->lock);
 
        INIT_LIST_HEAD(&dev_data->dev_list);
 
@@ -70,6 +108,8 @@ int pciback_publish_pci_roots(struct pci
        struct pci_dev *dev;
        int found;
        unsigned int domain, bus;
+
+       spin_lock(&dev_data->lock);
 
        list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
                /* Only publish this device as a root if none of its
@@ -96,10 +136,11 @@ int pciback_publish_pci_roots(struct pci
                }
        }
 
+       spin_unlock(&dev_data->lock);
+
        return err;
 }
 
-/* Must hold pciback_device->dev_lock when calling this */
 void pciback_release_devices(struct pciback_device *pdev)
 {
        struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Tue Mar 28 
08:54:58 2006 -0700
@@ -7,110 +7,190 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/kref.h>
 #include <asm/atomic.h>
 #include "pciback.h"
 
 static char *pci_devs_to_hide = NULL;
 module_param_named(hide, pci_devs_to_hide, charp, 0444);
 
-struct pci_stub_device_id {
+struct pcistub_device_id {
        struct list_head slot_list;
        int domain;
        unsigned char bus;
        unsigned int devfn;
 };
-LIST_HEAD(pci_stub_device_ids);
-
-struct pci_stub_device {
+static LIST_HEAD(pcistub_device_ids);
+static DEFINE_SPINLOCK(device_ids_lock);
+
+struct pcistub_device {
+       struct kref kref;
        struct list_head dev_list;
+       spinlock_t lock;
+
        struct pci_dev *dev;
-       atomic_t in_use;
+       struct pciback_device *pdev;    /* non-NULL if struct pci_dev is in use 
*/
 };
-/* Access to pci_stub_devices & seized_devices lists and the initialize_devices
- * flag must be locked with pci_stub_devices_lock
+/* Access to pcistub_devices & seized_devices lists and the initialize_devices
+ * flag must be locked with pcistub_devices_lock
  */
-DEFINE_SPINLOCK(pci_stub_devices_lock);
-LIST_HEAD(pci_stub_devices);
+static DEFINE_SPINLOCK(pcistub_devices_lock);
+static LIST_HEAD(pcistub_devices);
 
 /* wait for device_initcall before initializing our devices
  * (see pcistub_init_devices_late)
  */
 static int initialize_devices = 0;
-LIST_HEAD(seized_devices);
-
-static inline struct pci_dev *get_pci_dev(struct pci_stub_device *psdev)
-{
-       if (atomic_dec_and_test(&psdev->in_use))
-               return psdev->dev;
-       else {
-               atomic_inc(&psdev->in_use);
+static LIST_HEAD(seized_devices);
+
+static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
+{
+       struct pcistub_device *psdev;
+
+       dev_dbg(&dev->dev, "pcistub_device_alloc\n");
+
+       psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
+       if (!psdev)
                return NULL;
-       }
-}
-
-struct pci_dev *pcistub_get_pci_dev_by_slot(int domain, int bus,
+
+       psdev->dev = pci_dev_get(dev);
+       if (!psdev->dev) {
+               kfree(psdev);
+               return NULL;
+       }
+
+       kref_init(&psdev->kref);
+       spin_lock_init(&psdev->lock);
+
+       return psdev;
+}
+
+/* Don't call this directly as it's called by pcistub_device_put */
+static void pcistub_device_release(struct kref *kref)
+{
+       struct pcistub_device *psdev;
+
+       psdev = container_of(kref, struct pcistub_device, kref);
+
+       dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
+
+       /* Clean-up the device */
+       pciback_reset_device(psdev->dev);
+       pciback_config_free(psdev->dev);
+       kfree(pci_get_drvdata(psdev->dev));
+       pci_set_drvdata(psdev->dev, NULL);
+
+       pci_dev_put(psdev->dev);
+
+       kfree(psdev);
+}
+
+static inline void pcistub_device_get(struct pcistub_device *psdev)
+{
+       kref_get(&psdev->kref);
+}
+
+static inline void pcistub_device_put(struct pcistub_device *psdev)
+{
+       kref_put(&psdev->kref, pcistub_device_release);
+}
+
+static struct pci_dev *pcistub_device_get_pci_dev(struct pciback_device *pdev,
+                                                 struct pcistub_device *psdev)
+{
+       struct pci_dev *pci_dev = NULL;
+       unsigned long flags;
+
+       pcistub_device_get(psdev);
+
+       spin_lock_irqsave(&psdev->lock, flags);
+       if (!psdev->pdev) {
+               psdev->pdev = pdev;
+               pci_dev = psdev->dev;
+       }
+       spin_unlock_irqrestore(&psdev->lock, flags);
+
+       if (!pci_dev)
+               pcistub_device_put(psdev);
+
+       return pci_dev;
+}
+
+struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
+                                           int domain, int bus,
                                            int slot, int func)
 {
-       struct pci_stub_device *psdev;
+       struct pcistub_device *psdev;
        struct pci_dev *found_dev = NULL;
-
-       spin_lock(&pci_stub_devices_lock);
-
-       list_for_each_entry(psdev, &pci_stub_devices, dev_list) {
+       unsigned long flags;
+
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
                if (psdev->dev != NULL
                    && domain == pci_domain_nr(psdev->dev->bus)
                    && bus == psdev->dev->bus->number
                    && PCI_DEVFN(slot, func) == psdev->dev->devfn) {
-                       found_dev = get_pci_dev(psdev);
+                       found_dev = pcistub_device_get_pci_dev(pdev, psdev);
                        break;
                }
        }
 
-       spin_unlock(&pci_stub_devices_lock);
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
        return found_dev;
 }
 
-struct pci_dev *pcistub_get_pci_dev(struct pci_dev *dev)
-{
-       struct pci_stub_device *psdev;
+struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
+                                   struct pci_dev *dev)
+{
+       struct pcistub_device *psdev;
        struct pci_dev *found_dev = NULL;
-
-       spin_lock(&pci_stub_devices_lock);
-
-       list_for_each_entry(psdev, &pci_stub_devices, dev_list) {
+       unsigned long flags;
+
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
                if (psdev->dev == dev) {
-                       found_dev = get_pci_dev(psdev);
+                       found_dev = pcistub_device_get_pci_dev(pdev, psdev);
                        break;
                }
        }
 
-       spin_unlock(&pci_stub_devices_lock);
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
        return found_dev;
 }
 
 void pcistub_put_pci_dev(struct pci_dev *dev)
 {
-       struct pci_stub_device *psdev;
-
-       spin_lock(&pci_stub_devices_lock);
-
-       list_for_each_entry(psdev, &pci_stub_devices, dev_list) {
+       struct pcistub_device *psdev, *found_psdev = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
                if (psdev->dev == dev) {
-                       /* Cleanup our device
-                        * (so it's ready for the next domain)
-                        */
-                       pciback_reset_device(psdev->dev);
-
-                       atomic_inc(&psdev->in_use);
+                       found_psdev = psdev;
                        break;
                }
        }
 
-       spin_unlock(&pci_stub_devices_lock);
-}
-
-static int __devinit pcistub_match(struct pci_dev *dev,
-                                  struct pci_stub_device_id *pdev_id)
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+       /* Cleanup our device
+        * (so it's ready for the next domain)
+        */
+       pciback_reset_device(found_psdev->dev);
+       pciback_config_reset(found_psdev->dev);
+
+       spin_lock_irqsave(&found_psdev->lock, flags);
+       found_psdev->pdev = NULL;
+       spin_unlock_irqrestore(&found_psdev->lock, flags);
+
+       pcistub_device_put(found_psdev);
+}
+
+static int __devinit pcistub_match_one(struct pci_dev *dev,
+                                      struct pcistub_device_id *pdev_id)
 {
        /* Match the specified device by domain, bus, slot, func and also if
         * any of the device's parent bridges match.
@@ -125,23 +205,44 @@ static int __devinit pcistub_match(struc
        return 0;
 }
 
+static int __devinit pcistub_match(struct pci_dev *dev)
+{
+       struct pcistub_device_id *pdev_id;
+       unsigned long flags;
+       int found = 0;
+
+       spin_lock_irqsave(&device_ids_lock, flags);
+       list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) {
+               if (pcistub_match_one(dev, pdev_id)) {
+                       found = 1;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&device_ids_lock, flags);
+
+       return found;
+}
+
 static int __devinit pcistub_init_device(struct pci_dev *dev)
 {
        struct pciback_dev_data *dev_data;
        int err = 0;
+
+       dev_dbg(&dev->dev, "initializing...\n");
 
        /* The PCI backend is not intended to be a module (or to work with
         * removable PCI devices (yet). If it were, pciback_config_free()
         * would need to be called somewhere to free the memory allocated
         * here and then to call kfree(pci_get_drvdata(psdev->dev)).
         */
-       dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL);
+       dev_data = kmalloc(sizeof(*dev_data), GFP_ATOMIC);
        if (!dev_data) {
                err = -ENOMEM;
                goto out;
        }
        pci_set_drvdata(dev, dev_data);
 
+       dev_dbg(&dev->dev, "initializing config\n");
        err = pciback_config_init(dev);
        if (err)
                goto out;
@@ -153,14 +254,15 @@ static int __devinit pcistub_init_device
         * This makes the assumption that the device's resources won't
         * change after this point (otherwise this code may break!)
         */
+       dev_dbg(&dev->dev, "enabling device\n");
        err = pci_enable_device(dev);
        if (err)
                goto config_release;
 
        /* Now disable the device (this also ensures some private device
         * data is setup before we export)
-        * This calls pciback_config_reset(dev)
-        */
+        */
+       dev_dbg(&dev->dev, "reset device\n");
        pciback_reset_device(dev);
 
        return 0;
@@ -182,60 +284,82 @@ static int __devinit pcistub_init_device
  */
 static int __init pcistub_init_devices_late(void)
 {
-       struct pci_stub_device *psdev, *t;
+       struct pcistub_device *psdev;
+       unsigned long flags;
        int err = 0;
 
-       spin_lock(&pci_stub_devices_lock);
-
-       list_for_each_entry_safe(psdev, t, &seized_devices, dev_list) {
+       pr_debug("pciback: pcistub_init_devices_late\n");
+
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+       while (!list_empty(&seized_devices)) {
+               psdev = container_of(seized_devices.next,
+                                    struct pcistub_device, dev_list);
                list_del(&psdev->dev_list);
+
+               spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
                err = pcistub_init_device(psdev->dev);
                if (err) {
-                       printk(KERN_ERR
-                              "pciback: %s error %d initializing device\n",
-                              pci_name(psdev->dev), err);
+                       dev_err(&psdev->dev->dev,
+                               "error %d initializing device\n", err);
                        kfree(psdev);
-                       continue;
-               }
-
-               list_add_tail(&psdev->dev_list, &pci_stub_devices);
+                       psdev = NULL;
+               }
+
+               spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+               if (psdev)
+                       list_add_tail(&psdev->dev_list, &pcistub_devices);
        }
 
        initialize_devices = 1;
 
-       spin_unlock(&pci_stub_devices_lock);
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
 
        return 0;
 }
 
 static int __devinit pcistub_seize(struct pci_dev *dev)
 {
-       struct pci_stub_device *psdev;
+       struct pcistub_device *psdev;
+       unsigned long flags;
+       int initialize_devices_copy;
        int err = 0;
 
-       psdev = kmalloc(sizeof(*psdev), GFP_KERNEL);
+       psdev = pcistub_device_alloc(dev);
        if (!psdev)
                return -ENOMEM;
 
-       psdev->dev = dev;
-       atomic_set(&psdev->in_use, 1);
-
-       spin_lock(&pci_stub_devices_lock);
-
-       if (initialize_devices) {
+       /* initialize_devices has to be accessed under a spin lock. But since
+        * it can only change from 0 -> 1, if it's already 1, we don't have to
+        * worry about it changing. That's why we can take a *copy* of
+        * initialize_devices and wait till we're outside of the lock to
+        * check if it's 1 (don't ever check if it's 0 outside of the lock)
+        */
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+       initialize_devices_copy = initialize_devices;
+
+       if (!initialize_devices_copy) {
+               dev_dbg(&dev->dev, "deferring initialization\n");
+               list_add(&psdev->dev_list, &seized_devices);
+       }
+
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+       if (initialize_devices_copy) {
+               /* don't want irqs disabled when calling pcistub_init_device */
                err = pcistub_init_device(psdev->dev);
                if (err)
                        goto out;
 
-               list_add(&psdev->dev_list, &pci_stub_devices);
-       } else
-               list_add(&psdev->dev_list, &seized_devices);
+               list_add(&psdev->dev_list, &pcistub_devices);
+       }
 
       out:
-       spin_unlock(&pci_stub_devices_lock);
-
        if (err)
-               kfree(psdev);
+               pcistub_device_put(psdev);
 
        return err;
 }
@@ -243,47 +367,78 @@ static int __devinit pcistub_probe(struc
 static int __devinit pcistub_probe(struct pci_dev *dev,
                                   const struct pci_device_id *id)
 {
-       struct pci_stub_device_id *pdev_id;
-       struct pci_dev *seized_dev;
        int err = 0;
 
-       list_for_each_entry(pdev_id, &pci_stub_device_ids, slot_list) {
-
-               if (!pcistub_match(dev, pdev_id))
-                       continue;
+       dev_dbg(&dev->dev, "probing...\n");
+
+       if (pcistub_match(dev)) {
 
                if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
                    && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-                       printk(KERN_ERR
-                              "pciback: %s: can't export pci devices that "
-                              "don't have a normal (0) or bridge (1) "
-                              "header type!\n", pci_name(dev));
+                       dev_err(&dev->dev, "can't export pci devices that "
+                               "don't have a normal (0) or bridge (1) "
+                               "header type!\n");
+                       err = -ENODEV;
+                       goto out;
+               }
+
+               dev_info(&dev->dev, "seizing device\n");
+               err = pcistub_seize(dev);
+       } else
+               /* Didn't find the device */
+               err = -ENODEV;
+
+      out:
+       return err;
+}
+
+static void pcistub_remove(struct pci_dev *dev)
+{
+       struct pcistub_device *psdev, *found_psdev = NULL;
+       unsigned long flags;
+
+       dev_dbg(&dev->dev, "removing\n");
+
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
+               if (psdev->dev == dev) {
+                       found_psdev = psdev;
                        break;
                }
-
-               pr_info("pciback: seizing PCI device %s\n", pci_name(dev));
-               seized_dev = pci_dev_get(dev);
-
-               if (seized_dev) {
-                       err = pcistub_seize(seized_dev);
-                       if (err) {
-                               pci_dev_put(dev);
-                               goto out;
-                       }
-
-                       /* Success! */
-                       goto out;
-               }
-       }
-
-       /* Didn't find the device */
-       err = -ENODEV;
-
-      out:
-       return err;
-}
-
-struct pci_device_id pcistub_ids[] = {
+       }
+
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+       if (found_psdev) {
+               dev_dbg(&dev->dev, "found device to remove - in use? %p\n",
+                       found_psdev->pdev);
+
+               if (found_psdev->pdev) {
+                       printk(KERN_WARNING "pciback: ****** removing device "
+                              "%s while still in-use! ******\n",
+                              pci_name(found_psdev->dev));
+                       printk(KERN_WARNING "pciback: ****** driver domain may "
+                              "still access this device's i/o resources!\n");
+                       printk(KERN_WARNING "pciback: ****** shutdown driver "
+                              "domain before binding device\n");
+                       printk(KERN_WARNING "pciback: ****** to other drivers "
+                              "or domains\n");
+
+                       pciback_release_pci_dev(found_psdev->pdev,
+                                               found_psdev->dev);
+               }
+
+               spin_lock_irqsave(&pcistub_devices_lock, flags);
+               list_del(&found_psdev->dev_list);
+               spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+               /* the final put for releasing from the list */
+               pcistub_device_put(found_psdev);
+       }
+}
+
+static struct pci_device_id pcistub_ids[] = {
        {
         .vendor = PCI_ANY_ID,
         .device = PCI_ANY_ID,
@@ -298,16 +453,152 @@ struct pci_device_id pcistub_ids[] = {
  * for a normal device. I don't want it to be loaded automatically.
  */
 
-struct pci_driver pciback_pci_driver = {
+static struct pci_driver pciback_pci_driver = {
        .name = "pciback",
        .id_table = pcistub_ids,
        .probe = pcistub_probe,
+       .remove = pcistub_remove,
 };
 
+static inline int str_to_slot(const char *buf, int *domain, int *bus,
+                             int *slot, int *func)
+{
+       int err;
+
+       err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
+       if (err == 4)
+               return 0;
+       else if (err < 0)
+               return -EINVAL;
+
+       /* try again without domain */
+       *domain = 0;
+       err = sscanf(buf, " %x:%x.%x", bus, slot, func);
+       if (err == 3)
+               return 0;
+
+       return -EINVAL;
+}
+
+static int pcistub_device_id_add(int domain, int bus, int slot, int func)
+{
+       struct pcistub_device_id *pci_dev_id;
+       unsigned long flags;
+
+       pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
+       if (!pci_dev_id)
+               return -ENOMEM;
+
+       pci_dev_id->domain = domain;
+       pci_dev_id->bus = bus;
+       pci_dev_id->devfn = PCI_DEVFN(slot, func);
+
+       pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n",
+                domain, bus, slot, func);
+
+       spin_lock_irqsave(&device_ids_lock, flags);
+       list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids);
+       spin_unlock_irqrestore(&device_ids_lock, flags);
+
+       return 0;
+}
+
+static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
+{
+       struct pcistub_device_id *pci_dev_id, *t;
+       int devfn = PCI_DEVFN(slot, func);
+       int err = -ENOENT;
+       unsigned long flags;
+
+       spin_lock_irqsave(&device_ids_lock, flags);
+       list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, slot_list) 
{
+
+               if (pci_dev_id->domain == domain
+                   && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
+                       /* Don't break; here because it's possible the same
+                        * slot could be in the list more than once
+                        */
+                       list_del(&pci_dev_id->slot_list);
+                       kfree(pci_dev_id);
+
+                       err = 0;
+
+                       pr_debug("pciback: removed %04x:%02x:%02x.%01x from "
+                                "seize list\n", domain, bus, slot, func);
+               }
+       }
+       spin_unlock_irqrestore(&device_ids_lock, flags);
+
+       return err;
+}
+
+static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
+                               size_t count)
+{
+       int domain, bus, slot, func;
+       int err;
+
+       err = str_to_slot(buf, &domain, &bus, &slot, &func);
+       if (err)
+               goto out;
+
+       err = pcistub_device_id_add(domain, bus, slot, func);
+
+      out:
+       if (!err)
+               err = count;
+       return err;
+}
+
+DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
+
+static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
+                                  size_t count)
+{
+       int domain, bus, slot, func;
+       int err;
+
+       err = str_to_slot(buf, &domain, &bus, &slot, &func);
+       if (err)
+               goto out;
+
+       err = pcistub_device_id_remove(domain, bus, slot, func);
+
+      out:
+       if (!err)
+               err = count;
+       return err;
+}
+
+DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
+
+static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
+{
+       struct pcistub_device_id *pci_dev_id;
+       size_t count = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&device_ids_lock, flags);
+       list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) {
+               if (count >= PAGE_SIZE)
+                       break;
+
+               count += scnprintf(buf + count, PAGE_SIZE - count,
+                                  "%04x:%02x:%02x.%01x\n",
+                                  pci_dev_id->domain, pci_dev_id->bus,
+                                  PCI_SLOT(pci_dev_id->devfn),
+                                  PCI_FUNC(pci_dev_id->devfn));
+       }
+       spin_unlock_irqrestore(&device_ids_lock, flags);
+
+       return count;
+}
+
+DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
+
 static int __init pcistub_init(void)
 {
        int pos = 0;
-       struct pci_stub_device_id *pci_dev_id;
        int err = 0;
        int domain, bus, slot, func;
        int parsed;
@@ -328,33 +619,27 @@ static int __init pcistub_init(void)
                                        goto parse_error;
                        }
 
-                       pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
-                       if (!pci_dev_id) {
-                               err = -ENOMEM;
+                       err = pcistub_device_id_add(domain, bus, slot, func);
+                       if (err)
                                goto out;
-                       }
-
-                       pci_dev_id->domain = domain;
-                       pci_dev_id->bus = bus;
-                       pci_dev_id->devfn = PCI_DEVFN(slot, func);
-
-                       pr_debug
-                           ("pciback: wants to seize %04x:%02x:%02x.%01x\n",
-                            domain, bus, slot, func);
-
-                       list_add_tail(&pci_dev_id->slot_list,
-                                     &pci_stub_device_ids);
 
                        /* if parsed<=0, we've reached the end of the string */
                        pos += parsed;
                } while (parsed > 0 && pci_devs_to_hide[pos]);
-
-               /* If we're the first PCI Device Driver to register, we're the
-                * first one to get offered PCI devices as they become
-                * available (and thus we can be the first to grab them)
-                */
-               pci_register_driver(&pciback_pci_driver);
-       }
+       }
+
+       /* If we're the first PCI Device Driver to register, we're the
+        * first one to get offered PCI devices as they become
+        * available (and thus we can be the first to grab them)
+        */
+       err = pci_register_driver(&pciback_pci_driver);
+       if (err < 0)
+               goto out;
+
+       driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
+       driver_create_file(&pciback_pci_driver.driver,
+                          &driver_attr_remove_slot);
+       driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
 
       out:
        return err;
@@ -386,19 +671,22 @@ static int __init pciback_init(void)
                return err;
 #endif
 
-       if (list_empty(&pci_stub_device_ids))
-               return -ENODEV;
        pcistub_init_devices_late();
        pciback_xenbus_register();
 
-       __unsafe(THIS_MODULE);
-
        return 0;
 }
 
-static void pciback_cleanup(void)
-{
-       BUG();
+static void __exit pciback_cleanup(void)
+{
+       pciback_xenbus_unregister();
+
+       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
+       driver_remove_file(&pciback_pci_driver.driver,
+                          &driver_attr_remove_slot);
+       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
+
+       pci_unregister_driver(&pciback_pci_driver);
 }
 
 module_init(pciback_init);
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h        Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h        Tue Mar 28 
08:54:58 2006 -0700
@@ -37,9 +37,11 @@ struct pciback_dev_data {
 };
 
 /* Get/Put PCI Devices that are hidden from the PCI Backend Domain */
-struct pci_dev *pcistub_get_pci_dev_by_slot(int domain, int bus,
+struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
+                                           int domain, int bus,
                                            int slot, int func);
-struct pci_dev *pcistub_get_pci_dev(struct pci_dev *dev);
+struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
+                                   struct pci_dev *dev);
 void pcistub_put_pci_dev(struct pci_dev *dev);
 
 /* Ensure a device is turned off or reset */
@@ -57,6 +59,7 @@ typedef int (*publish_pci_root_cb) (stru
 typedef int (*publish_pci_root_cb) (struct pciback_device * pdev,
                                    unsigned int domain, unsigned int bus);
 int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev);
+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev);
 struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
                                    unsigned int domain, unsigned int bus,
                                    unsigned int devfn);
@@ -69,6 +72,7 @@ irqreturn_t pciback_handle_event(int irq
 irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs);
 
 int pciback_xenbus_register(void);
+void pciback_xenbus_unregister(void);
 
 extern int verbose_request;
 #endif
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c    Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c    Tue Mar 28 
08:54:58 2006 -0700
@@ -12,9 +12,8 @@ module_param(verbose_request, int, 0644)
 module_param(verbose_request, int, 0644);
 
 /* Ensure a device is "turned off" and ready to be exported.
- * This also sets up the device's private data to keep track of what should
- * be in the base address registers (BARs) so that we can keep the
- * client from manipulating them directly.
+ * (Also see pciback_config_reset to ensure virtual configuration space is
+ * ready to be re-exported)
  */
 void pciback_reset_device(struct pci_dev *dev)
 {
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pciback/vpci.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/vpci.c   Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/vpci.c   Tue Mar 28 08:54:58 
2006 -0700
@@ -8,12 +8,15 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/spinlock.h>
 #include "pciback.h"
 
 #define PCI_SLOT_MAX 32
 
 struct vpci_dev_data {
+       /* Access to dev_list must be protected by lock */
        struct list_head dev_list[PCI_SLOT_MAX];
+       spinlock_t lock;
 };
 
 static inline struct list_head *list_first(struct list_head *head)
@@ -25,25 +28,29 @@ struct pci_dev *pciback_get_pci_dev(stru
                                    unsigned int domain, unsigned int bus,
                                    unsigned int devfn)
 {
-       struct pci_dev_entry *dev_entry;
-       struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+       struct pci_dev_entry *entry;
+       struct pci_dev *dev = NULL;
+       struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+       unsigned long flags;
 
        if (domain != 0 || bus != 0)
                return NULL;
 
        if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
-               /* we don't need to lock the list here because once the backend
-                * is in operation, it won't have any more devices addeded
-                * (or removed).
-                */
-               list_for_each_entry(dev_entry,
+               spin_lock_irqsave(&vpci_dev->lock, flags);
+
+               list_for_each_entry(entry,
                                    &vpci_dev->dev_list[PCI_SLOT(devfn)],
                                    list) {
-                       if (PCI_FUNC(dev_entry->dev->devfn) == PCI_FUNC(devfn))
-                               return dev_entry->dev;
-               }
-       }
-       return NULL;
+                       if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
+                               dev = entry->dev;
+                               break;
+                       }
+               }
+
+               spin_unlock_irqrestore(&vpci_dev->lock, flags);
+       }
+       return dev;
 }
 
 static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
@@ -55,12 +62,12 @@ static inline int match_slot(struct pci_
        return 0;
 }
 
-/* Must hold pciback_device->dev_lock when calling this */
 int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
 {
        int err = 0, slot;
        struct pci_dev_entry *t, *dev_entry;
        struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+       unsigned long flags;
 
        if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
                err = -EFAULT;
@@ -78,6 +85,8 @@ int pciback_add_pci_dev(struct pciback_d
        }
 
        dev_entry->dev = dev;
+
+       spin_lock_irqsave(&vpci_dev->lock, flags);
 
        /* Keep multi-function devices together on the virtual PCI bus */
        for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
@@ -92,7 +101,7 @@ int pciback_add_pci_dev(struct pciback_d
                                        PCI_FUNC(dev->devfn));
                                list_add_tail(&dev_entry->list,
                                              &vpci_dev->dev_list[slot]);
-                               goto out;
+                               goto unlock;
                        }
                }
        }
@@ -105,7 +114,7 @@ int pciback_add_pci_dev(struct pciback_d
                               pci_name(dev), slot);
                        list_add_tail(&dev_entry->list,
                                      &vpci_dev->dev_list[slot]);
-                       goto out;
+                       goto unlock;
                }
        }
 
@@ -113,8 +122,39 @@ int pciback_add_pci_dev(struct pciback_d
        xenbus_dev_fatal(pdev->xdev, err,
                         "No more space on root virtual PCI bus");
 
+      unlock:
+       spin_unlock_irqrestore(&vpci_dev->lock, flags);
       out:
        return err;
+}
+
+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
+{
+       int slot;
+       struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+       struct pci_dev *found_dev = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&vpci_dev->lock, flags);
+
+       for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
+               struct pci_dev_entry *e, *tmp;
+               list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
+                                        list) {
+                       if (e->dev == dev) {
+                               list_del(&e->list);
+                               found_dev = e->dev;
+                               kfree(e);
+                               goto out;
+                       }
+               }
+       }
+
+      out:
+       spin_unlock_irqrestore(&vpci_dev->lock, flags);
+
+       if (found_dev)
+               pcistub_put_pci_dev(found_dev);
 }
 
 int pciback_init_devices(struct pciback_device *pdev)
@@ -126,6 +166,8 @@ int pciback_init_devices(struct pciback_
        if (!vpci_dev)
                return -ENOMEM;
 
+       spin_lock_init(&vpci_dev->lock);
+
        for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
                INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
        }
@@ -142,7 +184,6 @@ int pciback_publish_pci_roots(struct pci
        return publish_cb(pdev, 0, 0);
 }
 
-/* Must hold pciback_device->dev_lock when calling this */
 void pciback_release_devices(struct pciback_device *pdev)
 {
        int slot;
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Mon Mar 27 15:36:47 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Tue Mar 28 08:54:58 
2006 -0700
@@ -12,7 +12,7 @@
 
 #define INVALID_EVTCHN_IRQ  (-1)
 
-struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
+static struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
 {
        struct pciback_device *pdev;
 
@@ -38,7 +38,7 @@ struct pciback_device *alloc_pdev(struct
        return pdev;
 }
 
-void free_pdev(struct pciback_device *pdev)
+static void free_pdev(struct pciback_device *pdev)
 {
        if (pdev->be_watching)
                unregister_xenbus_watch(&pdev->be_watch);
@@ -247,7 +247,7 @@ static int pciback_export_device(struct 
        dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n",
                domain, bus, slot, func);
 
-       dev = pcistub_get_pci_dev_by_slot(domain, bus, slot, func);
+       dev = pcistub_get_pci_dev_by_slot(pdev, domain, bus, slot, func);
        if (!dev) {
                err = -EINVAL;
                xenbus_dev_fatal(pdev->xdev, err,
@@ -434,3 +434,8 @@ int __init pciback_xenbus_register(void)
 {
        return xenbus_register_backend(&xenbus_pciback_driver);
 }
+
+void __exit pciback_xenbus_unregister(void)
+{
+       xenbus_unregister_driver(&xenbus_pciback_driver);
+}
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c        Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c        Tue Mar 28 
08:54:58 2006 -0700
@@ -56,19 +56,19 @@ static int do_pci_op(struct pcifront_dev
        notify_remote_via_evtchn(port);
 
        /*
-        * We set a poll timeout of 5 seconds but give up on return after
-        * 4 seconds. It is better to time out too late rather than too early
+        * We set a poll timeout of 3 seconds but give up on return after
+        * 2 seconds. It is better to time out too late rather than too early
         * (in the latter case we end up continually re-executing poll() with a
         * timeout in the past). 1s difference gives plenty of slack for error.
         */
        do_gettimeofday(&tv);
-       ns_timeout = timeval_to_ns(&tv) + 4 * (nsec_t)NSEC_PER_SEC;
+       ns_timeout = timeval_to_ns(&tv) + 2 * (nsec_t)NSEC_PER_SEC;
 
        clear_evtchn(port);
 
        while (test_bit(_XEN_PCIF_active,
                        (unsigned long *)&pdev->sh_info->flags)) {
-               if (HYPERVISOR_poll(&port, 1, jiffies + 5*HZ))
+               if (HYPERVISOR_poll(&port, 1, jiffies + 3*HZ))
                        BUG();
                clear_evtchn(port);
                do_gettimeofday(&tv);
@@ -173,7 +173,7 @@ static void pcifront_claim_resource(stru
 
                if (!r->parent && r->start && r->flags) {
                        dev_dbg(&pdev->xdev->dev, "claiming resource %s/%d\n",
-                                       pci_name(dev), i);
+                               pci_name(dev), i);
                        pci_claim_resource(dev, i);
                }
        }
@@ -234,25 +234,38 @@ int pcifront_scan_root(struct pcifront_d
        return err;
 }
 
+static void free_root_bus_devs(struct pci_bus *bus)
+{
+       struct pci_dev *dev;
+
+       spin_lock(&pci_bus_lock);
+       while (!list_empty(&bus->devices)) {
+               dev = container_of(bus->devices.next, struct pci_dev, bus_list);
+               spin_unlock(&pci_bus_lock);
+
+               dev_dbg(&dev->dev, "removing device\n");
+               pci_remove_bus_device(dev);
+
+               spin_lock(&pci_bus_lock);
+       }
+       spin_unlock(&pci_bus_lock);
+}
+
 void pcifront_free_roots(struct pcifront_device *pdev)
 {
        struct pci_bus_entry *bus_entry, *t;
 
+       dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
+
        list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
-               /* TODO: Removing a PCI Bus is untested (as it normally
-                * just goes away on domain shutdown)
-                */
                list_del(&bus_entry->list);
 
-               spin_lock(&pci_bus_lock);
-               list_del(&bus_entry->bus->node);
-               spin_unlock(&pci_bus_lock);
+               free_root_bus_devs(bus_entry->bus);
 
                kfree(bus_entry->bus->sysdata);
 
                device_unregister(bus_entry->bus->bridge);
-
-               /* Do we need to free() the bus itself? */
+               pci_remove_bus(bus_entry->bus);
 
                kfree(bus_entry);
        }
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c        Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c        Tue Mar 28 
08:54:58 2006 -0700
@@ -50,6 +50,8 @@ static void free_pdev(struct pcifront_de
 {
        dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev);
 
+       pcifront_free_roots(pdev);
+
        if (pdev->evtchn != INVALID_EVTCHN)
                xenbus_free_evtchn(pdev->xdev, pdev->evtchn);
 
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c   Tue Mar 28 08:54:58 2006 -0700
@@ -6,9 +6,9 @@
 #include <asm/uaccess.h>
 #include <xen/driver_util.h>
 
-static int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
-       /* generic_page_range() does all the hard work. */
+       /* apply_to_page_range() does all the hard work. */
        return 0;
 }
 
@@ -24,8 +24,8 @@ struct vm_struct *alloc_vm_area(unsigned
         * This ensures that page tables are constructed for this region
         * of kernel virtual address space and mapped into init_mm.
         */
-       if (generic_page_range(&init_mm, (unsigned long)area->addr,
-                              area->size, f, NULL)) {
+       if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+                               area->size, f, NULL)) {
                free_vm_area(area);
                return NULL;
        }
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Mar 27 
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Mar 28 
08:54:58 2006 -0700
@@ -1039,8 +1039,7 @@ static int __init xenbus_probe_init(void
                xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
                if (xsd_port_intf)
                        xsd_port_intf->read_proc = xsd_port_read;
-       }
-       else
+       } else
                xenstored_ready = 1;
 
        /* Initialize the interface to xenstore. */
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h    Mon Mar 
27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h    Tue Mar 
28 08:54:58 2006 -0700
@@ -146,7 +146,7 @@ static inline void detect_ht(struct cpui
  */
 static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int 
*ebx, unsigned int *ecx, unsigned int *edx)
 {
-       __asm__("cpuid"
+       __asm__(XEN_CPUID
                : "=a" (*eax),
                  "=b" (*ebx),
                  "=c" (*ecx),
@@ -158,7 +158,7 @@ static inline void cpuid_count(int op, i
 static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
                int *edx)
 {
-       __asm__("cpuid"
+       __asm__(XEN_CPUID
                : "=a" (*eax),
                  "=b" (*ebx),
                  "=c" (*ecx),
@@ -173,7 +173,7 @@ static inline unsigned int cpuid_eax(uns
 {
        unsigned int eax;
 
-       __asm__("cpuid"
+       __asm__(XEN_CPUID
                : "=a" (eax)
                : "0" (op)
                : "bx", "cx", "dx");
@@ -183,7 +183,7 @@ static inline unsigned int cpuid_ebx(uns
 {
        unsigned int eax, ebx;
 
-       __asm__("cpuid"
+       __asm__(XEN_CPUID
                : "=a" (eax), "=b" (ebx)
                : "0" (op)
                : "cx", "dx" );
@@ -193,7 +193,7 @@ static inline unsigned int cpuid_ecx(uns
 {
        unsigned int eax, ecx;
 
-       __asm__("cpuid"
+       __asm__(XEN_CPUID
                : "=a" (eax), "=c" (ecx)
                : "0" (op)
                : "bx", "dx" );
@@ -203,7 +203,7 @@ static inline unsigned int cpuid_edx(uns
 {
        unsigned int eax, edx;
 
-       __asm__("cpuid"
+       __asm__(XEN_CPUID
                : "=a" (eax), "=d" (edx)
                : "0" (op)
                : "bx", "cx");
@@ -237,20 +237,11 @@ extern unsigned long mmu_cr4_features;
 
 static inline void set_in_cr4 (unsigned long mask)
 {
+       unsigned cr4;
        mmu_cr4_features |= mask;
-       switch (mask) {
-       case X86_CR4_OSFXSR:
-       case X86_CR4_OSXMMEXCPT:
-               break;
-       default:
-               do {
-                       const char *msg = "Xen unsupported cr4 update\n";
-                       (void)HYPERVISOR_console_io(
-                               CONSOLEIO_write, __builtin_strlen(msg),
-                               (char *)msg);
-                       BUG();
-               } while (0);
-       }
+       cr4 = read_cr4();
+       cr4 |= mask;
+       write_cr4(cr4);
 }
 
 static inline void clear_in_cr4 (unsigned long mask)
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Mon Mar 
27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Tue Mar 
28 08:54:58 2006 -0700
@@ -14,18 +14,6 @@ static char * __init machine_specific_me
        add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM);
 
        return "Xen";
-}
-
-void __devinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
-{
-       clear_bit(X86_FEATURE_VME, c->x86_capability);
-       clear_bit(X86_FEATURE_DE, c->x86_capability);
-       clear_bit(X86_FEATURE_PSE, c->x86_capability);
-       clear_bit(X86_FEATURE_PGE, c->x86_capability);
-       clear_bit(X86_FEATURE_SEP, c->x86_capability);
-       if (!(xen_start_info->flags & SIF_PRIVILEGED))
-               clear_bit(X86_FEATURE_MTRR, c->x86_capability);
-       c->hlt_works_ok = 0;
 }
 
 extern void hypervisor_callback(void);
@@ -51,8 +39,6 @@ static void __init machine_specific_arch
        cb.handler_address = (unsigned long)&nmi;
        HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
 
-       machine_specific_modify_cpu_capabilities(&boot_cpu_data);
-
        if (HYPERVISOR_xen_version(XENVER_platform_parameters,
                                   &pp) == 0)
                set_fixaddr_top(pp.virt_start - PAGE_SIZE);
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h  Mon Mar 
27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h  Tue Mar 
28 08:54:58 2006 -0700
@@ -141,31 +141,21 @@ static inline void set_in_cr4 (unsigned 
 static inline void set_in_cr4 (unsigned long mask)
 {
        mmu_cr4_features |= mask;
-       switch (mask) {
-       case X86_CR4_OSFXSR:
-       case X86_CR4_OSXMMEXCPT:
-               break;
-       default:
-               do {
-                       const char *msg = "Xen unsupported cr4 update\n";
-                       (void)HYPERVISOR_console_io(
-                               CONSOLEIO_write, __builtin_strlen(msg),
-                               (char *)msg);
-                       BUG();
-               } while (0);
-       }
+       __asm__("movq %%cr4,%%rax\n\t"
+               "orq %0,%%rax\n\t"
+               "movq %%rax,%%cr4\n"
+               : : "irg" (mask)
+               :"ax");
 }
 
 static inline void clear_in_cr4 (unsigned long mask)
 {
-#ifndef CONFIG_XEN
        mmu_cr4_features &= ~mask;
        __asm__("movq %%cr4,%%rax\n\t"
                "andq %0,%%rax\n\t"
                "movq %%rax,%%cr4\n"
                : : "irg" (~mask)
                :"ax");
-#endif
 }
 
 
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h        
Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h        
Tue Mar 28 08:54:58 2006 -0700
@@ -5,17 +5,6 @@
  *     This is included late in kernel/setup.c so that it can make
  *     use of all of the static functions.
  **/
-
-void __cpuinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
-{
-       clear_bit(X86_FEATURE_VME, c->x86_capability);
-       clear_bit(X86_FEATURE_DE, c->x86_capability);
-       clear_bit(X86_FEATURE_PSE, c->x86_capability);
-       clear_bit(X86_FEATURE_PGE, c->x86_capability);
-       clear_bit(X86_FEATURE_SEP, c->x86_capability);
-       if (!(xen_start_info->flags & SIF_PRIVILEGED))
-               clear_bit(X86_FEATURE_MTRR, c->x86_capability);
-}
 
 extern void hypervisor_callback(void);
 extern void failsafe_callback(void);
@@ -36,6 +25,4 @@ static void __init machine_specific_arch
        cb.handler_address = (unsigned long)&nmi;
        HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
 #endif
-
-       machine_specific_modify_cpu_capabilities(&boot_cpu_data);
 }
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/include/linux/mm.h
--- a/linux-2.6-xen-sparse/include/linux/mm.h   Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/linux/mm.h   Tue Mar 28 08:54:58 2006 -0700
@@ -1020,10 +1020,10 @@ struct page *follow_page(struct vm_area_
 #define FOLL_ANON      0x08    /* give ZERO_PAGE if no pgtable */
 
 #ifdef CONFIG_XEN
-typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr,
-                        void *data);
-extern int generic_page_range(struct mm_struct *mm, unsigned long address,
-                              unsigned long size, pte_fn_t fn, void *data);
+typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr,
+                       void *data);
+extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,
+                              unsigned long size, pte_fn_t fn, void *data);
 #endif
 
 #ifdef CONFIG_PROC_FS
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c  Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/mm/memory.c  Tue Mar 28 08:54:58 2006 -0700
@@ -1378,36 +1378,39 @@ EXPORT_SYMBOL(remap_pfn_range);
 EXPORT_SYMBOL(remap_pfn_range);
 
 #ifdef CONFIG_XEN
-static inline int generic_pte_range(struct mm_struct *mm, pmd_t *pmd,
-                                   unsigned long addr, unsigned long end,
-                                   pte_fn_t fn, void *data)
+static inline int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
+                                    unsigned long addr, unsigned long end,
+                                    pte_fn_t fn, void *data)
 {
        pte_t *pte;
        int err;
-       struct page *pte_page;
+       struct page *pmd_page;
+       spinlock_t *ptl;
 
        pte = (mm == &init_mm) ?
                pte_alloc_kernel(pmd, addr) :
-               pte_alloc_map(mm, pmd, addr);
+               pte_alloc_map_lock(mm, pmd, addr, &ptl);
        if (!pte)
                return -ENOMEM;
 
-       pte_page = pmd_page(*pmd);
+       BUG_ON(pmd_huge(*pmd));
+
+       pmd_page = pmd_page(*pmd);
 
        do {
-               err = fn(pte, pte_page, addr, data);
+               err = fn(pte, pmd_page, addr, data);
                if (err)
                        break;
        } while (pte++, addr += PAGE_SIZE, addr != end);
 
        if (mm != &init_mm)
-               pte_unmap(pte-1);
+               pte_unmap_unlock(pte-1, ptl);
        return err;
 }
 
-static inline int generic_pmd_range(struct mm_struct *mm, pud_t *pud,
-                                   unsigned long addr, unsigned long end,
-                                   pte_fn_t fn, void *data)
+static inline int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
+                                    unsigned long addr, unsigned long end,
+                                    pte_fn_t fn, void *data)
 {
        pmd_t *pmd;
        unsigned long next;
@@ -1418,16 +1421,16 @@ static inline int generic_pmd_range(stru
                return -ENOMEM;
        do {
                next = pmd_addr_end(addr, end);
-               err = generic_pte_range(mm, pmd, addr, next, fn, data);
+               err = apply_to_pte_range(mm, pmd, addr, next, fn, data);
                if (err)
                        break;
        } while (pmd++, addr = next, addr != end);
        return err;
 }
 
-static inline int generic_pud_range(struct mm_struct *mm, pgd_t *pgd,
-                                   unsigned long addr, unsigned long end,
-                                   pte_fn_t fn, void *data)
+static inline int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
+                                    unsigned long addr, unsigned long end,
+                                    pte_fn_t fn, void *data)
 {
        pud_t *pud;
        unsigned long next;
@@ -1438,7 +1441,7 @@ static inline int generic_pud_range(stru
                return -ENOMEM;
        do {
                next = pud_addr_end(addr, end);
-               err = generic_pmd_range(mm, pud, addr, next, fn, data);
+               err = apply_to_pmd_range(mm, pud, addr, next, fn, data);
                if (err)
                        break;
        } while (pud++, addr = next, addr != end);
@@ -1449,8 +1452,8 @@ static inline int generic_pud_range(stru
  * Scan a region of virtual memory, filling in page tables as necessary
  * and calling a provided function on each leaf page table.
  */
-int generic_page_range(struct mm_struct *mm, unsigned long addr,
-                      unsigned long size, pte_fn_t fn, void *data)
+int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
+                       unsigned long size, pte_fn_t fn, void *data)
 {
        pgd_t *pgd;
        unsigned long next;
@@ -1461,12 +1464,13 @@ int generic_page_range(struct mm_struct 
        pgd = pgd_offset(mm, addr);
        do {
                next = pgd_addr_end(addr, end);
-               err = generic_pud_range(mm, pgd, addr, next, fn, data);
+               err = apply_to_pud_range(mm, pgd, addr, next, fn, data);
                if (err)
                        break;
        } while (pgd++, addr = next, addr != end);
        return err;
 }
+EXPORT_SYMBOL_GPL(apply_to_page_range);
 #endif
 
 /*
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/Makefile
--- a/tools/Makefile    Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/Makefile    Tue Mar 28 08:54:58 2006 -0700
@@ -37,6 +37,7 @@ install: check
                $(MAKE) -C $$subdir $@; \
        done
        $(MAKE) ioemuinstall
+       $(INSTALL_DIR) -p $(DESTDIR)/var/xen/dump
 
 clean: check_clean
        @set -e; for subdir in $(SUBDIRS); do \
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/debugger/gdb/README
--- a/tools/debugger/gdb/README Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/debugger/gdb/README Tue Mar 28 08:54:58 2006 -0700
@@ -11,8 +11,8 @@ To build the GDB server:
     to your test machine.
 
 To build a debuggable guest kernel image:
- 1. cd linux-2.6.12-xenU
- 2. ARCH=xen make menuconfig
+ 1. cd linux-2.6.xx-xenU
+ 2. make menuconfig
  3. From within the configurator, enable the following options:
     # Kernel hacking -> Compile the kernel with debug info [*]
                      -> Compile the kernel with frame pointers
diff -r 7e3cbc409676 -r d75a6cc5e68a 
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv       
Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv       
Tue Mar 28 08:54:58 2006 -0700
@@ -61,7 +61,7 @@ case "${target}" in
                        srv_linux_thread_db=yes
                        ;;
   x86_64-*-linux*)     srv_regobj=reg-x86-64.o
-                       srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o"
+                       srv_tgtobj="linux-xen-low.o linux-x86-64-low.o 
i387-fp.o"
                        srv_linux_regsets=yes
                        ;;
   xscale*-*-linux*)    srv_regobj=reg-arm.o
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent  Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/examples/xen-backend.agent  Tue Mar 28 08:54:58 2006 -0700
@@ -1,6 +1,10 @@
 #! /bin/sh
 
 PATH=/etc/xen/scripts:$PATH
+
+. /etc/xen/scripts/locking.sh
+
+claim_lock xenbus_hotplug_global
 
 case "$XENBUS_TYPE" in
   vbd)
@@ -25,3 +29,5 @@ case "$ACTION" in
   offline)
     ;;
 esac
+
+release_lock xenbus_hotplug_global
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/examples/xend-config.sxp    Tue Mar 28 08:54:58 2006 -0700
@@ -15,7 +15,9 @@
 #(loglevel DEBUG)
 
 #(xend-http-server no)
-#(xend-unix-server yes)
+#(xend-unix-server no)
+#(xend-tcp-xmlrpc-server no)
+#(xend-unix-xmlrpc-server yes)
 #(xend-relocation-server no)
 (xend-relocation-server yes)
 
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/ioemu/hw/pcnet.c
--- a/tools/ioemu/hw/pcnet.c    Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/ioemu/hw/pcnet.c    Tue Mar 28 08:54:58 2006 -0700
@@ -45,21 +45,6 @@
 #define PCNET_PNPMMIO_SIZE      0x20
 
 
-typedef struct PCNetState_st PCNetState;
-
-struct PCNetState_st {
-    PCIDevice dev;
-    NetDriverState *nd;
-    int mmio_io_addr, rap, isr, lnkst;
-    target_phys_addr_t rdra, tdra;
-    uint8_t prom[16];
-    uint16_t csr[128];
-    uint16_t bcr[32];
-    uint64_t timer;
-    int xmit_pos, recv_pos;
-    uint8_t buffer[4096];
-};
-
 #include "pcnet.h"
 
 static void pcnet_poll(PCNetState *s);
@@ -217,6 +202,11 @@ static void pcnet_init(PCNetState *s)
     CSR_RCVRC(s) = CSR_RCVRL(s);
     CSR_XMTRC(s) = CSR_XMTRL(s);
 
+    /* flush any cached receive descriptors */
+    s->crmd.rmd1.own = 0;
+    s->nrmd.rmd1.own = 0;
+    s->nnrmd.rmd1.own = 0;
+
 #ifdef PCNET_DEBUG
     printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n", 
         BCR_SSIZE32(s),
@@ -239,6 +229,11 @@ static void pcnet_start(PCNetState *s)
     if (!CSR_DRX(s))
         s->csr[0] |= 0x0020;    /* set RXON */
 
+    /* flush any cached receive descriptors */
+    s->crmd.rmd1.own = 0;
+    s->nrmd.rmd1.own = 0;
+    s->nnrmd.rmd1.own = 0;
+
     s->csr[0] &= ~0x0004;       /* clear STOP bit */
     s->csr[0] |= 0x0002;
 }
@@ -260,29 +255,21 @@ static void pcnet_rdte_poll(PCNetState *
     s->csr[28] = s->csr[29] = 0;
     if (s->rdra) {
         int bad = 0;
-#if 1
         target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
         target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
         target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
-#else
-        target_phys_addr_t crda = s->rdra + 
-            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
-            (BCR_SWSTYLE(s) ? 16 : 8 );
-        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
-        target_phys_addr_t nrda = s->rdra + 
-            (CSR_RCVRL(s) - nrdc) *
-            (BCR_SWSTYLE(s) ? 16 : 8 );
-        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
-        target_phys_addr_t nnrd = s->rdra + 
-            (CSR_RCVRL(s) - nnrc) *
-            (BCR_SWSTYLE(s) ? 16 : 8 );
-#endif
-
-        CHECK_RMD(PHYSADDR(s,crda), bad);
+
+       if (!s->crmd.rmd1.own) {
+           CHECK_RMD(&(s->crmd),PHYSADDR(s,crda), bad);
+       }
         if (!bad) {
-            CHECK_RMD(PHYSADDR(s,nrda), bad);
+           if (s->crmd.rmd1.own && !s->nrmd.rmd1.own) {
+               CHECK_RMD(&(s->nrmd),PHYSADDR(s,nrda), bad);
+           }
             if (bad || (nrda == crda)) nrda = 0;
-            CHECK_RMD(PHYSADDR(s,nnrd), bad);
+           if (s->crmd.rmd1.own && s->nrmd.rmd1.own && !s->nnrmd.rmd1.own) {
+               CHECK_RMD(&(s->nnrmd),PHYSADDR(s,nnrd), bad);
+           }
             if (bad || (nnrd == crda)) nnrd = 0;
 
             s->csr[28] = crda & 0xffff;
@@ -303,14 +290,12 @@ static void pcnet_rdte_poll(PCNetState *
     }
     
     if (CSR_CRDA(s)) {
-        struct pcnet_RMD rmd;
-        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
-        CSR_CRBC(s) = rmd.rmd1.bcnt;
-        CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+        CSR_CRBC(s) = s->crmd.rmd1.bcnt;
+        CSR_CRST(s) = ((uint32_t *)&(s->crmd))[1] >> 16;
 #ifdef PCNET_DEBUG_RMD_X
         printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
                 PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
-                ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
+                ((uint32_t *)&(s->crmd))[1], ((uint32_t *)&(s->crmd))[2]);
         PRINT_RMD(&rmd);
 #endif
     } else {
@@ -318,10 +303,8 @@ static void pcnet_rdte_poll(PCNetState *
     }
     
     if (CSR_NRDA(s)) {
-        struct pcnet_RMD rmd;
-        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
-        CSR_NRBC(s) = rmd.rmd1.bcnt;
-        CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+        CSR_NRBC(s) = s->nrmd.rmd1.bcnt;
+        CSR_NRST(s) = ((uint32_t *)&(s->nrmd))[1] >> 16;
     } else {
         CSR_NRBC(s) = CSR_NRST(s) = 0;
     }
@@ -336,6 +319,7 @@ static int pcnet_tdte_poll(PCNetState *s
             (CSR_XMTRL(s) - CSR_XMTRC(s)) *
             (BCR_SWSTYLE(s) ? 16 : 8 );
         int bad = 0;
+       s->csr[0] &= ~0x0008;   /* clear TDMD */
         CHECK_TMD(PHYSADDR(s, cxda),bad);
         if (!bad) {
             if (CSR_CXDA(s) != cxda) {
@@ -354,12 +338,8 @@ static int pcnet_tdte_poll(PCNetState *s
     }
 
     if (CSR_CXDA(s)) {
-        struct pcnet_TMD tmd;
-
-        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
-
-        CSR_CXBC(s) = tmd.tmd1.bcnt;
-        CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
+        CSR_CXBC(s) = s->tmd.tmd1.bcnt;
+        CSR_CXST(s) = ((uint32_t *)&(s->tmd))[1] >> 16;
     } else {
         CSR_CXBC(s) = CSR_CXST(s) = 0;
     }
@@ -373,14 +353,11 @@ static int pcnet_can_receive(void *opaqu
     if (CSR_STOP(s) || CSR_SPND(s))
         return 0;
         
-    if (s->recv_pos > 0)
-        return 0;
-
     pcnet_rdte_poll(s);
     if (!(CSR_CRST(s) & 0x8000)) {
         return 0;
     }
-    return sizeof(s->buffer)-16;
+    return sizeof(s->rx_buffer)-16;
 }
 
 #define MIN_BUF_SIZE 60
@@ -389,7 +366,7 @@ static void pcnet_receive(void *opaque, 
 {
     PCNetState *s = opaque;
     int is_padr = 0, is_bcast = 0, is_ladr = 0;
-    uint8_t buf1[60];
+    int pad;
 
     if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
         return;
@@ -399,12 +376,10 @@ static void pcnet_receive(void *opaque, 
 #endif
 
     /* if too small buffer, then expand it */
-    if (size < MIN_BUF_SIZE) {
-        memcpy(buf1, buf, size);
-        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
-        buf = buf1;
-        size = MIN_BUF_SIZE;
-    }
+    if (size < MIN_BUF_SIZE)
+        pad = MIN_BUF_SIZE - size + 4;
+    else 
+       pad = 4;
 
     if (CSR_PROM(s) 
         || (is_padr=padr_match(s, buf, size)) 
@@ -413,124 +388,74 @@ static void pcnet_receive(void *opaque, 
 
         pcnet_rdte_poll(s);
 
-        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
-            struct pcnet_RMD rmd;
-            int rcvrc = CSR_RCVRC(s)-1,i;
-            target_phys_addr_t nrda;
-            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
-                if (rcvrc <= 1)
-                    rcvrc = CSR_RCVRL(s);
-                nrda = s->rdra +
-                    (CSR_RCVRL(s) - rcvrc) *
-                    (BCR_SWSTYLE(s) ? 16 : 8 );
-                RMDLOAD(&rmd, PHYSADDR(s,nrda));                  
-                if (rmd.rmd1.own) {                
+       if (size > 2000) {
 #ifdef PCNET_DEBUG_RMD
-                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", 
-                                rcvrc, CSR_RCVRC(s));
-#endif
-                    CSR_RCVRC(s) = rcvrc;
-                    pcnet_rdte_poll(s);
-                    break;
-                }
-            }
-        }
-
-        if (!(CSR_CRST(s) & 0x8000)) {
+           printf("pcnet - oversize packet discarded.\n");
+#endif
+       } else if (!(CSR_CRST(s) & 0x8000)) {
 #ifdef PCNET_DEBUG_RMD
             printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
 #endif
             s->csr[0] |= 0x1000; /* Set MISS flag */
             CSR_MISSC(s)++;
         } else {
-            uint8_t *src = &s->buffer[8];
+            uint8_t *src = &s->rx_buffer[8];
             target_phys_addr_t crda = CSR_CRDA(s);
-            struct pcnet_RMD rmd;
+            target_phys_addr_t nrda = CSR_NRDA(s);
+            target_phys_addr_t nnrda = CSR_NNRD(s);
             int pktcount = 0;
+           int packet_size = size + pad;
 
             memcpy(src, buf, size);
-            
-            if (!CSR_ASTRP_RCV(s)) {
-                uint32_t fcs = ~0;
-#if 0            
-                uint8_t *p = s->buffer;
-                
-                ((uint32_t *)p)[0] = ((uint32_t *)p)[1] = 0xaaaaaaaa;
-                p[7] = 0xab;
-#else
-                uint8_t *p = src;
-#endif
-
-                while (size < 46) {
-                    src[size++] = 0;
-                }
-                
-                while (p != &src[size]) {
-                    CRC(fcs, *p++);
-                }
-                ((uint32_t *)&src[size])[0] = htonl(fcs);
-                size += 4; /* FCS at end of packet */
-            } else size += 4;
+           memset(src + size, 0, pad); 
+            size += pad;
 
 #ifdef PCNET_DEBUG_MATCH
             PRINT_PKTHDR(buf);
 #endif
 
-            RMDLOAD(&rmd, PHYSADDR(s,crda));
-            /*if (!CSR_LAPPEN(s))*/
-                rmd.rmd1.stp = 1;
-
-#define PCNET_RECV_STORE() do {                                 \
-    int count = MIN(4096 - rmd.rmd1.bcnt,size);                 \
-    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr);     \
-    cpu_physical_memory_write(rbadr, src, count);               \
-    cpu_physical_memory_set_dirty(rbadr);                       \
-    cpu_physical_memory_set_dirty(rbadr+count);                 \
-    src += count; size -= count;                                \
-    rmd.rmd2.mcnt = count; rmd.rmd1.own = 0;                    \
-    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
-    pktcount++;                                                 \
-} while (0)
-
-            PCNET_RECV_STORE();
-            if ((size > 0) && CSR_NRDA(s)) {
-                target_phys_addr_t nrda = CSR_NRDA(s);
-                RMDLOAD(&rmd, PHYSADDR(s,nrda));
-                if (rmd.rmd1.own) {
-                    crda = nrda;
-                    PCNET_RECV_STORE();
-                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
-                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
-                        if (rmd.rmd1.own) {
-                            crda = nrda;
-                            PCNET_RECV_STORE();
-                        }
-                    }
-                }                
+           s->crmd.rmd1.stp = 1;
+           do {
+               int count = MIN(4096 - s->crmd.rmd1.bcnt,size);
+               target_phys_addr_t rbadr = PHYSADDR(s, s->crmd.rmd0.rbadr);
+               cpu_physical_memory_write(rbadr, src, count);
+               cpu_physical_memory_set_dirty(rbadr);
+               cpu_physical_memory_set_dirty(rbadr+count);
+               src += count; size -= count;
+               if (size > 0 && s->nrmd.rmd1.own) {
+                   RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
+                   crda = nrda;
+                   nrda = nnrda;
+                   s->crmd = s->nrmd;
+                   s->nrmd = s->nnrmd;
+                   s->nnrmd.rmd1.own = 0;
+               }
+               pktcount++;
+           } while (size > 0 && s->crmd.rmd1.own);
+
+            if (size == 0) {
+                s->crmd.rmd1.enp = 1;
+               s->crmd.rmd2.mcnt = packet_size;
+                s->crmd.rmd1.pam = !CSR_PROM(s) && is_padr;
+                s->crmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
+                s->crmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
+            } else {
+                s->crmd.rmd1.oflo = 1;
+                s->crmd.rmd1.buff = 1;
+                s->crmd.rmd1.err = 1;
             }
-
-#undef PCNET_RECV_STORE
-
-            RMDLOAD(&rmd, PHYSADDR(s,crda));
-            if (size == 0) {
-                rmd.rmd1.enp = 1;
-                rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
-                rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
-                rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
-            } else {
-                rmd.rmd1.oflo = 1;
-                rmd.rmd1.buff = 1;
-                rmd.rmd1.err = 1;
-            }
-            RMDSTORE(&rmd, PHYSADDR(s,crda));
+            RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
             s->csr[0] |= 0x0400;
+           s->crmd = s->nrmd;
+           s->nrmd = s->nnrmd;
+           s->nnrmd.rmd1.own = 0;
 
 #ifdef PCNET_DEBUG
             printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
                 CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
 #endif
 #ifdef PCNET_DEBUG_RMD
-            PRINT_RMD(&rmd);
+            PRINT_RMD(&s->crmd);
 #endif        
 
             while (pktcount--) {
@@ -551,80 +476,88 @@ static void pcnet_receive(void *opaque, 
 
 static void pcnet_transmit(PCNetState *s)
 {
-    target_phys_addr_t xmit_cxda = 0;
+    target_phys_addr_t start_addr = 0;
+    struct pcnet_TMD start_tmd;
     int count = CSR_XMTRL(s)-1;
-    s->xmit_pos = -1;
+    int xmit_pos = 0;
+    int len;
+
     
     if (!CSR_TXON(s)) {
         s->csr[0] &= ~0x0008;
         return;
     }
     
-    txagain:
-    if (pcnet_tdte_poll(s)) {
-        struct pcnet_TMD tmd;
-
-        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
+    while (pcnet_tdte_poll(s)) {
 
 #ifdef PCNET_DEBUG_TMD
         printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
-        PRINT_TMD(&tmd);
-#endif
-        if (tmd.tmd1.stp) {
-            s->xmit_pos = 0;                
-            if (!tmd.tmd1.enp) {
-                cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
-                        s->buffer, 4096 - tmd.tmd1.bcnt);
-                s->xmit_pos += 4096 - tmd.tmd1.bcnt;
-            } 
-            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
-        }
-        if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
-            cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
-                    s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
-            s->xmit_pos += 4096 - tmd.tmd1.bcnt;
-
-           tmd.tmd1.own = 0;
-           TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-
-#ifdef PCNET_DEBUG
-            printf("pcnet_transmit size=%d\n", s->xmit_pos);
-#endif            
-            if (CSR_LOOP(s))
-                pcnet_receive(s, s->buffer, s->xmit_pos);
-            else
-                qemu_send_packet(s->nd, s->buffer, s->xmit_pos);
-
-            s->csr[0] &= ~0x0008;   /* clear TDMD */
-            s->csr[4] |= 0x0004;    /* set TXSTRT */
-            s->xmit_pos = -1;
-        } else {
-           tmd.tmd1.own = 0;
-           TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-       }
-        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
-            s->csr[0] |= 0x0200;    /* set TINT */
-
-        if (CSR_XMTRC(s)<=1)
+        PRINT_TMD(&(s->tmd));
+#endif
+       len = 4096 - s->tmd.tmd1.bcnt;
+        if (CSR_XMTRC(s) <= 1)
             CSR_XMTRC(s) = CSR_XMTRL(s);
         else
             CSR_XMTRC(s)--;
-        if (count--)
-            goto txagain;
-
-    } else 
-    if (s->xmit_pos >= 0) {
-        struct pcnet_TMD tmd;
-        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));                
-        tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
-        tmd.tmd1.own = 0;
-        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
+
+       /* handle start followed by start */
+        if (s->tmd.tmd1.stp && start_addr) {
+           TMDSTORE(&start_tmd, start_addr);
+           start_addr = 0;
+           xmit_pos = 0;
+       }
+       if ((xmit_pos + len) < sizeof(s->tx_buffer)) {
+           cpu_physical_memory_read(PHYSADDR(s, s->tmd.tmd0.tbadr),
+                       s->tx_buffer + xmit_pos, len);
+           xmit_pos += len;
+       } else {
+           s->tmd.tmd2.buff = s->tmd.tmd2.uflo = s->tmd.tmd1.err = 1;
+           TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+           if (start_addr == PHYSADDR(s,CSR_CXDA(s)))
+               start_addr = 0;         /* don't clear own bit twice */
+           continue;
+       }
+        if (s->tmd.tmd1.stp) {
+           if (s->tmd.tmd1.enp) {
+               if (CSR_LOOP(s))
+                   pcnet_receive(s, s->tx_buffer, xmit_pos);
+               else
+                   qemu_send_packet(s->nd, s->tx_buffer, xmit_pos);
+
+               s->csr[4] |= 0x0008;    /* set TXSTRT */
+               TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+               xmit_pos = 0;
+               count--;
+           } else {
+               start_tmd = s->tmd;
+               start_addr = PHYSADDR(s,CSR_CXDA(s));
+           }
+        } else if (s->tmd.tmd1.enp) {
+           TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+           if (start_addr) {
+               TMDSTORE(&start_tmd, start_addr);
+           }
+           start_addr = 0;
+           xmit_pos = 0;
+           count--;
+
+        } else {
+           TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+       }
+        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && s->tmd.tmd1.ltint))
+            s->csr[0] |= 0x0200;    /* set TINT */
+
+        if (count <= 0)
+            break;
+
+    }
+    if (start_addr) {
+        start_tmd.tmd2.buff = start_tmd.tmd2.uflo = start_tmd.tmd1.err = 1;
+        TMDSTORE(&start_tmd, PHYSADDR(s,start_addr));
         s->csr[0] |= 0x0200;    /* set TINT */
         if (!CSR_DXSUFLO(s)) {
             s->csr[0] &= ~0x0010;
-        } else
-        if (count--)
-          goto txagain;
+        }
     }
 }
 
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/ioemu/hw/pcnet.h
--- a/tools/ioemu/hw/pcnet.h    Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/ioemu/hw/pcnet.h    Tue Mar 28 08:54:58 2006 -0700
@@ -177,6 +177,26 @@ struct pcnet_RMD {
     } rmd3;    
 };
 
+typedef struct PCNetState_st PCNetState;
+
+struct PCNetState_st {
+    PCIDevice dev;
+    NetDriverState *nd;
+    int mmio_io_addr, rap, isr, lnkst;
+    target_phys_addr_t rdra, tdra;
+    uint8_t prom[16];
+    uint16_t csr[128];
+    uint16_t bcr[32];
+    uint64_t timer;
+    int recv_pos;
+    uint8_t tx_buffer[2048];
+    uint8_t rx_buffer[2048];
+    struct pcnet_TMD tmd;
+    struct pcnet_RMD crmd;
+    struct pcnet_RMD nrmd;
+    struct pcnet_RMD nnrmd;
+};
+
 
 #define PRINT_TMD(T) printf(    \
         "TMD0 : TBADR=0x%08x\n" \
@@ -230,18 +250,17 @@ static inline void pcnet_tmd_load(PCNetS
         cpu_physical_memory_read(addr+4, (void *)&tmd->tmd1, 4);
         cpu_physical_memory_read(addr, (void *)&tmd->tmd0, 4);
     } else {
-        uint32_t xda[4];
-        cpu_physical_memory_read(addr,
-                (void *)&xda[0], sizeof(xda));
-        ((uint32_t *)tmd)[0] = xda[2];
-        ((uint32_t *)tmd)[1] = xda[1];
-        ((uint32_t *)tmd)[2] = xda[0];
-        ((uint32_t *)tmd)[3] = xda[3];
+        uint32_t xda[2];
+        cpu_physical_memory_read(addr+4, (void *)&xda[0], sizeof(xda));
+        ((uint32_t *)tmd)[0] = xda[1];
+        ((uint32_t *)tmd)[1] = xda[0];
+        ((uint32_t *)tmd)[2] = 0;
     }
 }
 
 static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, 
target_phys_addr_t addr)
 {
+    tmd->tmd1.own = 0;
     cpu_physical_memory_set_dirty(addr);
     if (!BCR_SWSTYLE(s)) {
         uint16_t xda[4];
@@ -259,13 +278,10 @@ static inline void pcnet_tmd_store(PCNet
             cpu_physical_memory_write(addr+8, (void *)&tmd->tmd2, 4);
             cpu_physical_memory_write(addr+4, (void *)&tmd->tmd1, 4);
         } else {
-            uint32_t xda[4];
+            uint32_t xda[2];
             xda[0] = ((uint32_t *)tmd)[2];
             xda[1] = ((uint32_t *)tmd)[1];
-            xda[2] = ((uint32_t *)tmd)[0];
-            xda[3] = ((uint32_t *)tmd)[3];
-            cpu_physical_memory_write(addr,
-                    (void *)&xda[0], sizeof(xda));
+            cpu_physical_memory_write(addr, (void *)&xda[0], sizeof(xda));
         }
         cpu_physical_memory_set_dirty(addr+15);
     }
@@ -286,22 +302,21 @@ static inline void pcnet_rmd_load(PCNetS
     }
     else
     if (BCR_SWSTYLE(s) != 3) {
-        rmd->rmd2.zeros = 0;
+        ((uint32_t *)rmd)[2] = 0;
         cpu_physical_memory_read(addr+4, (void *)&rmd->rmd1, 4);
         cpu_physical_memory_read(addr, (void *)&rmd->rmd0, 4);
     } else {
-        uint32_t rda[4];
-        cpu_physical_memory_read(addr,
-                (void *)&rda[0], sizeof(rda));
-        ((uint32_t *)rmd)[0] = rda[2];
-        ((uint32_t *)rmd)[1] = rda[1];
-        ((uint32_t *)rmd)[2] = rda[0];
-        ((uint32_t *)rmd)[3] = rda[3];
+        uint32_t rda[2];
+        cpu_physical_memory_read(addr+4, (void *)&rda[0], sizeof(rda));
+        ((uint32_t *)rmd)[0] = rda[1];
+        ((uint32_t *)rmd)[1] = rda[0];
+        ((uint32_t *)rmd)[2] = 0;
     }
 }
 
 static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, 
target_phys_addr_t addr)
 {
+    rmd->rmd1.own = 0;
     cpu_physical_memory_set_dirty(addr);
     if (!BCR_SWSTYLE(s)) {
         uint16_t rda[4];                        \
@@ -319,13 +334,10 @@ static inline void pcnet_rmd_store(PCNet
             cpu_physical_memory_write(addr+8, (void *)&rmd->rmd2, 4);
             cpu_physical_memory_write(addr+4, (void *)&rmd->rmd1, 4);
         } else {
-            uint32_t rda[4];
+            uint32_t rda[2];
             rda[0] = ((uint32_t *)rmd)[2];
             rda[1] = ((uint32_t *)rmd)[1];
-            rda[2] = ((uint32_t *)rmd)[0];
-            rda[3] = ((uint32_t *)rmd)[3];
-            cpu_physical_memory_write(addr,
-                    (void *)&rda[0], sizeof(rda));
+            cpu_physical_memory_write(addr, (void *)&rda[0], sizeof(rda));
         }
         cpu_physical_memory_set_dirty(addr+15);
     }
@@ -340,79 +352,16 @@ static inline void pcnet_rmd_store(PCNet
 
 #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
 
-#if 1
-
-#define CHECK_RMD(ADDR,RES) do {                \
-    struct pcnet_RMD rmd;                       \
-    RMDLOAD(&rmd,(ADDR));                       \
-    (RES) |= (rmd.rmd1.ones != 15);             \
+#define CHECK_RMD(RMD,ADDR,RES) do {            \
+    RMDLOAD((RMD),(ADDR));                      \
+    (RES) |= ((RMD)->rmd1.ones != 15);          \
 } while (0)
 
-#define CHECK_TMD(ADDR,RES) do {                \
-    struct pcnet_TMD tmd;                       \
-    TMDLOAD(&tmd,(ADDR));                       \
-    (RES) |= (tmd.tmd1.ones != 15);             \
+#define CHECK_TMD(ADDR,RES) do {            \
+    TMDLOAD(&(s->tmd),(ADDR));                       \
+    (RES) |= (s->tmd.tmd1.ones != 15);             \
 } while (0)
 
-#else
-
-#define CHECK_RMD(ADDR,RES) do {                \
-    switch (BCR_SWSTYLE(s)) {                   \
-    case 0x00:                                  \
-        do {                                    \
-            uint16_t rda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&rda[0], sizeof(rda));  \
-            (RES) |= (rda[2] & 0xf000)!=0xf000; \
-            (RES) |= (rda[3] & 0xf000)!=0x0000; \
-        } while (0);                            \
-        break;                                  \
-    case 0x01:                                  \
-    case 0x02:                                  \
-        do {                                    \
-            uint32_t rda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&rda[0], sizeof(rda)); \
-            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
-            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
-        } while (0);                            \
-        break;                                  \
-    case 0x03:                                  \
-        do {                                    \
-            uint32_t rda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&rda[0], sizeof(rda)); \
-            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
-            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
-        } while (0);                            \
-        break;                                  \
-    }                                           \
-} while (0)
-
-#define CHECK_TMD(ADDR,RES) do {                \
-    switch (BCR_SWSTYLE(s)) {                   \
-    case 0x00:                                  \
-        do {                                    \
-            uint16_t xda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&xda[0], sizeof(xda));  \
-            (RES) |= (xda[2] & 0xf000)!=0xf000;\
-        } while (0);                            \
-        break;                                  \
-    case 0x01:                                  \
-    case 0x02:                                  \
-    case 0x03:                                  \
-        do {                                    \
-            uint32_t xda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&xda[0], sizeof(xda));  \
-            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
-        } while (0);                            \
-        break;                                  \
-    }                                           \
-} while (0)
-
-#endif
 
 #define PRINT_PKTHDR(BUF) do {                  \
     struct ether_header *hdr = (void *)(BUF);   \
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/Makefile
--- a/tools/libxc/Makefile      Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/Makefile      Tue Mar 28 08:54:58 2006 -0700
@@ -21,13 +21,9 @@ SRCS       += xc_sedf.c
 SRCS       += xc_sedf.c
 SRCS       += xc_tbuf.c
 
-ifeq ($(XEN_TARGET_ARCH),x86_32)
+ifeq ($(patsubst x86%,x86,$(XEN_TARGET_ARCH)),x86)
 SRCS       += xc_ptrace.c
 SRCS       += xc_ptrace_core.c
-SRCS       += xc_pagetab.c
-endif
-
-ifeq ($(XEN_TARGET_ARCH),x86_64)
 SRCS       += xc_pagetab.c
 endif
 
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_core.c     Tue Mar 28 08:54:58 2006 -0700
@@ -3,7 +3,6 @@
 #include "xc_elf.h"
 #include <stdlib.h>
 #include <unistd.h>
-#include <zlib.h>
 
 /* number of pages to write at a time */
 #define DUMP_INCREMENT (4 * 1024)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_private.c  Tue Mar 28 08:54:58 2006 -0700
@@ -4,7 +4,6 @@
  * Helper functions for the rest of the library.
  */
 
-#include <zlib.h>
 #include "xc_private.h"
 #include <xen/memory.h>
 
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_ptrace.c   Tue Mar 28 08:54:58 2006 -0700
@@ -38,9 +38,6 @@ static char *ptrace_names[] = {
 };
 #endif
 
-/* XXX application state */
-static long                     nr_pages = 0;
-static unsigned long           *page_array = NULL;
 static int                      current_domid = -1;
 static int                      current_isfile;
 
@@ -196,6 +193,60 @@ map_domain_va_pae(
     return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
 }
 
+#ifdef __x86_64__
+static void *
+map_domain_va(
+    int xc_handle,
+    int cpu,
+    void *guest_va,
+    int perm)
+{
+    unsigned long l3p, l2p, l1p, p, va = (unsigned long)guest_va;
+    uint64_t *l4, *l3, *l2, *l1;
+    static void *v;
+
+    if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
+        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
+
+    if (fetch_regs(xc_handle, cpu, NULL))
+        return NULL;
+
+    l4 = xc_map_foreign_range(
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
+    if ( l4 == NULL )
+        return NULL;
+
+    l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
+    l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l3p);
+    if ( l3 == NULL )
+        return NULL;
+
+    l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
+    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
+    if ( l2 == NULL )
+        return NULL;
+
+    l1p = l2[l2_table_offset(va)] >> PAGE_SHIFT;
+    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+    if ( l1 == NULL )
+        return NULL;
+
+    p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
+    if ( v != NULL )
+        munmap(v, PAGE_SIZE);
+    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+    if ( v == NULL )
+        return NULL;
+
+    return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
+}
+#endif
+
+#ifdef __i386__
+/* XXX application state */
+static long                     nr_pages = 0;
+static unsigned long           *page_array = NULL;
+
 static void *
 map_domain_va(
     int xc_handle,
@@ -216,15 +267,18 @@ map_domain_va(
     static unsigned long  page_phys[MAX_VIRT_CPUS];
     static unsigned long *page_virt[MAX_VIRT_CPUS];    
     static int            prev_perm[MAX_VIRT_CPUS];
-    static enum { MODE_UNKNOWN, MODE_32, MODE_PAE } mode;
+    static enum { MODE_UNKNOWN, MODE_32, MODE_PAE, MODE_64 } mode;
 
     if ( mode == MODE_UNKNOWN )
     {
         xen_capabilities_info_t caps;
         (void)xc_version(xc_handle, XENVER_capabilities, caps);
-        mode = MODE_32;
-        if ( strstr(caps, "_x86_32p") )
+        if ( strstr(caps, "-x86_64") )
+            mode = MODE_64;
+        else if ( strstr(caps, "-x86_32p") )
             mode = MODE_PAE;
+        else if ( strstr(caps, "-x86_32") ) 
+            mode = MODE_32;
     }
 
     if ( mode == MODE_PAE )
@@ -303,6 +357,8 @@ map_domain_va(
 
     return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
 }
+
+#endif
 
 static int 
 __xc_waitdomain(
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h   Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_ptrace.h   Tue Mar 28 08:54:58 2006 -0700
@@ -9,6 +9,96 @@
 #define BSD_PAGE_MASK (PAGE_SIZE-1)
 #define PDRSHIFT        22
 #define PSL_T  0x00000100 /* trace enable bit */
+
+#ifdef __x86_64__
+struct gdb_regs
+{
+  unsigned long r15;
+  unsigned long r14;
+  unsigned long r13;
+  unsigned long r12;
+  unsigned long rbp;
+  unsigned long rbx;
+  unsigned long r11;
+  unsigned long r10;
+  unsigned long r9;
+  unsigned long r8;
+  unsigned long rax;
+  unsigned long rcx;
+  unsigned long rdx;
+  unsigned long rsi;
+  unsigned long rdi;
+  unsigned long orig_rax;
+  unsigned long rip;
+  unsigned long xcs;
+  unsigned long eflags;
+  unsigned long rsp;
+  unsigned long xss;
+  unsigned long fs_base;
+  unsigned long gs_base;
+  unsigned long xds;
+  unsigned long xes;
+  unsigned long xfs;
+  unsigned long xgs;
+};
+
+#define SET_PT_REGS(pt, xc)                     \
+{                                               \
+    pt.r8 = xc.r8;                              \
+    pt.r9 = xc.r9;                              \
+    pt.r10 = xc.r10;                            \
+    pt.r11 = xc.r11;                            \
+    pt.r12 = xc.r12;                            \
+    pt.r13 = xc.r13;                            \
+    pt.r14 = xc.r14;                            \
+    pt.r15 = xc.r15;                            \
+    pt.rbx = xc.rbx;                            \
+    pt.rcx = xc.rcx;                            \
+    pt.rdx = xc.rdx;                            \
+    pt.rsi = xc.rsi;                            \
+    pt.rdi = xc.rdi;                            \
+    pt.rbp = xc.rbp;                            \
+    pt.rax = xc.rax;                            \
+    pt.rip = xc.rip;                            \
+    pt.xcs = xc.cs;                             \
+    pt.eflags = xc.eflags;                      \
+    pt.rsp = xc.rsp;                            \
+    pt.xss = xc.ss;                             \
+    pt.xes = xc.es;                             \
+    pt.xds = xc.ds;                             \
+    pt.xfs = xc.fs;                             \
+    pt.xgs = xc.gs;                             \
+}
+
+#define SET_XC_REGS(pt, xc)                     \
+{                                               \
+    xc.r8 = pt->r8;                             \
+    xc.r9 = pt->r9;                             \
+    xc.r10 = pt->r10;                           \
+    xc.r11 = pt->r11;                           \
+    xc.r12 = pt->r12;                           \
+    xc.r13 = pt->r13;                           \
+    xc.r14 = pt->r14;                           \
+    xc.r15 = pt->r15;                           \
+    xc.rbx = pt->rbx;                           \
+    xc.rcx = pt->rcx;                           \
+    xc.rdx = pt->rdx;                           \
+    xc.rsi = pt->rsi;                           \
+    xc.rdi = pt->rdi;                           \
+    xc.rbp = pt->rbp;                           \
+    xc.rax = pt->rax;                           \
+    xc.rip = pt->rip;                           \
+    xc.cs = pt->xcs;                            \
+    xc.eflags = pt->eflags;                     \
+    xc.rsp = pt->rsp;                           \
+    xc.ss = pt->xss;                            \
+    xc.es = pt->xes;                            \
+    xc.ds = pt->xds;                            \
+    xc.fs = pt->xfs;                            \
+    xc.gs = pt->xgs;                            \
+}
+
+#elif __i386__
 
 struct gdb_regs {
     long ebx; /* 0 */
@@ -30,8 +120,6 @@ struct gdb_regs {
     int  xss;    /* 64 */
 };
 
-
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
 #define SET_PT_REGS(pt, xc)                     \
 {                                               \
     pt.ebx = xc.ebx;                            \
@@ -71,7 +159,9 @@ struct gdb_regs {
     xc.fs = pt->xfs;                            \
     xc.gs = pt->xgs;                            \
 }
+#endif
 
+#define printval(x) printf("%s = %lx\n", #x, (long)x);
 #define vtopdi(va) ((va) >> PDRSHIFT)
 #define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
 #endif
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendClient.py       Tue Mar 28 08:54:58 2006 -0700
@@ -14,403 +14,15 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
 #============================================================================
 
-"""Client API for the HTTP interface on xend.
-Callable as a script - see main().
-Supports inet or unix connection to xend.
+from xen.util.xmlrpclib2 import ServerProxy
 
-This API is the 'control-plane' for xend.
-The 'data-plane' is done separately.
-"""
-import os
-import sys
-import types
+XML_RPC_SOCKET = "/var/run/xend-xmlrpc.sock"
 
-import sxp
-import PrettyPrint
-from XendProtocol import HttpXendClientProtocol, \
-                         UnixXendClientProtocol, \
-                         XendError
+ERROR_INTERNAL = 1
+ERROR_GENERIC = 2
+ERROR_INVALID_DOMAIN = 3
 
-def fileof(val):
-    """Converter for passing configs or other 'large' data.
-    Handles lists, files directly.
-    Assumes a string is a file name and passes its contents.
-    """
-    if isinstance(val, types.ListType):
-        return sxp.to_string(val)
-    if isinstance(val, types.StringType):
-        return file(val)
-    if hasattr(val, 'readlines'):
-        return val
-    raise XendError('cannot convert value')
-
-class URL:
-    """A URL.
-    """
-
-    def __init__(self, proto='http', host='localhost', port=None, path='', 
query=None, frag=None):
-        self.proto = proto
-        self.host = host
-        if port: port = int(port)
-        self.port = port
-        self.path = path
-        self.query = query
-        self.frag = frag
-
-    def url(self):
-        """Get the full URL string including protocol, location and the full 
path.
-        """
-        return self.proto + '://' + self.location() + self.fullpath()
-
-    def location(self):
-        """Get the location part of the URL, including host and port, if 
present.
-        """
-        if self.port:
-            return self.host + ':' + str(self.port)
-        else:
-            return self.host
-
-    def fullpath(self):
-        """Get the full path part of the URL, including query and fragment if 
present.
-        """
-        u = [ self.path ]
-        if self.query:
-            u.append('?')
-            u.append(self.query)
-        if self.frag:
-            u.append('#')
-            u.append(self.frag)
-        return ''.join(u)
-
-    def relative(self, path='', query=None, frag=None):
-        """Create a URL relative to this one.
-        """
-        return URL(proto=self.proto,
-                   host=self.host,
-                   port=self.port,
-                   path=self.path + path,
-                   query=query,
-                   frag=frag)
-
-class Xend:
-    """Client interface to Xend.
-    """
-
-    """Default location of the xend server."""
-    SRV_DEFAULT = "localhost:8000"
-
-    """Environment variable to set the location of xend."""
-    SRV_VAR = "XEND"
-
-    """Default path to the xend root on the server."""
-    ROOT_DEFAULT = "/xend/"
-
-    """Environment variable to set the xend root path."""
-    ROOT_VAR = "XEND_ROOT"
-
-    def __init__(self, client=None, srv=None, root=None):
-        """Create a xend client interface.
-        If the client protocol is not specified, the default
-        is to use a synchronous protocol.
-
-        @param client:  client protocol to use
-        @param srv:     server host, and optional port (format host:port)
-        @param root:    xend root path on the server
-        """
-        if client is None:
-            client = HttpXendClientProtocol()
-        self.client = client
-        self.bind(srv, root)
-
-    def default_server(self):
-        """Get the default location of the xend server.
-        """
-        return os.getenv(self.SRV_VAR, self.SRV_DEFAULT)
-
-    def default_root(self):
-        """Get the default root path on the xend server.
-        """
-        return os.getenv(self.ROOT_VAR, self.ROOT_DEFAULT)
-
-    def bind(self, srv=None, root=None):
-        """Bind to a given server.
-
-        @param srv:  server location (host:port)
-        @param root: xend root path on the server
-        """
-        if srv is None: srv = self.default_server()
-        if root is None: root = self.default_root()
-        if not root.endswith('/'): root += '/'
-        (host, port) = srv.split(':', 1)
-        self.url = URL(host=host, port=port, path=root)
-
-    def xendGet(self, url, args=None):
-        return self.client.xendGet(url, args)
-
-    def xendPost(self, url, data):
-        return self.client.xendPost(url, data)
-
-    def nodeurl(self, id=''):
-        return self.url.relative('node/' + str(id))
-
-    def domainurl(self, id=''):
-        return self.url.relative('domain/' + str(id))
-
-    def deviceurl(self, id=''):
-        return self.url.relative('device/' + str(id))
-
-    def vneturl(self, id=''):
-        return self.url.relative('vnet/' + str(id))
-
-    def xend(self):
-        return self.xendGet(self.url)
-
-    def xend_node(self):
-        return self.xendGet(self.nodeurl())
-        
-    def xend_node_shutdown(self):
-        return self.xendPost(self.nodeurl(),
-                             {'op'      : 'shutdown'})
-                
-    def xend_node_restart(self):
-        return self.xendPost(self.nodeurl(),
-                             {'op'      : 'reboot'})
-
-    def xend_node_get_dmesg(self):
-            return self.xendGet(self.nodeurl('dmesg'))
-
-    def xend_node_clear_dmesg(self):
-        return self.xendPost(self.nodeurl('dmesg'),
-                             {'op' : 'clear' } )
-
-    def xend_node_log(self):
-        return self.xendGet(self.nodeurl('log'))
-
-    def xend_node_cpu_bvt_slice_set(self, ctx_allow):
-        return self.xendPost(self.nodeurl(),
-                             {'op'      : 'cpu_bvt_slice_set',
-                              'ctx_allow' : ctx_allow })
-
-    def xend_domains(self):
-        return self.xendGet(self.domainurl())
-
-    def xend_list_domains(self, detail = True):
-        return self.xendGet(self.domainurl(),
-                            {'detail': detail and '1' or '0'})
-
-    def xend_domain_vcpuinfo(self, dom):
-        return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
-
-    def xend_domain_create(self, conf):
-        return self.xendPost(self.domainurl(),
-                             {'op'      : 'create',
-                              'config'  : fileof(conf) })
-
-    def xend_domain_restore(self, filename):
-        return self.xendPost(self.domainurl(),
-                             {'op'      : 'restore',
-                              'file'    : filename })
-
-    def xend_domain_configure(self, id, conf):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'configure',
-                              'config'  : fileof(conf) })
-
-    def xend_domain(self, id):
-        return self.xendGet(self.domainurl(id))
-
-    def xend_domain_wait_for_devices(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'wait_for_devices' })
-
-    def xend_domain_unpause(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'unpause' })
-
-    def xend_domain_pause(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'pause' })
-
-    def xend_domain_rename(self, id, name):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'rename',
-                              'name'    : name})
-
-    def xend_domain_shutdown(self, id, reason):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'shutdown',
-                              'reason'  : reason})
-
-    def xend_domain_sysrq(self, id, key):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'sysrq',
-                              'key'     : key})
-
-    def xend_domain_destroy(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'destroy' })
-
-    def xend_domain_save(self, id, filename):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'save',
-                              'file'    : filename })
-
-    def xend_domain_migrate(self, id, dst, live=0, resource=0, port=0):
-        return self.xendPost(self.domainurl(id),
-                             {'op'         : 'migrate',
-                              'destination': dst,
-                              'live'       : live,
-                              'resource'   : resource,
-                              'port'       : port })
-
-    def xend_domain_pincpu(self, id, vcpu, cpumap):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'pincpu',
-                              'vcpu'    : vcpu,
-                              'cpumap'  : str(cpumap) })
-
-    def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, 
warpu):
-        return self.xendPost(self.domainurl(id),
-                             {'op'       : 'cpu_bvt_set',
-                              'mcuadv'   : mcuadv,
-                              'warpback' : warpback,
-                              'warpvalue': warpvalue,
-                              'warpl'    : warpl,
-                              'warpu'    : warpu })
-
-    def xend_domain_cpu_sedf_get(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op' : 'cpu_sedf_get'})
-
-    def xend_domain_cpu_sedf_set(self, id, period, slice, latency, extratime, 
weight):
-        return self.xendPost(self.domainurl(id),
-                             {'op'        : 'cpu_sedf_set',
-                              'period'    : period,
-                              'slice'     : slice,
-                             'latency'   : latency,
-                             'extratime' : extratime,
-                             'weight'    : weight })
-
-    def xend_domain_maxmem_set(self, id, memory):
-        return self.xendPost(self.domainurl(id),
-                             { 'op'      : 'maxmem_set',
-                               'memory'  : memory })
-
-    def xend_domain_mem_target_set(self, id, mem_target):
-        val = self.xendPost(self.domainurl(id),
-                            {'op'        : 'mem_target_set',
-                             'target'    : mem_target })
-        return val
-
-    def xend_domain_set_vcpus(self, dom, vcpus):
-        return self.xendPost(self.domainurl(dom),
-                            {'op'    : 'set_vcpus',
-                             'vcpus' : vcpus })
-
-    def xend_domain_devices(self, id, type):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'devices',
-                              'type'    : type })
-
-    def xend_domain_device_create(self, id, config):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_create',
-                              'config'  : fileof(config) })
-
-    def xend_domain_device_refresh(self, id, type, dev):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_refresh',
-                              'type'    : type,
-                              'dev'     : dev })
-
-    def xend_domain_device_destroy(self, id, type, dev):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_destroy',
-                              'type'    : type,
-                              'dev'     : dev })
-
-    def xend_domain_device_configure(self, id, config, dev):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_configure',
-                              'dev'     : dev,
-                              'config'  : fileof(config) })
-
-    def xend_vnets(self):
-        return self.xendGet(self.vneturl())
-
-    def xend_vnet_create(self, conf):
-        return self.xendPost(self.vneturl(),
-                             {'op'      : 'create',
-                              'config'  : fileof(conf) })
-
-    def xend_vnet(self, id):
-        return self.xendGet(self.vneturl(id))
-
-    def xend_vnet_delete(self, id):
-        return self.xendPost(self.vneturl(id),
-                              {'op'     : 'delete' })
-
-def getHttpServer(srv=None):
-    """Create and return a xend client.
-    """
-    return Xend(srv=srv, client=HttpXendClientProtocol())
-
-def getUnixServer(srv=None):
-    """Create and return a unix-domain xend client.
-    """
-    return Xend(client=UnixXendClientProtocol(srv))
-
-def xendmain(srv, fn, args, unix=False):
-    if unix:
-        xend = getUnixServer(srv)
-    else:
-        xend = getHttpServer(srv)
-    xend.rc = 0
-    try:
-        v = getattr(xend, fn)(*args)
-        PrettyPrint.prettyprint(v)
-        return 0
-    except XendError, err:
-        print 'ERROR:', err
-        return 1
-
-def main(argv):
-    """Call an API function:
-
-    python XendClient.py fn args...
-
-    The leading 'xend_' on the function can be omitted.
-    Example:
-
-python XendClient.py domains
-    (0 8)
-python XendClient.py domain 0
-    (domain (id 0) (name Domain-0) (memory 128))
-    """
-    from getopt import getopt
-    short_options = 'x:au:d'
-    long_options = ['xend=', 'unix=', 'debug']
-    (options, args) = getopt(argv[1:], short_options, long_options)
-    srv = None
-    unix = 1
-    for k, v in options:
-        if k in ['-x', '--xend']:
-            srv = v
-        elif k in ['-u', '--unix']:
-            unix = int(v)
-    if len(args):
-        fn = args[0]
-        args = args[1:]
-    else:
-        fn = 'xend'
-        args = []
-    if not fn.startswith('xend'):
-        fn = 'xend_' + fn
-    sys.exit(xendmain(srv, fn, args, unix=unix))
-
-if __name__ == "__main__":
-    main(sys.argv)
-else:    
-    server = getUnixServer()
+server = ServerProxy('httpu:///var/run/xend-xmlrpc.sock')
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py       Tue Mar 28 08:54:58 2006 -0700
@@ -81,7 +81,8 @@ class XendDomain:
             # that we're sure that we haven't missed any releases, but inside
             # the domains_lock, as we don't want the watch to fire until after
             # the refresh call has completed.
-            xswatch("@releaseDomain", self.onReleaseDomain)
+            xswatch("@introduceDomain", self.onChangeDomain)
+            xswatch("@releaseDomain",   self.onChangeDomain)
             
             self.refresh(True)
         finally:
@@ -121,7 +122,7 @@ class XendDomain:
 
     ## private:
 
-    def onReleaseDomain(self, _):
+    def onChangeDomain(self, _):
         self.domains_lock.acquire()
         try:
             self.refresh()
@@ -355,7 +356,7 @@ class XendDomain:
     def domain_unpause(self, domid):
         """Unpause domain execution."""
         try:
-            dominfo = self.domain_lookup(domid)
+            dominfo = self.domain_lookup_by_name_or_id_nr(domid)
             log.info("Domain %s (%d) unpaused.", dominfo.getName(),
                      dominfo.getDomid())
             return dominfo.unpause()
@@ -366,7 +367,7 @@ class XendDomain:
     def domain_pause(self, domid):
         """Pause domain execution."""
         try:
-            dominfo = self.domain_lookup(domid)
+            dominfo = self.domain_lookup_by_name_or_id_nr(domid)
             log.info("Domain %s (%d) paused.", dominfo.getName(),
                      dominfo.getDomid())
             return dominfo.pause()
@@ -377,10 +378,10 @@ class XendDomain:
     def domain_destroy(self, domid):
         """Terminate domain immediately."""
 
-        if domid == PRIV_DOMAIN:
-            raise XendError("Cannot destroy privileged domain %i" % domid)
-        
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+       if dominfo and dominfo.getDomid() == PRIV_DOMAIN:
+            raise XendError("Cannot destroy privileged domain %s" % domid)
+
         if dominfo:
             val = dominfo.destroy()
         else:
@@ -393,7 +394,7 @@ class XendDomain:
     def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
         """Start domain migration."""
 
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
 
         if dominfo.getDomid() == PRIV_DOMAIN:
             raise XendError("Cannot migrate privileged domain %i" % domid)
@@ -418,7 +419,7 @@ class XendDomain:
         """
 
         try:
-            dominfo = self.domain_lookup(domid)
+            dominfo = self.domain_lookup_by_name_or_id_nr(domid)
 
             if dominfo.getDomid() == PRIV_DOMAIN:
                 raise XendError("Cannot save privileged domain %i" % domid)
@@ -438,7 +439,7 @@ class XendDomain:
 
         @param cpumap:  string repr of list of usable cpus
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         # convert cpumap string into a list of ints
         cpumap = map(lambda x: int(x),
                      cpumap.replace("[", "").replace("]", "").split(","))
@@ -451,7 +452,7 @@ class XendDomain:
                            warpu):
         """Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             return xc.bvtsched_domain_set(dom=dominfo.getDomid(),
                                           mcuadv=mcuadv,
@@ -464,7 +465,7 @@ class XendDomain:
     def domain_cpu_bvt_get(self, domid):
         """Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             return xc.bvtsched_domain_get(dominfo.getDomid())
         except Exception, ex:
@@ -475,7 +476,7 @@ class XendDomain:
                             weight):
         """Set Simple EDF scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             return xc.sedf_domain_set(dominfo.getDomid(), period, slice_,
                                       latency, extratime, weight)
@@ -485,7 +486,7 @@ class XendDomain:
     def domain_cpu_sedf_get(self, domid):
         """Get Simple EDF scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             
             sedf_info = xc.sedf_domain_get(dominfo.getDomid())
@@ -507,7 +508,7 @@ class XendDomain:
         @param mem: memory limit (in MiB)
         @return: 0 on success, -1 on error
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         maxmem = int(mem) * 1024
         try:
             return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
@@ -521,7 +522,7 @@ class XendDomain:
         @param last: last IO port
         @return: 0 on success, -1 on error
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         nr_ports = last - first + 1
         try:
             return xc.domain_ioport_permission(dominfo.getDomid(),
@@ -538,7 +539,7 @@ class XendDomain:
         @param last: last IO port
         @return: 0 on success, -1 on error
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         nr_ports = last - first + 1
         try:
             return xc.domain_ioport_permission(dominfo.getDomid(),
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py        Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendError.py        Tue Mar 28 08:54:58 2006 -0700
@@ -15,9 +15,18 @@
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
 #============================================================================
 
-class XendError(ValueError):
+from xmlrpclib import Fault
+
+import XendClient
+
+class XendInvalidDomain(Fault):
+    def __init__(self, value):
+        Fault.__init__(self, XendClient.ERROR_INVALID_DOMAIN, value)
+
+class XendError(Fault):
     
     def __init__(self, value):
+        Fault.__init__(self, XendClient.ERROR_GENERIC, value)
         self.value = value
 
     def __str__(self):
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendRoot.py Tue Mar 28 08:54:58 2006 -0700
@@ -57,8 +57,13 @@ class XendRoot:
     """Default level of information to be logged."""
     loglevel_default = 'DEBUG'
 
-    """Default for the flag indicating whether xend should run an http 
server."""
+    """Default for the flag indicating whether xend should run an http server
+    (deprecated)."""
     xend_http_server_default = 'no'
+
+    xend_tcp_xmlrpc_server_default = 'no'
+
+    xend_unix_xmlrpc_server_default = 'yes'
 
     """Default interface address xend listens at. """
     xend_address_default      = ''
@@ -77,8 +82,9 @@ class XendRoot:
 
     xend_relocation_hosts_allow_default = ''
 
-    """Default for the flag indicating whether xend should run a unix-domain 
server."""
-    xend_unix_server_default = 'yes'
+    """Default for the flag indicating whether xend should run a unix-domain
+    server (deprecated)."""
+    xend_unix_server_default = 'no'
 
     """Default path the unix-domain server listens at."""
     xend_unix_path_default = '/var/lib/xend/xend-socket'
@@ -180,6 +186,12 @@ class XendRoot:
         """
         return self.get_config_bool("xend-http-server", 
self.xend_http_server_default)
 
+    def get_xend_tcp_xmlrpc_server(self):
+        return self.get_config_bool("xend-tcp-xmlrpc-server", 
self.xend_tcp_xmlrpc_server_default)
+
+    def get_xend_unix_xmlrpc_server(self):
+        return self.get_config_bool("xend-unix-xmlrpc-server", 
self.xend_unix_xmlrpc_server_default)
+
     def get_xend_relocation_server(self):
         """Get the flag indicating whether xend should run a relocation server.
         """
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/server/SrvServer.py Tue Mar 28 08:54:58 2006 -0700
@@ -52,6 +52,7 @@ from xen.web.SrvDir import SrvDir
 from xen.web.SrvDir import SrvDir
 
 from SrvRoot import SrvRoot
+from XMLRPCServer import XMLRPCServer
 
 
 xroot = XendRoot.instance()
@@ -114,4 +115,10 @@ def create():
         path = xroot.get_xend_unix_path()
         log.info('unix path=' + path)
         servers.add(UnixHttpServer(root, path))
+
+    if xroot.get_xend_tcp_xmlrpc_server():
+        servers.add(XMLRPCServer(True))
+
+    if xroot.get_xend_unix_xmlrpc_server():
+        servers.add(XMLRPCServer())
     return servers
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/server/pciif.py     Tue Mar 28 08:54:58 2006 -0700
@@ -118,10 +118,12 @@ class PciController(DevController):
                     "parse it's resources - %s"+str(e))
 
         if dev.driver!='pciback':
-            raise VmError(("pci: PCI Backend does not own device "+
-                    "%s\n"+
-                    "See the pciback.hide kernel "+
-                    "command-line parameter")%(dev.name))
+            raise VmError(("pci: PCI Backend does not own device "+ \
+                    "%s\n"+ \
+                    "See the pciback.hide kernel "+ \
+                    "command-line parameter or\n"+ \
+                    "bind your slot/device to the PCI backend using sysfs" \
+                    )%(dev.name))
 
         for (start, size) in dev.ioports:
             log.debug('pci: enabling ioport 0x%x/0x%x'%(start,size))
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/create.py     Tue Mar 28 08:54:58 2006 -0700
@@ -30,7 +30,7 @@ import re
 
 from xen.xend import sxp
 from xen.xend import PrettyPrint
-from xen.xend.XendClient import server, XendError
+from xen.xend.XendClient import server
 from xen.xend.XendBootloader import bootloader
 from xen.util import blkif
 
@@ -813,8 +813,8 @@ def make_domain(opts, config):
     """
 
     try:
-        dominfo = server.xend_domain_create(config)
-    except XendError, ex:
+        dominfo = server.xend.domain.create(config)
+    except Exception, ex:
         import signal
         if vncpid:
             os.kill(vncpid, signal.SIGKILL)
@@ -822,13 +822,17 @@ def make_domain(opts, config):
 
     dom = sxp.child_value(dominfo, 'name')
 
-    if server.xend_domain_wait_for_devices(dom) < 0:
-        server.xend_domain_destroy(dom)
+    try:
+        server.xend.domain.waitForDevices(dom)
+    except:
+        server.xend.domain.destroy(dom)
         err("Device creation failed for domain %s" % dom)
 
     if not opts.vals.paused:
-        if server.xend_domain_unpause(dom) < 0:
-            server.xend_domain_destroy(dom)
+        try:
+            server.xend.domain.unpause(dom)
+        except:
+            server.xend.domain.destroy(dom)
             err("Failed to unpause domain %s" % dom)
     opts.info("Started domain %s" % (dom))
     return int(sxp.child_value(dominfo, 'domid'))
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/main.py       Tue Mar 28 08:54:58 2006 -0700
@@ -1,6 +1,6 @@
 # (C) Copyright IBM Corp. 2005
 # Copyright (C) 2004 Mike Wray
-# Copyright (c) 2005 XenSource Ltd
+# Copyright (c) 2005-2006 XenSource Ltd.
 #
 # Authors:
 #     Sean Dague <sean at dague dot net>
@@ -29,8 +29,8 @@ import socket
 import socket
 import warnings
 warnings.filterwarnings('ignore', category=FutureWarning)
-
-import xen.xend.XendError
+import xmlrpclib
+
 import xen.xend.XendProtocol
 
 from xen.xend import PrettyPrint
@@ -38,7 +38,8 @@ from xen.xm.opts import *
 from xen.xm.opts import *
 
 import console
-
+import xen.xend.XendClient
+from xen.xend.XendClient import server
 
 # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
 # getopt.getopt if gnu_getopt is not available.  This will mean that options
@@ -319,8 +320,7 @@ def xm_save(args):
         err("xm save: Unable to create file %s" % savefile)
         sys.exit(1)
     
-    from xen.xend.XendClient import server
-    server.xend_domain_save(dom, savefile)
+    server.xend.domain.save(dom, savefile)
     
 def xm_restore(args):
     arg_check(args, "restore", 1)
@@ -331,16 +331,14 @@ def xm_restore(args):
         err("xm restore: Unable to read file %s" % savefile)
         sys.exit(1)
 
-    from xen.xend.XendClient import server
-    server.xend_domain_restore(savefile)
+    server.xend.domain.restore(savefile)
 
 
 def getDomains(domain_names):
-    from xen.xend.XendClient import server
     if domain_names:
-        return map(server.xend_domain, domain_names)
-    else:
-        return server.xend_list_domains()
+        return map(server.xend.domain, domain_names)
+    else:
+        return server.xend.domains(1)
 
 
 def xm_list(args):
@@ -416,12 +414,11 @@ def xm_brief_list(doms):
 
 def xm_vcpu_list(args):
 
-    from xen.xend.XendClient import server
     if args:
-        dominfo = map(server.xend_domain_vcpuinfo, args)
-    else:
-        doms = server.xend_list_domains(False)
-        dominfo = map(server.xend_domain_vcpuinfo, doms)
+        dominfo = map(server.xend.domain.getVCPUInfo, args)
+    else:
+        doms = server.xend.domains(False)
+        dominfo = map(server.xend.domain.getVCPUInfo, doms)
 
     print 'Name                              ID  VCPU  CPU  State  Time(s)  
CPU Affinity'
 
@@ -475,8 +472,7 @@ def xm_vcpu_list(args):
             cpumap = map(lambda x: int(x), cpumap)
             cpumap.sort()
 
-            from xen.xend.XendClient import server
-            for x in server.xend_node()[1:]:
+            for x in server.xend.node.info()[1:]:
                 if len(x) > 1 and x[0] == 'nr_cpus':
                     nr_cpus = int(x[1])
                     # normalize cpumap by modulus nr_cpus, and drop duplicates
@@ -532,21 +528,18 @@ def xm_pause(args):
     arg_check(args, "pause", 1)
     dom = args[0]
 
-    from xen.xend.XendClient import server
-    server.xend_domain_pause(dom)
+    server.xend.domain.pause(dom)
 
 def xm_unpause(args):
     arg_check(args, "unpause", 1)
     dom = args[0]
 
-    from xen.xend.XendClient import server
-    server.xend_domain_unpause(dom)
+    server.xend.domain.unpause(dom)
 
 def xm_rename(args):
     arg_check(args, "rename", 2)
 
-    from xen.xend.XendClient import server
-    server.xend_domain_rename(args[0], args[1])
+    server.xend.domain.setName(args[0], args[1])
 
 def xm_subcommand(command, args):
     cmd = __import__(command, globals(), locals(), 'xen.xm')
@@ -574,8 +567,7 @@ def xm_vcpu_pin(args):
     vcpu = int(args[1])
     cpumap = cpu_make_map(args[2])
     
-    from xen.xend.XendClient import server
-    server.xend_domain_pincpu(dom, vcpu, cpumap)
+    server.xend.domain.pincpu(dom, vcpu, cpumap)
 
 def xm_mem_max(args):
     arg_check(args, "mem-max", 2)
@@ -583,8 +575,7 @@ def xm_mem_max(args):
     dom = args[0]
     mem = int_unit(args[1], 'm')
 
-    from xen.xend.XendClient import server
-    server.xend_domain_maxmem_set(dom, mem)
+    server.xend.domain.maxmem_set(dom, mem)
     
 def xm_mem_set(args):
     arg_check(args, "mem-set", 2)
@@ -592,20 +583,17 @@ def xm_mem_set(args):
     dom = args[0]
     mem_target = int_unit(args[1], 'm')
 
-    from xen.xend.XendClient import server
-    server.xend_domain_mem_target_set(dom, mem_target)
+    server.xend.domain.setMemoryTarget(dom, mem_target)
     
 def xm_vcpu_set(args):
     arg_check(args, "vcpu-set", 2)
     
-    from xen.xend.XendClient import server
-    server.xend_domain_set_vcpus(args[0], int(args[1]))
+    server.xend.domain.setVCpuCount(args[0], int(args[1]))
 
 
 def xm_destroy(args):
     arg_check(args, "destroy", 1)
-    from xen.xend.XendClient import server
-    server.xend_domain_destroy(args[0])
+    server.xend.domain.destroy(args[0])
 
 
 def xm_domid(args):
@@ -613,8 +601,7 @@ def xm_domid(args):
 
     name = args[0]
 
-    from xen.xend.XendClient import server
-    dom = server.xend_domain(name)
+    dom = server.xend.domain(name)
     print sxp.child_value(dom, 'domid')
     
 def xm_domname(args):
@@ -622,23 +609,20 @@ def xm_domname(args):
 
     name = args[0]
 
-    from xen.xend.XendClient import server
-    dom = server.xend_domain(name)
+    dom = server.xend.domain(name)
     print sxp.child_value(dom, 'name')
 
 def xm_sched_bvt(args):
     arg_check(args, "sched-bvt", 6)
     dom = args[0]
     v = map(long, args[1:6])
-    from xen.xend.XendClient import server
-    server.xend_domain_cpu_bvt_set(dom, *v)
+    server.xend.domain.cpu_bvt_set(dom, *v)
 
 def xm_sched_bvt_ctxallow(args):
     arg_check(args, "sched-bvt-ctxallow", 1)
 
     slice = int(args[0])
-    from xen.xend.XendClient import server
-    server.xend_node_cpu_bvt_slice_set(slice)
+    server.xend.node.cpu_bvt_slice_set(slice)
 
 def xm_sched_sedf(args):
     def ns_to_ms(val):
@@ -695,13 +679,12 @@ def xm_sched_sedf(args):
                                                      'Slice(ms)', 'Lat(ms)',
                                                      'Extra','Weight')
 
-    from xen.xend.XendClient import server
     doms = filter(lambda x : domid_match(domid, x),
                         [parse_doms_info(dom) for dom in getDomains("")])
     for d in doms:
         # fetch current values so as not to clobber them
         sedf_info = \
-            parse_sedf_info(server.xend_domain_cpu_sedf_get(d['dom']))
+            parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
         sedf_info['name'] = d['name']
 
         # update values in case of call to set
@@ -713,7 +696,7 @@ def xm_sched_sedf(args):
             v = map(int, [sedf_info['period'], sedf_info['slice'],
                           sedf_info['latency'],sedf_info['extratime'], 
                           sedf_info['weight']])
-            rv = server.xend_domain_cpu_sedf_set(d['dom'], *v)
+            rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
             if int(rv) != 0:
                 err("Failed to set sedf parameters (rv=%d)."%(rv))
 
@@ -725,8 +708,7 @@ def xm_info(args):
 def xm_info(args):
     arg_check(args, "info", 0)
 
-    from xen.xend.XendClient import server
-    info = server.xend_node()
+    info = server.xend.node.info()
     
     for x in info[1:]:
         if len(x) < 2: 
@@ -738,8 +720,7 @@ def xm_console(args):
     arg_check(args, "console", 1)
 
     dom = args[0]
-    from xen.xend.XendClient import server
-    info = server.xend_domain(dom)
+    info = server.xend.domain(dom)
     domid = int(sxp.child_value(info, 'domid', '-1'))
     console.execConsole(domid)
 
@@ -768,17 +749,15 @@ its contents if the [-c|--clear] flag is
     if not (1 <= len(myargs) <= 2):
         err('Invalid arguments: ' + str(myargs))
 
-    from xen.xend.XendClient import server
     if not gopts.vals.clear:
-        print server.xend_node_get_dmesg()
-    else:
-        server.xend_node_clear_dmesg()
+        print server.xend.node.dmesg.info()
+    else:
+        server.xend.node.dmesg.clear()
 
 def xm_log(args):
     arg_check(args, "log", 0)
     
-    from xen.xend.XendClient import server
-    print server.xend_node_log()
+    print server.xend.node.log()
 
 def parse_dev_info(info):
     def get_info(n, t, d):
@@ -826,13 +805,12 @@ def xm_network_list(args):
         print 'No domain parameter given'
         sys.exit(1)
     dom = params[0]
-    from xen.xend.XendClient import server
     if use_long:
-        devs = server.xend_domain_devices(dom, 'vif')
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend_domain_devices(dom, 'vif'):
+        for x in server.xend.domain.getDeviceSxprs(dom, 'vif'):
             if hdr == 0:
                 print 'Idx BE     MAC Addr.     handle state evt-ch 
tx-/rx-ring-ref BE-path'
                 hdr = 1
@@ -857,13 +835,12 @@ def xm_block_list(args):
         print 'No domain parameter given'
         sys.exit(1)
     dom = params[0]
-    from xen.xend.XendClient import server
     if use_long:
-        devs = server.xend_domain_devices(dom, 'vbd')
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend_domain_devices(dom, 'vbd'):
+        for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
             if hdr == 0:
                 print 'Vdev  BE handle state evt-ch ring-ref BE-path'
                 hdr = 1
@@ -887,13 +864,12 @@ def xm_vtpm_list(args):
         print 'No domain parameter given'
         sys.exit(1)
     dom = params[0]
-    from xen.xend.XendClient import server
     if use_long:
-        devs = server.xend_domain_devices(dom, 'vtpm')
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend_domain_devices(dom, 'vtpm'):
+        for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'):
             if hdr == 0:
                 print 'Idx  BE handle state evt-ch ring-ref BE-path'
                 hdr = 1
@@ -919,8 +895,7 @@ def xm_block_attach(args):
     if len(args) == 5:
         vbd.append(['backend', args[4]])
 
-    from xen.xend.XendClient import server
-    server.xend_domain_device_create(dom, vbd)
+    server.xend.domain.device_create(dom, vbd)
 
 
 def xm_network_attach(args):
@@ -932,8 +907,7 @@ def xm_network_attach(args):
     for a in args[1:]:
         vif.append(a.split("="))
 
-    from xen.xend.XendClient import server
-    server.xend_domain_device_create(dom, vif)
+    server.xend.domain.device_create(dom, vif)
 
 
 def detach(args, command, deviceClass):
@@ -942,8 +916,7 @@ def detach(args, command, deviceClass):
     dom = args[0]
     dev = args[1]
 
-    from xen.xend.XendClient import server
-    server.xend_domain_device_destroy(dom, deviceClass, dev)
+    server.xend.domain.destroyDevice(dom, deviceClass, dev)
 
 
 def xm_block_detach(args):
@@ -955,7 +928,6 @@ def xm_network_detach(args):
 
 
 def xm_vnet_list(args):
-    from xen.xend.XendClient import server
     try:
         (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
     except getopt.GetoptError, opterr:
@@ -990,13 +962,11 @@ def xm_vnet_create(args):
         print "File not found: %s" % conf
         sys.exit(1)
 
-    from xen.xend.XendClient import server
     server.xend_vnet_create(conf)
 
 def xm_vnet_delete(args):
     arg_check(args, "vnet-delete", 1)
     vnet = args[0]
-    from xen.xend.XendClient import server
     server.xend_vnet_delete(vnet)
 
 commands = {
@@ -1132,23 +1102,13 @@ def main(argv=sys.argv):
             else:
                 err("Error connecting to xend: %s." % ex[1])
             sys.exit(1)
-        except xen.xend.XendError.XendError, ex:
-            if len(args) > 0:
-                handle_xend_error(argv[1], args, ex)
+        except SystemExit:
+            sys.exit(1)
+        except xmlrpclib.Fault, ex:
+            if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN:
+                print "Error: the domain '%s' does not exist." % ex.faultString
             else:
-                print "Unexpected error:", sys.exc_info()[0]
-                print
-                print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
-                raise
-        except xen.xend.XendProtocol.XendError, ex:
-            if len(args) > 0:
-                handle_xend_error(argv[1], args, ex)
-            else:
-                print "Unexpected error:", sys.exc_info()[0]
-                print
-                print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
-                raise
-        except SystemExit:
+                print "Error: %s" % ex.faultString
             sys.exit(1)
         except:
             print "Unexpected error:", sys.exc_info()[0]
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py    Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/migrate.py    Tue Mar 28 08:54:58 2006 -0700
@@ -60,4 +60,4 @@ def main(argv):
         opts.err('Invalid arguments: ' + str(args))
     dom = args[0]
     dst = args[1]
-    server.xend_domain_migrate(dom, dst, opts.vals.live, opts.vals.resource, 
opts.vals.port)
+    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, 
opts.vals.port)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py   Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/shutdown.py   Tue Mar 28 08:54:58 2006 -0700
@@ -53,8 +53,8 @@ gopts.opt('reboot', short='R',
           use='Shutdown and reboot.')
 
 def shutdown(opts, doms, mode, wait):
-    if doms == None: doms = server.xend_domains()
-    dom0_name = sxp.child_value(server.xend_domain(0), 'name')
+    if doms == None: doms = server.xend.domains(0)
+    dom0_name = sxp.child_value(server.xend.domain(0), 'name')
     for x in [dom0_name, DOM0_ID]:
         if x in doms:
             if opts.vals.all:
@@ -62,10 +62,10 @@ def shutdown(opts, doms, mode, wait):
             else:
                 opts.err("Can't specify Domain-0")
     for d in doms:
-        server.xend_domain_shutdown(d, mode)
+        server.xend.domain.shutdown(d, mode)
     if wait:
         while doms:
-            alive = server.xend_domains()
+            alive = server.xend.domains(0)
             dead = []
             for d in doms:
                 if d in alive: continue
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/sysrq.py
--- a/tools/python/xen/xm/sysrq.py      Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/sysrq.py      Tue Mar 28 08:54:58 2006 -0700
@@ -28,4 +28,4 @@ def main(argv):
     if len(args) < 2: opts.err('Missing sysrq character')
     dom = args[0]
     req = ord(args[1][0])
-    server.xend_domain_sysrq(dom, req)
+    server.xend.domain.send_sysrq(dom, req)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/talloc.c
--- a/tools/xenstore/talloc.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xenstore/talloc.c   Tue Mar 28 08:54:58 2006 -0700
@@ -1,4 +1,4 @@
-/* 
+/*
    Samba Unix SMB/CIFS implementation.
 
    Samba trivial allocation library - new interface
@@ -6,26 +6,29 @@
    NOTE: Please read talloc_guide.txt for full documentation
 
    Copyright (C) Andrew Tridgell 2004
-   
-   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,
+
+     ** NOTE! The following LGPL license applies to the talloc
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 /*
   inspired by http://swapped.cc/halloc/
 */
-
 
 #ifdef _SAMBA_BUILD_
 #include "includes.h"
@@ -52,15 +55,13 @@
 
 /* use this to force every realloc to change the pointer, to stress test
    code that might not cope */
-#ifdef TESTING
-#define ALWAYS_REALLOC 1
-void *test_malloc(size_t size);
-#define malloc test_malloc
-#endif
+#define ALWAYS_REALLOC 0
+
 
 #define MAX_TALLOC_SIZE 0x10000000
-#define TALLOC_MAGIC 0xe814ec4f
-#define TALLOC_MAGIC_FREE 0x7faebef3
+#define TALLOC_MAGIC 0xe814ec70
+#define TALLOC_FLAG_FREE 0x01
+#define TALLOC_FLAG_LOOP 0x02
 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
 
 /* by default we abort when given a bad pointer (such as when talloc_free() is 
called 
@@ -83,8 +84,7 @@ void *test_malloc(size_t size);
 */
 static const void *null_context;
 static void *cleanup_context;
-static int (*malloc_fail_handler)(void *);
-static void *malloc_fail_data;
+
 
 struct talloc_reference_handle {
        struct talloc_reference_handle *next, *prev;
@@ -97,24 +97,27 @@ struct talloc_chunk {
        struct talloc_chunk *next, *prev;
        struct talloc_chunk *parent, *child;
        struct talloc_reference_handle *refs;
-       size_t size;
-       unsigned magic;
        talloc_destructor_t destructor;
        const char *name;
+       size_t size;
+       unsigned flags;
 };
+
+/* 16 byte alignment seems to keep everyone happy */
+#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
+#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
 
 /* panic if we get a bad magic value */
 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
 {
-       struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
-       if (tc->magic != TALLOC_MAGIC) { 
-               if (tc->magic == TALLOC_MAGIC_FREE) {
-                       TALLOC_ABORT("Bad talloc magic value - double free"); 
-               } else {
-                       TALLOC_ABORT("Bad talloc magic value - unknown value"); 
-               }
-       }
-
+       const char *pp = ptr;
+       struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - 
TC_HDR_SIZE);
+       if ((tc->flags & ~0xF) != TALLOC_MAGIC) { 
+               TALLOC_ABORT("Bad talloc magic value - unknown value"); 
+       }
+       if (tc->flags & TALLOC_FLAG_FREE) {
+               TALLOC_ABORT("Bad talloc magic value - double free"); 
+       }
        return tc;
 }
 
@@ -159,7 +162,7 @@ void *talloc_parent(const void *ptr)
 void *talloc_parent(const void *ptr)
 {
        struct talloc_chunk *tc = talloc_parent_chunk(ptr);
-       return (void *)(tc+1);
+       return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
 }
 
 /* 
@@ -177,17 +180,11 @@ void *_talloc(const void *context, size_
                return NULL;
        }
 
-       tc = malloc(sizeof(*tc)+size);
-       if (tc == NULL) {
-               if (malloc_fail_handler)
-                       if (malloc_fail_handler(malloc_fail_data))
-                               tc = malloc(sizeof(*tc)+size);
-               if (!tc)
-                       return NULL;
-       }
+       tc = malloc(TC_HDR_SIZE+size);
+       if (tc == NULL) return NULL;
 
        tc->size = size;
-       tc->magic = TALLOC_MAGIC;
+       tc->flags = TALLOC_MAGIC;
        tc->destructor = NULL;
        tc->child = NULL;
        tc->name = NULL;
@@ -207,7 +204,7 @@ void *_talloc(const void *context, size_
                tc->next = tc->prev = tc->parent = NULL;
        }
 
-       return (void *)(tc+1);
+       return TC_PTR_FROM_CHUNK(tc);
 }
 
 
@@ -292,7 +289,11 @@ static int talloc_unreference(const void
 
        for (h=tc->refs;h;h=h->next) {
                struct talloc_chunk *p = talloc_parent_chunk(h);
-               if ((p==NULL && context==NULL) || p+1 == context) break;
+               if (p == NULL) {
+                       if (context == NULL) break;
+               } else if (TC_PTR_FROM_CHUNK(p) == context) {
+                       break;
+               }
        }
        if (h == NULL) {
                return -1;
@@ -343,7 +344,7 @@ int talloc_unlink(const void *context, v
 
        new_p = talloc_parent_chunk(tc_p->refs);
        if (new_p) {
-               new_parent = new_p+1;
+               new_parent = TC_PTR_FROM_CHUNK(new_p);
        } else {
                new_parent = NULL;
        }
@@ -470,6 +471,8 @@ void *talloc_init(const char *fmt, ...)
 {
        va_list ap;
        void *ptr;
+
+       talloc_enable_null_tracking();
 
        ptr = _talloc(NULL, 0);
        if (ptr == NULL) return NULL;
@@ -502,16 +505,16 @@ void talloc_free_children(void *ptr)
                   choice is owner of any remaining reference to this
                   pointer, the second choice is our parent, and the
                   final choice is the null context. */
-               void *child = tc->child+1;
+               void *child = TC_PTR_FROM_CHUNK(tc->child);
                const void *new_parent = null_context;
                if (tc->child->refs) {
                        struct talloc_chunk *p = 
talloc_parent_chunk(tc->child->refs);
-                       if (p) new_parent = p+1;
+                       if (p) new_parent = TC_PTR_FROM_CHUNK(p);
                }
                if (talloc_free(child) == -1) {
                        if (new_parent == null_context) {
                                struct talloc_chunk *p = 
talloc_parent_chunk(ptr);
-                               if (p) new_parent = p+1;
+                               if (p) new_parent = TC_PTR_FROM_CHUNK(p);
                        }
                        talloc_steal(new_parent, child);
                }
@@ -539,6 +542,11 @@ int talloc_free(void *ptr)
        if (tc->refs) {
                talloc_reference_destructor(tc->refs);
                return -1;
+       }
+
+       if (tc->flags & TALLOC_FLAG_LOOP) {
+               /* we have a free loop - stop looping */
+               return 0;
        }
 
        if (tc->destructor) {
@@ -554,6 +562,8 @@ int talloc_free(void *ptr)
                tc->destructor = NULL;
        }
 
+       tc->flags |= TALLOC_FLAG_LOOP;
+
        talloc_free_children(ptr);
 
        if (tc->parent) {
@@ -566,7 +576,7 @@ int talloc_free(void *ptr)
                if (tc->next) tc->next->prev = tc->prev;
        }
 
-       tc->magic = TALLOC_MAGIC_FREE;
+       tc->flags |= TALLOC_FLAG_FREE;
 
        free(tc);
        return 0;
@@ -606,36 +616,24 @@ void *_talloc_realloc(const void *contex
        }
 
        /* by resetting magic we catch users of the old memory */
-       tc->magic = TALLOC_MAGIC_FREE;
+       tc->flags |= TALLOC_FLAG_FREE;
 
 #if ALWAYS_REALLOC
-       new_ptr = malloc(size + sizeof(*tc));
-       if (!new_ptr) {
-               tc->magic = TALLOC_MAGIC; 
-               if (malloc_fail_handler)
-                       if (malloc_fail_handler(malloc_fail_data))
-                               new_ptr = malloc(size + sizeof(*tc));
-       }
+       new_ptr = malloc(size + TC_HDR_SIZE);
        if (new_ptr) {
-               memcpy(new_ptr, tc, tc->size + sizeof(*tc));
+               memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
                free(tc);
        }
 #else
-       new_ptr = realloc(tc, size + sizeof(*tc));
-       if (!new_ptr) {
-               tc->magic = TALLOC_MAGIC; 
-               if (malloc_fail_handler)
-                       if (malloc_fail_handler(malloc_fail_data))
-                               new_ptr = realloc(tc, size + sizeof(*tc));
-       }
+       new_ptr = realloc(tc, size + TC_HDR_SIZE);
 #endif
        if (!new_ptr) { 
-               tc->magic = TALLOC_MAGIC; 
+               tc->flags &= ~TALLOC_FLAG_FREE; 
                return NULL; 
        }
 
        tc = new_ptr;
-       tc->magic = TALLOC_MAGIC;
+       tc->flags &= ~TALLOC_FLAG_FREE; 
        if (tc->parent) {
                tc->parent->child = new_ptr;
        }
@@ -651,9 +649,9 @@ void *_talloc_realloc(const void *contex
        }
 
        tc->size = size;
-       talloc_set_name_const(tc+1, name);
-
-       return (void *)(tc+1);
+       talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
+
+       return TC_PTR_FROM_CHUNK(tc);
 }
 
 /* 
@@ -730,10 +728,19 @@ off_t talloc_total_size(const void *ptr)
 
        tc = talloc_chunk_from_ptr(ptr);
 
+       if (tc->flags & TALLOC_FLAG_LOOP) {
+               return 0;
+       }
+
+       tc->flags |= TALLOC_FLAG_LOOP;
+
        total = tc->size;
        for (c=tc->child;c;c=c->next) {
-               total += talloc_total_size(c+1);
-       }
+               total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
+       }
+
+       tc->flags &= ~TALLOC_FLAG_LOOP;
+
        return total;
 }
 
@@ -743,20 +750,21 @@ off_t talloc_total_blocks(const void *pt
 off_t talloc_total_blocks(const void *ptr)
 {
        off_t total = 0;
-       struct talloc_chunk *c, *tc;
-
-       if (ptr == NULL) {
-               ptr = null_context;
-       }
-       if (ptr == NULL) {
+       struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+
+       if (tc->flags & TALLOC_FLAG_LOOP) {
                return 0;
        }
-       tc = talloc_chunk_from_ptr(ptr);
+
+       tc->flags |= TALLOC_FLAG_LOOP;
 
        total++;
        for (c=tc->child;c;c=c->next) {
-               total += talloc_total_blocks(c+1);
-       }
+               total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
+       }
+
+       tc->flags &= ~TALLOC_FLAG_LOOP;
+
        return total;
 }
 
@@ -782,23 +790,29 @@ void talloc_report_depth(const void *ptr
 {
        struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
 
+       if (tc->flags & TALLOC_FLAG_LOOP) {
+               return;
+       }
+
+       tc->flags |= TALLOC_FLAG_LOOP;
+
        for (c=tc->child;c;c=c->next) {
                if (c->name == TALLOC_MAGIC_REFERENCE) {
-                       struct talloc_reference_handle *handle = (void *)(c+1);
+                       struct talloc_reference_handle *handle = 
TC_PTR_FROM_CHUNK(c);
                        const char *name2 = talloc_get_name(handle->ptr);
                        fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
                } else {
-                       const char *name = talloc_get_name(c+1);
+                       const char *name = 
talloc_get_name(TC_PTR_FROM_CHUNK(c));
                        fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks 
(ref %d)\n", 
                                depth*4, "",
                                name,
-                               (unsigned long)talloc_total_size(c+1),
-                               (unsigned long)talloc_total_blocks(c+1),
-                               talloc_reference_count(c+1));
-                       talloc_report_depth(c+1, f, depth+1);
-               }
-       }
-
+                               (unsigned 
long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+                               (unsigned 
long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
+                               talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
+                       talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
+               }
+       }
+       tc->flags &= ~TALLOC_FLAG_LOOP;
 }
 
 /*
@@ -841,9 +855,9 @@ void talloc_report(const void *ptr, FILE
 
        for (c=tc->child;c;c=c->next) {
                fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", 
-                       talloc_get_name(c+1),
-                       (unsigned long)talloc_total_size(c+1),
-                       (unsigned long)talloc_total_blocks(c+1));
+                       talloc_get_name(TC_PTR_FROM_CHUNK(c)),
+                       (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+                       (unsigned 
long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
        }
        fflush(f);
 }
@@ -877,6 +891,74 @@ void talloc_enable_null_tracking(void)
                null_context = talloc_named_const(NULL, 0, "null_context");
        }
 }
+
+#ifdef _SAMBA_BUILD_
+/* Ugly calls to Samba-specific sprintf_append... JRA. */
+
+/*
+  report on memory usage by all children of a pointer, giving a full tree view
+*/
+static void talloc_report_depth_str(const void *ptr, char **pps, ssize_t 
*plen, size_t *pbuflen, int depth)
+{
+       struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+
+       if (tc->flags & TALLOC_FLAG_LOOP) {
+               return;
+       }
+
+       tc->flags |= TALLOC_FLAG_LOOP;
+
+       for (c=tc->child;c;c=c->next) {
+               if (c->name == TALLOC_MAGIC_REFERENCE) {
+                       struct talloc_reference_handle *handle = 
TC_PTR_FROM_CHUNK(c);
+                       const char *name2 = talloc_get_name(handle->ptr);
+
+                       sprintf_append(NULL, pps, plen, pbuflen,
+                               "%*sreference to: %s\n", depth*4, "", name2);
+
+               } else {
+                       const char *name = 
talloc_get_name(TC_PTR_FROM_CHUNK(c));
+
+                       sprintf_append(NULL, pps, plen, pbuflen,
+                               "%*s%-30s contains %6lu bytes in %3lu blocks 
(ref %d)\n", 
+                               depth*4, "",
+                               name,
+                               (unsigned 
long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+                               (unsigned 
long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
+                               talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
+
+                       talloc_report_depth_str(TC_PTR_FROM_CHUNK(c), pps, 
plen, pbuflen, depth+1);
+               }
+       }
+       tc->flags &= ~TALLOC_FLAG_LOOP;
+}
+
+/*
+  report on memory usage by all children of a pointer
+*/
+char *talloc_describe_all(void)
+{
+       ssize_t len = 0;
+       size_t buflen = 512;
+       char *s = NULL;
+
+       if (null_context == NULL) {
+               return NULL;
+       }
+
+       sprintf_append(NULL, &s, &len, &buflen,
+               "full talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
+               talloc_get_name(null_context), 
+               (unsigned long)talloc_total_size(null_context),
+               (unsigned long)talloc_total_blocks(null_context));
+
+       if (!s) {
+               return NULL;
+       }
+       talloc_report_depth_str(null_context, &s, &len, &buflen, 1);
+       return s;
+}
+#endif
 
 /*
   enable leak reporting on exit
@@ -942,6 +1024,30 @@ char *talloc_strdup(const void *t, const
 }
 
 /*
+ append to a talloced string 
+*/
+char *talloc_append_string(const void *t, char *orig, const char *append)
+{
+       char *ret;
+       size_t olen = strlen(orig);
+       size_t alenz;
+
+       if (!append)
+               return orig;
+
+       alenz = strlen(append) + 1;
+
+       ret = talloc_realloc(t, orig, char, olen + alenz);
+       if (!ret)
+               return NULL;
+
+       /* append the string with the trailing \0 */
+       memcpy(&ret[olen], append, alenz);
+
+       return ret;
+}
+
+/*
   strndup with a talloc 
 */
 char *talloc_strndup(const void *t, const char *p, size_t n)
@@ -949,7 +1055,7 @@ char *talloc_strndup(const void *t, cons
        size_t len;
        char *ret;
 
-       for (len=0; p[len] && len<n; len++) ;
+       for (len=0; len<n && p[len]; len++) ;
 
        ret = _talloc(t, len + 1);
        if (!ret) { return NULL; }
@@ -974,10 +1080,14 @@ char *talloc_vasprintf(const void *t, co
        int len;
        char *ret;
        va_list ap2;
+       char c;
        
        VA_COPY(ap2, ap);
 
-       len = vsnprintf(NULL, 0, fmt, ap2);
+       /* this call looks strange, but it makes it work on older solaris boxes 
*/
+       if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
+               return NULL;
+       }
 
        ret = _talloc(t, len+1);
        if (ret) {
@@ -1029,7 +1139,15 @@ static char *talloc_vasprintf_append(cha
        VA_COPY(ap2, ap);
 
        s_len = tc->size - 1;
-       len = vsnprintf(NULL, 0, fmt, ap2);
+       if ((len = vsnprintf(NULL, 0, fmt, ap2)) <= 0) {
+               /* Either the vsnprintf failed or the format resulted in
+                * no characters being formatted. In the former case, we
+                * ought to return NULL, in the latter we ought to return
+                * the original string. Most current callers of this 
+                * function expect it to never return NULL.
+                */
+               return s;
+       }
 
        s = talloc_realloc(NULL, s, char, s_len + len+1);
        if (!s) return NULL;
@@ -1133,11 +1251,45 @@ size_t talloc_get_size(const void *conte
        return tc->size;
 }
 
-talloc_fail_handler *talloc_set_fail_handler(talloc_fail_handler *handler,
-                                            void *data)
-{
-       talloc_fail_handler *old = malloc_fail_handler;
-       malloc_fail_handler = handler;
-       malloc_fail_data = data;
-       return old;
-}
+/*
+  find a parent of this context that has the given name, if any
+*/
+void *talloc_find_parent_byname(const void *context, const char *name)
+{
+       struct talloc_chunk *tc;
+
+       if (context == NULL) {
+               return NULL;
+       }
+
+       tc = talloc_chunk_from_ptr(context);
+       while (tc) {
+               if (tc->name && strcmp(tc->name, name) == 0) {
+                       return TC_PTR_FROM_CHUNK(tc);
+               }
+               while (tc && tc->prev) tc = tc->prev;
+               tc = tc->parent;
+       }
+       return NULL;
+}
+
+/*
+  show the parentage of a context
+*/
+void talloc_show_parents(const void *context, FILE *file)
+{
+       struct talloc_chunk *tc;
+
+       if (context == NULL) {
+               fprintf(file, "talloc no parents for NULL\n");
+               return;
+       }
+
+       tc = talloc_chunk_from_ptr(context);
+       fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
+       while (tc) {
+               fprintf(file, "\t'%s'\n", 
talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
+               while (tc && tc->prev) tc = tc->prev;
+               tc = tc->parent;
+       }
+}
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/talloc.h
--- a/tools/xenstore/talloc.h   Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xenstore/talloc.h   Tue Mar 28 08:54:58 2006 -0700
@@ -6,19 +6,23 @@
 
    Copyright (C) Andrew Tridgell 2004-2005
    
-   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.
+     ** NOTE! The following LGPL license applies to the talloc
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
    
-   This program is distributed in the hope that it will be useful,
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 /* this is only needed for compatibility with the old talloc */
@@ -58,12 +62,17 @@ typedef void TALLOC_CTX;
 #define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), 
count)
 #define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count)
 
+#if 0 
+/* Not correct for Samba3. */
 #define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB: 
"__location__)
 #define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, 
size, "DATA_BLOB: "__location__)
 #define data_blob_dup_talloc(ctx, blob) data_blob_talloc_named(ctx, 
(blob)->data, (blob)->length, "DATA_BLOB: "__location__)
+#endif
 
 #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
 #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
+
+#define talloc_find_parent_bytype(ptr, type) (type 
*)talloc_find_parent_byname(ptr, #type)
 
 
 #if TALLOC_DEPRECATED
@@ -117,6 +126,7 @@ void *_talloc_memdup(const void *t, cons
 void *_talloc_memdup(const void *t, const void *p, size_t size, const char 
*name);
 char *talloc_strdup(const void *t, const char *p);
 char *talloc_strndup(const void *t, const char *p, size_t n);
+char *talloc_append_string(const void *t, char *orig, const char *append);
 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) 
PRINTF_ATTRIBUTE(2,0);
 char *talloc_asprintf(const void *t, const char *fmt, ...) 
PRINTF_ATTRIBUTE(2,3);
 char *talloc_asprintf_append(char *s,
@@ -127,8 +137,8 @@ void *talloc_realloc_fn(const void *cont
 void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
 void *talloc_autofree_context(void);
 size_t talloc_get_size(const void *ctx);
+void *talloc_find_parent_byname(const void *ctx, const char *name);
+void talloc_show_parents(const void *context, FILE *file);
 
-typedef int talloc_fail_handler(void *);
-talloc_fail_handler *talloc_set_fail_handler(talloc_fail_handler *, void *);
 #endif
 
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xenstore/xenstored_core.c   Tue Mar 28 08:54:58 2006 -0700
@@ -1231,39 +1231,17 @@ static void process_message(struct conne
        conn->transaction = NULL;
 }
 
-static int out_of_mem(void *data)
-{
-       longjmp(*(jmp_buf *)data, 1);
-}
-
 static void consider_message(struct connection *conn)
 {
-       jmp_buf talloc_fail;
-
        if (verbose)
                xprintf("Got message %s len %i from %p\n",
                        sockmsg_string(conn->in->hdr.msg.type),
                        conn->in->hdr.msg.len, conn);
 
-       /* For simplicity, we kill the connection on OOM. */
-       talloc_set_fail_handler(out_of_mem, &talloc_fail);
-       if (setjmp(talloc_fail)) {
-               talloc_free(conn);
-               goto end;
-       }
-
        process_message(conn, conn->in);
 
        talloc_free(conn->in);
        conn->in = new_buffer(conn);
-
-end:
-       talloc_set_fail_handler(NULL, NULL);
-       if (talloc_total_blocks(NULL)
-           != talloc_total_blocks(talloc_autofree_context()) + 1) {
-               talloc_report_full(NULL, stderr);
-               abort();
-       }
 }
 
 /* Errors in reading or allocating here mean we get out of sync, so we
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xentrace/Makefile
--- a/tools/xentrace/Makefile   Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xentrace/Makefile   Tue Mar 28 08:54:58 2006 -0700
@@ -6,7 +6,7 @@ XEN_ROOT=../..
 XEN_ROOT=../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-CFLAGS  += -Werror
+CFLAGS  += -Werror -D_LARGEFILE64_SOURCE
 
 CFLAGS  += -I $(XEN_XC)
 CFLAGS  += -I $(XEN_LIBXC)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xentrace/formats
--- a/tools/xentrace/formats    Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xentrace/formats    Tue Mar 28 08:54:58 2006 -0700
@@ -16,6 +16,6 @@ 0x00080002    CPU%(cpu)d      %(tsc)d         VMX_
 0x00080002     CPU%(cpu)d      %(tsc)d         VMX_VECTOR              [ domid 
= 0x%(1)08x, eip = 0x%(2)08x, vector = 0x%(3)08x ]
 0x00080003     CPU%(cpu)d      %(tsc)d         VMX_INT                 [ domid 
= 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ]
 
-0x00090001      CPU%(cpu)d      %(tsc)d         VMENTRY                 
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
-0x00090002      CPU%(cpu)d      %(tsc)d         VMEXIT                  
0x%(1)08x 0x%(2)08x 0x%(3)08x 
+0x00081001      CPU%(cpu)d      %(tsc)d         VMEXIT                  
0x%(1)08x 0x%(2)08x 0x%(3)08x 
+0x00081002      CPU%(cpu)d      %(tsc)d         VMENTRY                 
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
 
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xentrace/xentrace.c Tue Mar 28 08:54:58 2006 -0700
@@ -498,7 +498,7 @@ int main(int argc, char **argv)
     }
 
     if ( opts.outfile )
-        outfd = open(opts.outfile, O_WRONLY | O_CREAT);
+        outfd = open(opts.outfile, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
 
     if(outfd < 0)
     {
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xm-test/lib/XmTestLib/Test.py
--- a/tools/xm-test/lib/XmTestLib/Test.py       Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xm-test/lib/XmTestLib/Test.py       Tue Mar 28 08:54:58 2006 -0700
@@ -131,12 +131,12 @@ def becomeNonRoot():
         if os.geteuid() == 0:
             FAIL("Could not become a non-root user")
 
-def FAIL(reason):
-    print "\nREASON: %s" % reason
+def FAIL(format, *args):
+    print "\nREASON:", (format % args)
     sys.exit(TEST_FAIL)
 
-def SKIP(reason):
-    print "\nREASON: %s" % reason
+def SKIP(format, *args):
+    print "\nREASON:", (format % args)
     sys.exit(TEST_SKIP)
 
 def saveLog(logText, filename=None):
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xm-test/ramdisk/Makefile.am
--- a/tools/xm-test/ramdisk/Makefile.am Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xm-test/ramdisk/Makefile.am Tue Mar 28 08:54:58 2006 -0700
@@ -1,3 +1,4 @@
+INITRD ?= http://xm-test.xensource.com/ramdisks
 
 EXTRA_DIST = skel configs patches
 
@@ -60,7 +61,7 @@ disk.img: existing
        fi
 
 existing:
-       @if test -n "$(INITRD)"; then \
+       @if [ -n "$(INITRD)" ] && [ ! -f $(XMTEST_VER_IMG) ] ; then \
                wget $(INITRD)/$(XMTEST_VER_IMG); \
        fi
        @if [ -f $(XMTEST_VER_IMG) ] ; then \
diff -r 7e3cbc409676 -r d75a6cc5e68a 
tools/xm-test/tests/block-create/Makefile.am
--- a/tools/xm-test/tests/block-create/Makefile.am      Mon Mar 27 15:36:47 
2006 -0700
+++ b/tools/xm-test/tests/block-create/Makefile.am      Tue Mar 28 08:54:58 
2006 -0700
@@ -12,7 +12,7 @@ TESTS = 01_block_attach_device_pos.test 
        11_block_attach_shared_dom0.test \
        12_block_attach_shared_domU.test
 
-EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
+EXTRA_DIST = $(TESTS)
 
 TESTS_ENVIRONMENT=@TENV@
 
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xm-test/tests/create/Makefile.am
--- a/tools/xm-test/tests/create/Makefile.am    Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xm-test/tests/create/Makefile.am    Tue Mar 28 08:54:58 2006 -0700
@@ -15,7 +15,7 @@ TESTS = 01_create_basic_pos.test \
        14_create_blockroot_pos.test \
        15_create_smallmem_pos.test
 
-EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
+EXTRA_DIST = $(TESTS)
 
 TESTS_ENVIRONMENT=@TENV@
 
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/dom0_ops.c   Tue Mar 28 08:54:58 2006 -0700
@@ -460,8 +460,7 @@ void arch_getdomaininfo_ctxt(
 
     if ( hvm_guest(v) )
     {
-        hvm_store_cpu_guest_regs(v, &c->user_regs);
-        hvm_store_cpu_guest_ctrl_regs(v, c->ctrlreg);
+        hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg);
     }
     else
     {
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/platform.c       Tue Mar 28 08:54:58 2006 -0700
@@ -773,7 +773,7 @@ void handle_mmio(unsigned long va, unsig
     mmio_opp = &v->arch.hvm_vcpu.mmio_op;
 
     regs = mmio_opp->inst_decoder_regs;
-    hvm_store_cpu_guest_regs(v, regs);
+    hvm_store_cpu_guest_regs(v, regs, NULL);
 
     if ((inst_len = hvm_instruction_length(v)) <= 0) {
         printf("handle_mmio: failed to get instruction length\n");
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/svm/intr.c       Tue Mar 28 08:54:58 2006 -0700
@@ -44,6 +44,58 @@
  */
 #define BSP_CPU(v)    (!(v->vcpu_id))
 
+u64 svm_get_guest_time(struct vcpu *v)
+{
+    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+    u64    host_tsc;
+    
+    rdtscll(host_tsc);
+    return host_tsc + vpit->cache_tsc_offset;
+}
+
+void svm_set_guest_time(struct vcpu *v, u64 gtime)
+{
+    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+    u64    host_tsc;
+   
+    rdtscll(host_tsc);
+    
+    vpit->cache_tsc_offset = gtime - host_tsc;
+    v->arch.hvm_svm.vmcb->tsc_offset = vpit->cache_tsc_offset;
+}
+
+static inline void
+interrupt_post_injection(struct vcpu * v, int vector, int type)
+{
+    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+
+    if ( is_pit_irq(v, vector, type) ) {
+        if ( !vpit->first_injected ) {
+            vpit->pending_intr_nr = 0;
+            vpit->last_pit_gtime = svm_get_guest_time(v);
+            vpit->scheduled = NOW() + vpit->period;
+            set_timer(&vpit->pit_timer, vpit->scheduled);
+            vpit->first_injected = 1;
+        } else {
+            vpit->pending_intr_nr--;
+        }
+        vpit->inject_point = NOW();
+
+        vpit->last_pit_gtime += vpit->period;
+        svm_set_guest_time(v, vpit->last_pit_gtime);
+    }
+
+    switch(type)
+    {
+    case VLAPIC_DELIV_MODE_EXT:
+        break;
+
+    default:
+        vlapic_post_injection(v, vector, type);
+        break;
+    }
+}
+
 static inline int svm_inject_extint(struct vcpu *v, int trap, int error_code)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -62,45 +114,6 @@ static inline int svm_inject_extint(stru
     vmcb->vintr = intr;
 //  printf( "IRQ = %d\n", trap );
     return 0;
-}
-
-void svm_set_tsc_shift(struct vcpu *v, struct hvm_virpit *vpit)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    u64    drift;
-
-    if ( vpit->first_injected )
-        drift = vpit->period_cycles * vpit->pending_intr_nr;
-    else
-        drift = 0;
-    vmcb->tsc_offset = ( 0 - drift );
-}
-
-static inline void
-interrupt_post_injection(struct vcpu * v, int vector, int type)
-{
-    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
-
-    if ( is_pit_irq(v, vector, type) ) {
-            if ( !vpit->first_injected ) {
-                vpit->first_injected = 1;
-                vpit->pending_intr_nr = 0;
-            }
-            else if (vpit->pending_intr_nr) {
-                --vpit->pending_intr_nr;
-            }
-            vpit->inject_point = NOW();
-            svm_set_tsc_shift (v, vpit);
-    }
-
-    switch(type)
-    {
-    case VLAPIC_DELIV_MODE_EXT:
-        break;
-
-    default:
-        vlapic_post_injection(v, vector, type);
-    }
 }
 
 asmlinkage void svm_intr_assist(void) 
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Mar 28 08:54:58 2006 -0700
@@ -201,31 +201,41 @@ int svm_initialize_guest_resources(struc
 }
 
 static void svm_store_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *regs)
+    struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
+    if ( regs != NULL )
+    {
 #if defined (__x86_64__)
-    regs->rip    = vmcb->rip;
-    regs->rsp    = vmcb->rsp;
-    regs->rflags = vmcb->rflags;
-    regs->cs     = vmcb->cs.sel;
-    regs->ds     = vmcb->ds.sel;
-    regs->es     = vmcb->es.sel;
-    regs->ss     = vmcb->ss.sel;
-    regs->gs     = vmcb->gs.sel;
-    regs->fs     = vmcb->fs.sel;
+        regs->rip    = vmcb->rip;
+        regs->rsp    = vmcb->rsp;
+        regs->rflags = vmcb->rflags;
+        regs->cs     = vmcb->cs.sel;
+        regs->ds     = vmcb->ds.sel;
+        regs->es     = vmcb->es.sel;
+        regs->ss     = vmcb->ss.sel;
+        regs->gs     = vmcb->gs.sel;
+        regs->fs     = vmcb->fs.sel;
 #elif defined (__i386__)
-    regs->eip    = vmcb->rip;
-    regs->esp    = vmcb->rsp;
-    regs->eflags = vmcb->rflags;
-    regs->cs     = vmcb->cs.sel;
-    regs->ds     = vmcb->ds.sel;
-    regs->es     = vmcb->es.sel;
-    regs->ss     = vmcb->ss.sel;
-    regs->gs     = vmcb->gs.sel;
-    regs->fs     = vmcb->fs.sel;
+        regs->eip    = vmcb->rip;
+        regs->esp    = vmcb->rsp;
+        regs->eflags = vmcb->rflags;
+        regs->cs     = vmcb->cs.sel;
+        regs->ds     = vmcb->ds.sel;
+        regs->es     = vmcb->es.sel;
+        regs->ss     = vmcb->ss.sel;
+        regs->gs     = vmcb->gs.sel;
+        regs->fs     = vmcb->fs.sel;
 #endif
+    }
+
+    if ( crs != NULL )
+    {
+        crs[0] = vmcb->cr0;
+        crs[3] = vmcb->cr3;
+        crs[4] = vmcb->cr4;
+    }
 }
 
 static void svm_load_cpu_guest_regs(
@@ -372,15 +382,6 @@ static inline int long_mode_do_msr_write
     return 1;
 }
 
-void svm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    crs[0] = vmcb->cr0;
-    crs[3] = vmcb->cr3;
-    crs[4] = vmcb->cr4;
-}
-
 void svm_modify_guest_state(struct vcpu *v)
 {
     svm_modify_vmcb(v, &v->arch.guest_context.user_regs);
@@ -448,7 +449,6 @@ int start_svm(void)
     hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
     hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
 
-    hvm_funcs.store_cpu_guest_ctrl_regs = svm_store_cpu_guest_ctrl_regs;
     hvm_funcs.modify_guest_state = svm_modify_guest_state;
 
     hvm_funcs.realmode = svm_realmode;
@@ -670,8 +670,18 @@ static void arch_svm_do_launch(struct vc
     reset_stack_and_jump(svm_asm_do_launch);
 }
 
+static void svm_freeze_time(struct vcpu *v)
+{
+    struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
+    
+    v->domain->arch.hvm_domain.guest_time = svm_get_guest_time(v);
+    if ( vpit->first_injected )
+        stop_timer(&(vpit->pit_timer));
+}
+
 static void svm_ctxt_switch_from(struct vcpu *v)
 {
+    svm_freeze_time(v);
 }
 
 static void svm_ctxt_switch_to(struct vcpu *v)
@@ -718,6 +728,8 @@ static void svm_relinquish_guest_resourc
 
     for_each_vcpu ( d, v )
     {
+        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+            continue;
 #if 0
         /* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */
         free_host_save_area(v->arch.hvm_svm.host_save_area);
@@ -911,7 +923,7 @@ static void svm_vmexit_do_cpuid(struct v
 
     if (input == 1)
     {
-        if ( hvm_apic_support(v->domain) &&
+        if ( !hvm_apic_support(v->domain) ||
                 !vlapic_global_enabled((VLAPIC(v))) )
             clear_bit(X86_FEATURE_APIC, &edx);
            
@@ -1251,11 +1263,6 @@ static void svm_io_instruction(struct vc
 
         /* Need the original rip, here. */
         addr = svm_get_io_address(vmcb, regs, dir, real);
-        /* 
-         * On SVM, the RIP of the intruction following the IN/OUT is saved in
-         * ExitInfo2
-         */
-        vmcb->rip = vmcb->exitinfo2;
 
         /* "rep" prefix */
         if (info.fields.rep) 
@@ -1288,6 +1295,8 @@ static void svm_io_instruction(struct vc
                 else
                     count = (addr & ~PAGE_MASK) / size;
             }
+            else    
+                vmcb->rip = vmcb->exitinfo2;
 
             send_pio_req(regs, port, count, size, addr, dir, 1);
         }
@@ -1693,7 +1702,7 @@ static inline void svm_do_msr_access(str
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     int  inst_len;
-    int64_t tsc_sum;
+    u64 msr_content=0;
 
     ASSERT(vmcb);
 
@@ -1708,24 +1717,27 @@ static inline void svm_do_msr_access(str
         inst_len = __get_instruction_length(vmcb, INSTR_RDMSR, NULL);
 
         regs->edx = 0;
-        switch (regs->ecx)
+        switch (regs->ecx) {
+        case MSR_IA32_TIME_STAMP_COUNTER:
         {
+            struct hvm_virpit *vpit;
+
+            rdtscll(msr_content);
+            vpit = &(v->domain->arch.hvm_domain.vpit);
+            msr_content += vpit->cache_tsc_offset;
+            break;
+        }
         case MSR_IA32_SYSENTER_CS:
-            regs->eax = vmcb->sysenter_cs;
+            msr_content = vmcb->sysenter_cs;
             break;
         case MSR_IA32_SYSENTER_ESP: 
-            regs->eax = vmcb->sysenter_esp;
+            msr_content = vmcb->sysenter_esp;
             break;
         case MSR_IA32_SYSENTER_EIP:     
-            regs->eax = vmcb->sysenter_eip;
+            msr_content = vmcb->sysenter_eip;
             break;
-        case MSR_IA32_TIME_STAMP_COUNTER:
-            __asm__ __volatile__("rdtsc" : "=a" (regs->eax), "=d" (regs->edx));
-            tsc_sum = regs->edx;
-            tsc_sum = (tsc_sum << 32) + regs->eax;
-            tsc_sum += (int64_t) vmcb->tsc_offset;
-            regs->eax = tsc_sum & 0xFFFFFFFF;
-            regs->edx = (tsc_sum >> 32) & 0xFFFFFFFF;
+        case MSR_IA32_APICBASE:
+            msr_content = VLAPIC(v) ? VLAPIC(v)->apic_base_msr : 0;
             break;
         default:
             if (long_mode_do_msr_read(regs))
@@ -1733,21 +1745,30 @@ static inline void svm_do_msr_access(str
             rdmsr_safe(regs->ecx, regs->eax, regs->edx);
             break;
         }
+        regs->eax = msr_content & 0xFFFFFFFF;
+        regs->edx = msr_content >> 32;
     }
     else
     {
         inst_len = __get_instruction_length(vmcb, INSTR_WRMSR, NULL);
+        msr_content = (regs->eax & 0xFFFFFFFF) | ((u64)regs->edx << 32);
 
         switch (regs->ecx)
         {
+        case MSR_IA32_TIME_STAMP_COUNTER:
+            svm_set_guest_time(v, msr_content);
+            break;
         case MSR_IA32_SYSENTER_CS:
-            vmcb->sysenter_cs = regs->eax;
+            vmcb->sysenter_cs = msr_content;
             break;
         case MSR_IA32_SYSENTER_ESP: 
-            vmcb->sysenter_esp = regs->eax;
+            vmcb->sysenter_esp = msr_content;
             break;
         case MSR_IA32_SYSENTER_EIP:     
-            vmcb->sysenter_eip = regs->eax;
+            vmcb->sysenter_eip = msr_content;
+            break;
+        case MSR_IA32_APICBASE:
+            vlapic_msr_set(VLAPIC(v), msr_content);
             break;
         default:
             long_mode_do_msr_write(regs);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Tue Mar 28 08:54:58 2006 -0700
@@ -123,7 +123,7 @@ static int construct_vmcb_controls(struc
           GENERAL1_INTERCEPT_RDTSC         | GENERAL1_INTERCEPT_PUSHF      |
           GENERAL1_INTERCEPT_SWINT         | GENERAL1_INTERCEPT_POPF       | 
           GENERAL1_INTERCEPT_IRET          | GENERAL1_INTERCEPT_PAUSE      |
-          GENERAL1_INTERCEPT_TASK_SWITCH   | GENERAL1_INTERCEPT_SMI
+          GENERAL1_INTERCEPT_TASK_SWITCH
         );
 
     /* turn on the general 2 intercepts */
@@ -467,6 +467,8 @@ void svm_do_launch(struct vcpu *v)
     v->arch.hvm_svm.injecting_event  = 0;
     v->arch.hvm_svm.saved_irq_vector = -1;
 
+    svm_set_guest_time(v, 0);
+       
     if (svm_dbg_on)
         svm_dump_vmcb(__func__, vmcb);
 }
@@ -494,15 +496,16 @@ void svm_do_resume(struct vcpu *v)
     struct hvm_virpit *vpit = &d->arch.hvm_domain.vpit;
 
     svm_stts(v);
+    
+    /* pick up the elapsed PIT ticks and re-enable pit_timer */
+    if ( vpit->first_injected) {
+        svm_set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+        pickup_deactive_ticks(vpit);
+    }
 
     if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
          test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
         hvm_wait_io();
-
-    /* pick up the elapsed PIT ticks and re-enable pit_timer */
-    if ( vpit->first_injected )
-        pickup_deactive_ticks(vpit);
-    svm_set_tsc_shift(v, vpit);
 
     /* We can't resume the guest if we're waiting on I/O */
     ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/io.c Tue Mar 28 08:54:58 2006 -0700
@@ -86,7 +86,7 @@ interrupt_post_injection(struct vcpu * v
         }
         vpit->inject_point = NOW();
 
-        vpit->last_pit_gtime += vpit->period;
+        vpit->last_pit_gtime += vpit->period_cycles;
         set_guest_time(v, vpit->last_pit_gtime);
     }
 
@@ -206,8 +206,11 @@ void vmx_do_resume(struct vcpu *v)
     vmx_stts();
 
     /* pick up the elapsed PIT ticks and re-enable pit_timer */
-    if ( vpit->first_injected) {
-        set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+    if ( vpit->first_injected ) {
+        if ( v->domain->arch.hvm_domain.guest_time ) {
+            set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+            v->domain->arch.hvm_domain.guest_time = 0;
+        }
         pickup_deactive_ticks(vpit);
     }
 
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Mar 28 08:54:58 2006 -0700
@@ -89,6 +89,8 @@ static void vmx_relinquish_guest_resourc
 
     for_each_vcpu ( d, v )
     {
+        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+            continue;
         vmx_request_clear_vmcs(v);
         destroy_vmcs(&v->arch.hvm_vmx);
         free_monitor_pagetable(v);
@@ -358,9 +360,10 @@ static void vmx_freeze_time(struct vcpu 
 {
     struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
     
-    v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
-    if ( vpit->first_injected )
+    if ( vpit->first_injected && !v->domain->arch.hvm_domain.guest_time ) {
+        v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
         stop_timer(&(vpit->pit_timer));
+    }
 }
 
 static void vmx_ctxt_switch_from(struct vcpu *v)
@@ -397,31 +400,81 @@ void vmx_migrate_timers(struct vcpu *v)
         migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
 }
 
-void vmx_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{
+struct vmx_store_cpu_guest_regs_callback_info {
+    struct vcpu *v;
+    struct cpu_user_regs *regs;
+    unsigned long *crs;
+};
+
+static void vmx_store_cpu_guest_regs(
+    struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs);
+
+static void vmx_store_cpu_guest_regs_callback(void *data)
+{
+    struct vmx_store_cpu_guest_regs_callback_info *info = data;
+    vmx_store_cpu_guest_regs(info->v, info->regs, info->crs);
+}
+
+static void vmx_store_cpu_guest_regs(
+    struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
+{
+    if ( v != current )
+    {
+        /* Non-current VCPUs must be paused to get a register snapshot. */
+        ASSERT(atomic_read(&v->pausecnt) != 0);
+
+        if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
+        {
+            /* Get register details from remote CPU. */
+            struct vmx_store_cpu_guest_regs_callback_info info = {
+                .v = v, .regs = regs, .crs = crs };
+            cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
+            on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback,
+                             &info, 1, 1);
+            return;
+        }
+
+        /* Register details are on this CPU. Load the correct VMCS. */
+        __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+    }
+
+    ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
+
+    if ( regs != NULL )
+    {
 #if defined (__x86_64__)
-    __vmread(GUEST_RFLAGS, &regs->rflags);
-    __vmread(GUEST_SS_SELECTOR, &regs->ss);
-    __vmread(GUEST_CS_SELECTOR, &regs->cs);
-    __vmread(GUEST_DS_SELECTOR, &regs->ds);
-    __vmread(GUEST_ES_SELECTOR, &regs->es);
-    __vmread(GUEST_GS_SELECTOR, &regs->gs);
-    __vmread(GUEST_FS_SELECTOR, &regs->fs);
-    __vmread(GUEST_RIP, &regs->rip);
-    __vmread(GUEST_RSP, &regs->rsp);
+        __vmread(GUEST_RFLAGS, &regs->rflags);
+        __vmread(GUEST_SS_SELECTOR, &regs->ss);
+        __vmread(GUEST_CS_SELECTOR, &regs->cs);
+        __vmread(GUEST_DS_SELECTOR, &regs->ds);
+        __vmread(GUEST_ES_SELECTOR, &regs->es);
+        __vmread(GUEST_GS_SELECTOR, &regs->gs);
+        __vmread(GUEST_FS_SELECTOR, &regs->fs);
+        __vmread(GUEST_RIP, &regs->rip);
+        __vmread(GUEST_RSP, &regs->rsp);
 #elif defined (__i386__)
-    __vmread(GUEST_RFLAGS, &regs->eflags);
-    __vmread(GUEST_SS_SELECTOR, &regs->ss);
-    __vmread(GUEST_CS_SELECTOR, &regs->cs);
-    __vmread(GUEST_DS_SELECTOR, &regs->ds);
-    __vmread(GUEST_ES_SELECTOR, &regs->es);
-    __vmread(GUEST_GS_SELECTOR, &regs->gs);
-    __vmread(GUEST_FS_SELECTOR, &regs->fs);
-    __vmread(GUEST_RIP, &regs->eip);
-    __vmread(GUEST_RSP, &regs->esp);
-#else
-#error Unsupported architecture
+        __vmread(GUEST_RFLAGS, &regs->eflags);
+        __vmread(GUEST_SS_SELECTOR, &regs->ss);
+        __vmread(GUEST_CS_SELECTOR, &regs->cs);
+        __vmread(GUEST_DS_SELECTOR, &regs->ds);
+        __vmread(GUEST_ES_SELECTOR, &regs->es);
+        __vmread(GUEST_GS_SELECTOR, &regs->gs);
+        __vmread(GUEST_FS_SELECTOR, &regs->fs);
+        __vmread(GUEST_RIP, &regs->eip);
+        __vmread(GUEST_RSP, &regs->esp);
 #endif
+    }
+
+    if ( crs != NULL )
+    {
+        __vmread(CR0_READ_SHADOW, &crs[0]);
+        __vmread(GUEST_CR3, &crs[3]);
+        __vmread(CR4_READ_SHADOW, &crs[4]);
+    }
+
+    /* Reload current VCPU's VMCS if it was temporarily unloaded. */
+    if ( (v != current) && hvm_guest(current) )
+        __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
 }
 
 void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
@@ -453,13 +506,6 @@ void vmx_load_cpu_guest_regs(struct vcpu
 #else
 #error Unsupported architecture
 #endif
-}
-
-void vmx_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
-    __vmread(CR0_READ_SHADOW, &crs[0]);
-    __vmread(GUEST_CR3, &crs[3]);
-    __vmread(CR4_READ_SHADOW, &crs[4]);
 }
 
 void vmx_modify_guest_state(struct vcpu *v)
@@ -615,7 +661,6 @@ int start_vmx(void)
     hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
     hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
 
-    hvm_funcs.store_cpu_guest_ctrl_regs = vmx_store_cpu_guest_ctrl_regs;
     hvm_funcs.modify_guest_state = vmx_modify_guest_state;
 
     hvm_funcs.realmode = vmx_realmode;
@@ -945,7 +990,7 @@ static void vmx_io_instruction(struct cp
         port = (exit_qualification >> 16) & 0xFFFF;
     else
         port = regs->edx & 0xffff;
-    TRACE_VMEXIT(2, port);
+    TRACE_VMEXIT(1, port);
     size = (exit_qualification & 7) + 1;
     dir = test_bit(3, &exit_qualification); /* direction */
 
@@ -1308,7 +1353,8 @@ static int vmx_set_cr0(unsigned long val
             vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE;
             __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
 
-            if ( !shadow_set_guest_paging_levels(v->domain, 4) ) {
+            if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L4) )
+            {
                 printk("Unsupported guest paging levels\n");
                 domain_crash_synchronous(); /* need to take a clean path */
             }
@@ -1317,9 +1363,26 @@ static int vmx_set_cr0(unsigned long val
 #endif  /* __x86_64__ */
         {
 #if CONFIG_PAGING_LEVELS >= 3
-            if ( !shadow_set_guest_paging_levels(v->domain, 2) ) {
-                printk("Unsupported guest paging levels\n");
-                domain_crash_synchronous(); /* need to take a clean path */
+            /* seems it's a 32-bit or 32-bit PAE guest */
+
+            if ( test_bit(VMX_CPU_STATE_PAE_ENABLED,
+                        &v->arch.hvm_vmx.cpu_state) )
+            {
+                /* The guest enables PAE first and then it enables PG, it is
+                 * really a PAE guest */
+                if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) )
+                {
+                    printk("Unsupported guest paging levels\n");
+                    domain_crash_synchronous();
+                }
+            }
+            else
+            {
+                if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L2) )
+                {
+                    printk("Unsupported guest paging levels\n");
+                    domain_crash_synchronous(); /* need to take a clean path */
+                }
             }
 #endif
         }
@@ -1398,6 +1461,12 @@ static int vmx_set_cr0(unsigned long val
                         "Restoring to %%eip 0x%lx\n", eip);
             return 0; /* do not update eip! */
         }
+    }
+    else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
+    {
+        /* we should take care of this kind of situation */
+        clear_all_shadow_status(v->domain);
+        __vmwrite(GUEST_CR3, pagetable_get_paddr(v->domain->arch.phys_table));
     }
 
     return 1;
@@ -1528,11 +1597,11 @@ static int mov_to_cr(int gp, int cr, str
 
             if ( vmx_pgbit_test(v) )
             {
-                /* The guest is 32 bit. */
+                /* The guest is a 32-bit PAE guest. */
 #if CONFIG_PAGING_LEVELS >= 4
                 unsigned long mfn, old_base_mfn;
 
-                if( !shadow_set_guest_paging_levels(v->domain, 3) )
+                if( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) )
                 {
                     printk("Unsupported guest paging levels\n");
                     domain_crash_synchronous(); /* need to take a clean path */
@@ -1572,12 +1641,31 @@ static int mov_to_cr(int gp, int cr, str
             }
             else
             {
-                /*  The guest is 64 bit. */
+                /*  The guest is a 64 bit or 32-bit PAE guest. */
 #if CONFIG_PAGING_LEVELS >= 4
-                if ( !shadow_set_guest_paging_levels(v->domain, 4) )
+                if ( (v->domain->arch.ops != NULL) &&
+                        v->domain->arch.ops->guest_paging_levels == PAGING_L2)
                 {
-                    printk("Unsupported guest paging levels\n");
-                    domain_crash_synchronous(); /* need to take a clean path */
+                    /* Seems the guest first enables PAE without enabling PG,
+                     * it must enable PG after that, and it is a 32-bit PAE
+                     * guest */
+
+                    if ( !shadow_set_guest_paging_levels(v->domain,
+                                                            PAGING_L3) )
+                    {
+                        printk("Unsupported guest paging levels\n");
+                        /* need to take a clean path */
+                        domain_crash_synchronous();
+                    }
+                }
+                else
+                {
+                    if ( !shadow_set_guest_paging_levels(v->domain,
+                                                            PAGING_L4) )
+                    {
+                        printk("Unsupported guest paging levels\n");
+                        domain_crash_synchronous();
+                    }
                 }
 #endif
             }
@@ -1827,6 +1915,7 @@ static inline void vmx_vmexit_do_extint(
 
     vector &= 0xff;
     local_irq_disable();
+    TRACE_VMEXIT(1,vector);
 
     switch(vector) {
     case LOCAL_TIMER_VECTOR:
@@ -1956,7 +2045,6 @@ asmlinkage void vmx_vmexit_handler(struc
 
     {
         __vmread(GUEST_RIP, &eip);
-        TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason);
         TRACE_VMEXIT(0,exit_reason);
     }
 
@@ -1980,7 +2068,6 @@ asmlinkage void vmx_vmexit_handler(struc
         TRACE_VMEXIT(1,vector);
         perfc_incra(cause_vector, vector);
 
-        TRACE_3D(TRC_VMX_VECTOR, v->domain->domain_id, eip, vector);
         switch (vector) {
 #ifdef XEN_DEBUGGER
         case TRAP_debug:
@@ -2164,7 +2251,7 @@ asmlinkage void vmx_load_cr2(void)
 
 asmlinkage void vmx_trace_vmentry (void)
 {
-    TRACE_5D(TRC_VMENTRY,
+    TRACE_5D(TRC_VMX_VMENTRY,
              trace_values[smp_processor_id()][0],
              trace_values[smp_processor_id()][1],
              trace_values[smp_processor_id()][2],
@@ -2180,7 +2267,7 @@ asmlinkage void vmx_trace_vmentry (void)
 
 asmlinkage void vmx_trace_vmexit (void)
 {
-    TRACE_3D(TRC_VMEXIT,0,0,0);
+    TRACE_3D(TRC_VMX_VMEXIT,0,0,0);
     return;
 }
 
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/mm.c Tue Mar 28 08:54:58 2006 -0700
@@ -3351,8 +3351,9 @@ int ptwr_do_page_fault(struct domain *d,
      * permissions in page directories by writing back to the linear mapping.
      */
     if ( (flags = l1e_get_flags(pte) & WRPT_PTE_FLAGS) == WRPT_PTE_FLAGS )
-        return !__put_user(
-            pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1);
+        return __put_user(
+            pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1) ?
+            0 : EXCRET_not_a_fault;
 
     /* We are looking only for read-only mappings of p.t. pages. */
     if ( ((flags | _PAGE_RW) != WRPT_PTE_FLAGS) ||
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/shadow.c     Tue Mar 28 08:54:58 2006 -0700
@@ -1807,6 +1807,16 @@ static int resync_all(struct domain *d, 
                   entry_has_changed(
                       guest_pt[i], snapshot_pt[i], PAGE_FLAG_MASK) )
                 {
+
+                    unsigned long gpfn;
+
+                    gpfn = entry_get_pfn(guest_pt[i]);
+                    /*
+                     * Looks like it's longer a page table.
+                     */
+                    if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) )
+                        continue;
+
                     need_flush |= validate_entry_change(
                         d, &guest_pt[i], &shadow_pt[i],
                         shadow_type_to_level(stype));
@@ -1851,6 +1861,14 @@ static int resync_all(struct domain *d, 
                 {
 #ifndef GUEST_PGENTRY_32
                     l4_pgentry_t *shadow4 = shadow;
+                    unsigned long gpfn;
+
+                    gpfn = l4e_get_pfn(new_root_e);
+                    /*
+                     * Looks like it's longer a page table.
+                     */
+                    if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) )
+                        continue;
 
                     if ( d->arch.ops->guest_paging_levels == PAGING_L4 ) 
                     {
@@ -1894,7 +1912,7 @@ static int resync_all(struct domain *d, 
         unmap_domain_page(snapshot);
         unmap_domain_page(guest);
 
-        if ( unlikely(unshadow) )
+        if ( unlikely(unshadow && stype == PGT_root_page_table) )
         {
             for_each_vcpu(d, v)
                 if(smfn == pagetable_get_pfn(v->arch.shadow_table))
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c        Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/smp.c        Tue Mar 28 08:54:58 2006 -0700
@@ -106,6 +106,16 @@ void send_IPI_self(int vector)
     __send_IPI_shortcut(APIC_DEST_SELF, vector);
 }
 
+static inline void check_IPI_mask(cpumask_t cpumask)
+{
+    /*
+     * Sanity, and necessary. An IPI with no target generates a send accept
+     * error with Pentium and P6 APICs.
+     */
+    ASSERT(cpus_subset(cpumask, cpu_online_map));
+    ASSERT(!cpus_empty(cpumask));
+}
+
 /*
  * This is only used on smaller machines.
  */
@@ -115,6 +125,8 @@ void send_IPI_mask_bitmask(cpumask_t cpu
     unsigned long cfg;
     unsigned long flags;
 
+    check_IPI_mask(cpumask);
+
     local_irq_save(flags);
 
     /*
@@ -145,6 +157,8 @@ inline void send_IPI_mask_sequence(cpuma
 {
     unsigned long cfg, flags;
     unsigned int query_cpu;
+
+    check_IPI_mask(mask);
 
     /*
      * Hack. The clustered APIC addressing mode doesn't allow us to send 
@@ -304,6 +318,9 @@ extern int on_selected_cpus(
 
     ASSERT(local_irq_is_enabled());
 
+    if ( nr_cpus == 0 )
+        return 0;
+
     data.func = func;
     data.info = info;
     data.wait = wait;
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/traps.c      Tue Mar 28 08:54:58 2006 -0700
@@ -286,7 +286,7 @@ asmlinkage void fatal_trap(int trapnr, s
     unsigned long cr2;
     static char *trapstr[] = { 
         "divide error", "debug", "nmi", "bkpt", "overflow", "bounds", 
-        "invalid operation", "device not available", "double fault", 
+        "invalid opcode", "device not available", "double fault", 
         "coprocessor segment", "invalid tss", "segment not found", 
         "stack error", "general protection fault", "page fault", 
         "spurious interrupt", "coprocessor error", "alignment check", 
@@ -382,7 +382,6 @@ DO_ERROR_NOCODE( 0, "divide error", divi
 DO_ERROR_NOCODE( 0, "divide error", divide_error)
 DO_ERROR_NOCODE( 4, "overflow", overflow)
 DO_ERROR_NOCODE( 5, "bounds", bounds)
-DO_ERROR_NOCODE( 6, "invalid operand", invalid_op)
 DO_ERROR_NOCODE( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
 DO_ERROR(10, "invalid TSS", invalid_TSS)
 DO_ERROR(11, "segment not present", segment_not_present)
@@ -391,6 +390,85 @@ DO_ERROR(17, "alignment check", alignmen
 DO_ERROR(17, "alignment check", alignment_check)
 DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
 
+static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
+{
+    char signature[5], instr[2];
+    unsigned long a, b, c, d, eip;
+
+    a = regs->eax;
+    b = regs->ebx;
+    c = regs->ecx;
+    d = regs->edx;
+    eip = regs->eip;
+
+    /* Check for forced emulation signature: ud2 ; .ascii "xen". */
+    if ( copy_from_user(signature, (char *)eip, sizeof(signature)) ||
+         memcmp(signature, "\xf\xbxen", sizeof(signature)) )
+        return 0;
+    eip += sizeof(signature);
+
+    /* We only emulate CPUID. */
+    if ( copy_from_user(instr, (char *)eip, sizeof(instr)) ||
+         memcmp(instr, "\xf\xa2", sizeof(instr)) )
+        return 0;
+    eip += sizeof(instr);
+
+    __asm__ ( 
+        "cpuid"
+        : "=a" (a), "=b" (b), "=c" (c), "=d" (d)
+        : "0" (a), "1" (b), "2" (c), "3" (d) );
+
+    if ( regs->eax == 1 )
+    {
+        /* Modify Feature Information. */
+        clear_bit(X86_FEATURE_VME, &d);
+        clear_bit(X86_FEATURE_DE,  &d);
+        clear_bit(X86_FEATURE_PSE, &d);
+        clear_bit(X86_FEATURE_PGE, &d);
+        clear_bit(X86_FEATURE_SEP, &d);
+        if ( !IS_PRIV(current->domain) )
+            clear_bit(X86_FEATURE_MTRR, &d);
+    }
+
+    regs->eax = a;
+    regs->ebx = b;
+    regs->ecx = c;
+    regs->edx = d;
+    regs->eip = eip;
+
+    return EXCRET_fault_fixed;
+}
+
+asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
+{
+    struct vcpu *v = current;
+    struct trap_bounce *tb = &v->arch.trap_bounce;
+    struct trap_info *ti;
+    int rc;
+
+    DEBUGGER_trap_entry(TRAP_invalid_op, regs);
+
+    if ( unlikely(!guest_mode(regs)) )
+    {
+        DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+        show_registers(regs);
+        panic("CPU%d FATAL TRAP: vector = %d (invalid opcode)\n",
+              smp_processor_id(), TRAP_invalid_op);
+    }
+
+    if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
+        return rc;
+
+    ti = &current->arch.guest_context.trap_ctxt[TRAP_invalid_op];
+    tb->flags = TBF_EXCEPTION;
+    tb->cs    = ti->cs;
+    tb->eip   = ti->address;
+    if ( TI_GET_IF(ti) )
+        tb->flags |= TBF_INTERRUPT;
+
+    return 0;
+}
+
 asmlinkage int do_int3(struct cpu_user_regs *regs)
 {
     struct vcpu *v = current;
@@ -540,6 +618,46 @@ static int fixup_page_fault(unsigned lon
     }
 
     return 0;
+}
+
+static int spurious_page_fault(unsigned long addr, struct cpu_user_regs *regs)
+{
+    struct vcpu   *v = current;
+    struct domain *d = v->domain;
+    int            rc;
+
+    /*
+     * The only possible reason for a spurious page fault not to be picked
+     * up already is that a page directory was unhooked by writable page table
+     * logic and then reattached before the faulting VCPU could detect it.
+     */
+    if ( is_idle_domain(d) ||               /* no ptwr in idle domain       */
+         IN_HYPERVISOR_RANGE(addr) ||       /* no ptwr on hypervisor addrs  */
+         shadow_mode_enabled(d) ||          /* no ptwr logic in shadow mode */
+         ((regs->error_code & 0x1d) != 0) ) /* simple not-present fault?    */
+        return 0;
+
+    LOCK_BIGLOCK(d);
+
+    /*
+     * The page directory could have been detached again while we weren't
+     * holding the per-domain lock. Detect that and fix up if it's the case.
+     */
+    if ( unlikely(d->arch.ptwr[PTWR_PT_ACTIVE].l1va) &&
+         unlikely(l2_linear_offset(addr) ==
+                  d->arch.ptwr[PTWR_PT_ACTIVE].l2_idx) )
+    {
+        ptwr_flush(d, PTWR_PT_ACTIVE);
+        rc = 1;
+    }
+    else
+    {
+        /* Okay, walk the page tables. Only check for not-present faults.*/
+        rc = __spurious_page_fault(addr);
+    }
+
+    UNLOCK_BIGLOCK(d);
+    return rc;
 }
 
 /*
@@ -566,6 +684,13 @@ asmlinkage int do_page_fault(struct cpu_
 
     if ( unlikely(!guest_mode(regs)) )
     {
+        if ( spurious_page_fault(addr, regs) )
+        {
+            DPRINTK("Spurious fault in domain %u:%u at addr %lx\n",
+                    current->domain->domain_id, current->vcpu_id, addr);
+            return EXCRET_not_a_fault;
+        }
+
         if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
         {
             perfc_incrc(copy_user_faults);
@@ -580,7 +705,7 @@ asmlinkage int do_page_fault(struct cpu_
         panic("CPU%d FATAL PAGE FAULT\n"
               "[error_code=%04x]\n"
               "Faulting linear address: %p\n",
-              smp_processor_id(), regs->error_code, addr);
+              smp_processor_id(), regs->error_code, _p(addr));
     }
 
     propagate_page_fault(addr, regs->error_code);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/x86_32/traps.c       Tue Mar 28 08:54:58 2006 -0700
@@ -27,8 +27,7 @@ void show_registers(struct cpu_user_regs
     if ( hvm_guest(current) && guest_mode(regs) )
     {
         context = "hvm";
-        hvm_store_cpu_guest_regs(current, &fault_regs);
-        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
+        hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
     }
     else
     {
@@ -71,38 +70,77 @@ void show_registers(struct cpu_user_regs
 
 void show_page_walk(unsigned long addr)
 {
+    unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;
+#ifdef CONFIG_X86_PAE
+    l3_pgentry_t l3e, *l3t;
+#endif
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
+    printk("Pagetable walk from %08lx:\n", addr);
+
+#ifdef CONFIG_X86_PAE
+    l3t = map_domain_page(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk(" L3 = %"PRIpte" %08lx\n", l3e_get_intpte(l3e), pfn);
+    unmap_domain_page(l3t);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return;
+#endif
+
+    l2t = map_domain_page(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("  L2 = %"PRIpte" %08lx %s\n", l2e_get_intpte(l2e), pfn, 
+           (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
+    unmap_domain_page(l2t);
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
+         (l2e_get_flags(l2e) & _PAGE_PSE) )
+        return;
+
+    l1t = map_domain_page(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("   L1 = %"PRIpte" %08lx\n", l1e_get_intpte(l1e), pfn);
+    unmap_domain_page(l1t);
+}
+
+int __spurious_page_fault(unsigned long addr)
+{
     unsigned long mfn = read_cr3() >> PAGE_SHIFT;
-    intpte_t *ptab, ent;
-    unsigned long pfn; 
-
-    printk("Pagetable walk from %08lx:\n", addr);
-
 #ifdef CONFIG_X86_PAE
-    ptab = map_domain_page(mfn);
-    ent  = ptab[l3_table_offset(addr)];
-    pfn  = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT)); 
-    printk(" L3 = %"PRIpte" %08lx\n", ent, pfn);
-    unmap_domain_page(ptab);
-    if ( !(ent & _PAGE_PRESENT) )
-        return;
-    mfn = ent >> PAGE_SHIFT;
+    l3_pgentry_t l3e, *l3t;
 #endif
-
-    ptab = map_domain_page(mfn);
-    ent  = ptab[l2_table_offset(addr)];
-    pfn  = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT));
-    printk("  L2 = %"PRIpte" %08lx %s\n", ent, pfn, 
-           (ent & _PAGE_PSE) ? "(PSE)" : "");
-    unmap_domain_page(ptab);
-    if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
-        return;
-    mfn = ent >> PAGE_SHIFT;
-
-    ptab = map_domain_page(ent >> PAGE_SHIFT);
-    ent  = ptab[l1_table_offset(addr)];
-    pfn  = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT));
-    printk("   L1 = %"PRIpte" %08lx\n", ent, pfn);
-    unmap_domain_page(ptab);
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
+#ifdef CONFIG_X86_PAE
+    l3t = map_domain_page(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    unmap_domain_page(l3t);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return 0;
+#endif
+
+    l2t = map_domain_page(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    unmap_domain_page(l2t);
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+        return 0;
+    if ( l2e_get_flags(l2e) & _PAGE_PSE )
+        return 1;
+
+    l1t = map_domain_page(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    unmap_domain_page(l1t);
+    return !!(l1e_get_flags(l1e) & _PAGE_PRESENT);
 }
 
 #define DOUBLEFAULT_STACK_SIZE 1024
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/x86_64/traps.c       Tue Mar 28 08:54:58 2006 -0700
@@ -27,8 +27,7 @@ void show_registers(struct cpu_user_regs
     if ( hvm_guest(current) && guest_mode(regs) )
     {
         context = "hvm";
-        hvm_store_cpu_guest_regs(current, &fault_regs);
-        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
+        hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
     }
     else
     {
@@ -71,31 +70,79 @@ void show_registers(struct cpu_user_regs
 
 void show_page_walk(unsigned long addr)
 {
-    unsigned long page = read_cr3();
-    
+    unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;
+    l4_pgentry_t l4e, *l4t;
+    l3_pgentry_t l3e, *l3t;
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
     printk("Pagetable walk from %016lx:\n", addr);
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
-    printk(" L4 = %016lx\n", page);
-    if ( !(page & _PAGE_PRESENT) )
+    l4t = mfn_to_virt(mfn);
+    l4e = l4t[l4_table_offset(addr)];
+    mfn = l4e_get_pfn(l4e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk(" L4 = %"PRIpte" %016lx\n", l4e_get_intpte(l4e), pfn);
+    if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
         return;
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
-    printk("  L3 = %016lx\n", page);
-    if ( !(page & _PAGE_PRESENT) )
+    l3t = mfn_to_virt(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("  L3 = %"PRIpte" %016lx\n", l3e_get_intpte(l3e), pfn);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
         return;
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
-    printk("   L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
-    if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
+    l2t = mfn_to_virt(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("   L2 = %"PRIpte" %016lx %s\n", l2e_get_intpte(l2e), pfn,
+           (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
+         (l2e_get_flags(l2e) & _PAGE_PSE) )
         return;
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
-    printk("    L1 = %016lx\n", page);
+    l1t = mfn_to_virt(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("    L1 = %"PRIpte" %016lx\n", l1e_get_intpte(l1e), pfn);
+}
+
+int __spurious_page_fault(unsigned long addr)
+{
+    unsigned long mfn = read_cr3() >> PAGE_SHIFT;
+    l4_pgentry_t l4e, *l4t;
+    l3_pgentry_t l3e, *l3t;
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
+    l4t = mfn_to_virt(mfn);
+    l4e = l4t[l4_table_offset(addr)];
+    mfn = l4e_get_pfn(l4e);
+    if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
+        return 0;
+
+    l3t = mfn_to_virt(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return 0;
+
+    l2t = mfn_to_virt(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+        return 0;
+    if ( l2e_get_flags(l2e) & _PAGE_PSE )
+        return 1;
+
+    l1t = mfn_to_virt(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    return !!(l1e_get_flags(l1e) & _PAGE_PRESENT);
 }
 
 asmlinkage void double_fault(void);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/common/gdbstub.c
--- a/xen/common/gdbstub.c      Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/common/gdbstub.c      Tue Mar 28 08:54:58 2006 -0700
@@ -562,6 +562,7 @@ initialise_gdb(void)
     gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
     if ( gdb_ctx->serhnd != -1 )
         printk("GDB stub initialised.\n");
+    serial_start_sync(gdb_ctx->serhnd);
 }
 
 /*
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/common/page_alloc.c   Tue Mar 28 08:54:58 2006 -0700
@@ -219,8 +219,6 @@ unsigned long alloc_boot_pages(unsigned 
 #define pfn_dom_zone_type(_pfn)                                 \
     (((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM)
 
-/* Up to 2^20 pages can be allocated at once. */
-#define MAX_ORDER 20
 static struct list_head heap[NR_ZONES][MAX_ORDER+1];
 
 static unsigned long avail[NR_ZONES];
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/drivers/char/ns16550.c        Tue Mar 28 08:54:58 2006 -0700
@@ -121,8 +121,11 @@ static void ns16550_interrupt(
 
     while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
     {
-        serial_tx_interrupt(port, regs);
-        serial_rx_interrupt(port, regs);
+        char lsr = ns_read_reg(uart, LSR);
+        if ( lsr & LSR_THRE )
+            serial_tx_interrupt(port, regs);
+        if ( lsr & LSR_DR )
+            serial_rx_interrupt(port, regs);
     }
 }
 
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/drivers/char/serial.c
--- a/xen/drivers/char/serial.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/drivers/char/serial.c Tue Mar 28 08:54:58 2006 -0700
@@ -7,6 +7,7 @@
  */
 
 #include <xen/config.h>
+#include <xen/delay.h>
 #include <xen/init.h>
 #include <xen/irq.h>
 #include <xen/keyhandler.h> 
@@ -15,8 +16,8 @@
 #include <xen/serial.h>
 
 static struct serial_port com[2] = {
-    { .lock = SPIN_LOCK_UNLOCKED }, 
-    { .lock = SPIN_LOCK_UNLOCKED }
+    { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }, 
+    { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }
 };
 
 void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
@@ -25,7 +26,7 @@ void serial_rx_interrupt(struct serial_p
     serial_rx_fn fn = NULL;
     unsigned long flags;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->rx_lock, flags);
 
     if ( port->driver->getc(port, &c) )
     {
@@ -39,7 +40,7 @@ void serial_rx_interrupt(struct serial_p
             port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufp++)] = c;            
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->rx_lock, flags);
 
     if ( fn != NULL )
         (*fn)(c & 0x7f, regs);
@@ -50,7 +51,19 @@ void serial_tx_interrupt(struct serial_p
     int i;
     unsigned long flags;
 
-    spin_lock_irqsave(&port->lock, flags);
+    local_irq_save(flags);
+
+    /*
+     * Avoid spinning for a long time: if there is a long-term lock holder
+     * then we know that they'll be stuffing bytes into the transmitter which
+     * will therefore not be empty for long.
+     */
+    while ( !spin_trylock(&port->tx_lock) )
+    {
+        if ( !port->driver->tx_empty(port) )
+            return;
+        cpu_relax();
+    }
 
     if ( port->driver->tx_empty(port) )
     {
@@ -63,7 +76,7 @@ void serial_tx_interrupt(struct serial_p
         }
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 static void __serial_putc(struct serial_port *port, char c)
@@ -117,7 +130,7 @@ void serial_putc(int handle, char c)
     if ( (handle == -1) || !port->driver || !port->driver->putc )
         return;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     if ( (c == '\n') && (handle & SERHND_COOKED) )
         __serial_putc(port, '\r');
@@ -129,7 +142,7 @@ void serial_putc(int handle, char c)
 
     __serial_putc(port, c);
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 void serial_puts(int handle, const char *s)
@@ -141,7 +154,7 @@ void serial_puts(int handle, const char 
     if ( (handle == -1) || !port->driver || !port->driver->putc )
         return;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     while ( (c = *s++) != '\0' )
     {
@@ -156,7 +169,7 @@ void serial_puts(int handle, const char 
         __serial_putc(port, c);
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 char serial_getc(int handle)
@@ -168,27 +181,28 @@ char serial_getc(int handle)
     if ( (handle == -1) || !port->driver || !port->driver->getc )
         return '\0';
 
-    do {        
+    do {
         for ( ; ; )
         {
-            spin_lock_irqsave(&port->lock, flags);
+            spin_lock_irqsave(&port->rx_lock, flags);
             
             if ( port->rxbufp != port->rxbufc )
             {
                 c = port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufc++)];
-                spin_unlock_irqrestore(&port->lock, flags);
+                spin_unlock_irqrestore(&port->rx_lock, flags);
                 break;
             }
             
             if ( port->driver->getc(port, &c) )
             {
-                spin_unlock_irqrestore(&port->lock, flags);
+                spin_unlock_irqrestore(&port->rx_lock, flags);
                 break;
             }
 
-            spin_unlock_irqrestore(&port->lock, flags);
+            spin_unlock_irqrestore(&port->rx_lock, flags);
 
             cpu_relax();
+            udelay(100);
         }
     } while ( ((handle & SERHND_LO) &&  (c & 0x80)) ||
               ((handle & SERHND_HI) && !(c & 0x80)) );
@@ -241,7 +255,7 @@ void serial_set_rx_handler(int handle, s
     if ( handle == -1 )
         return;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->rx_lock, flags);
 
     if ( port->rx != NULL )
         goto fail;
@@ -265,11 +279,11 @@ void serial_set_rx_handler(int handle, s
         port->rx = fn;
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->rx_lock, flags);
     return;
 
  fail:
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->rx_lock, flags);
     printk("ERROR: Conflicting receive handlers for COM%d\n", 
            handle & SERHND_IDX);
 }
@@ -277,8 +291,13 @@ void serial_force_unlock(int handle)
 void serial_force_unlock(int handle)
 {
     struct serial_port *port = &com[handle & SERHND_IDX];
-    if ( handle != -1 )
-        port->lock = SPIN_LOCK_UNLOCKED;
+
+    if ( handle == -1 )
+        return;
+
+    port->rx_lock = SPIN_LOCK_UNLOCKED;
+    port->tx_lock = SPIN_LOCK_UNLOCKED;
+
     serial_start_sync(handle);
 }
 
@@ -290,7 +309,7 @@ void serial_start_sync(int handle)
     if ( handle == -1 )
         return;
     
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     if ( port->sync++ == 0 )
     {
@@ -303,7 +322,7 @@ void serial_start_sync(int handle)
         }
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 void serial_end_sync(int handle)
@@ -314,11 +333,11 @@ void serial_end_sync(int handle)
     if ( handle == -1 )
         return;
     
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     port->sync--;
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 int serial_tx_space(int handle)
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/asm-x86/hvm/hvm.h     Tue Mar 28 08:54:58 2006 -0700
@@ -41,12 +41,12 @@ struct hvm_function_table {
     /*
      * Store and load guest state:
      * 1) load/store guest register state,
-     * 2) store guest control register state (used for panic dumps),
-     * 3) modify guest state (e.g., set debug flags).
+     * 2) modify guest state (e.g., set debug flags).
      */
-    void (*store_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
-    void (*load_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
-    void (*store_cpu_guest_ctrl_regs)(struct vcpu *v, unsigned long crs[8]);
+    void (*store_cpu_guest_regs)(
+        struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);
+    void (*load_cpu_guest_regs)(
+        struct vcpu *v, struct cpu_user_regs *r);
     void (*modify_guest_state)(struct vcpu *v);
 
     /*
@@ -93,21 +93,16 @@ hvm_relinquish_guest_resources(struct do
 }
 
 static inline void
-hvm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
+hvm_store_cpu_guest_regs(
+    struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs)
 {
-    hvm_funcs.store_cpu_guest_regs(v, r);
+    hvm_funcs.store_cpu_guest_regs(v, r, crs);
 }
 
 static inline void
 hvm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
 {
     hvm_funcs.load_cpu_guest_regs(v, r);
-}
-
-static inline void
-hvm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
-    hvm_funcs.store_cpu_guest_ctrl_regs(v, crs);
 }
 
 static inline void
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/asm-x86/hvm/svm/svm.h
--- a/xen/include/asm-x86/hvm/svm/svm.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/asm-x86/hvm/svm/svm.h Tue Mar 28 08:54:58 2006 -0700
@@ -48,6 +48,8 @@ extern void svm_stts(struct vcpu *v);
 extern void svm_stts(struct vcpu *v); 
 extern void svm_do_launch(struct vcpu *v);
 extern void svm_do_resume(struct vcpu *v);
+extern void svm_set_guest_time(struct vcpu *v, u64 gtime);
+extern u64 svm_get_guest_time(struct vcpu *v);
 extern void arch_svm_do_resume(struct vcpu *v);
 extern int load_vmcb(struct arch_svm_struct *arch_svm, u64 phys_hsa);
 /* For debugging. Remove when no longer needed. */
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/asm-x86/processor.h   Tue Mar 28 08:54:58 2006 -0700
@@ -524,6 +524,7 @@ void show_stack(struct cpu_user_regs *re
 void show_stack(struct cpu_user_regs *regs);
 void show_registers(struct cpu_user_regs *regs);
 void show_page_walk(unsigned long addr);
+int __spurious_page_fault(unsigned long addr);
 asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
 
 extern void mtrr_ap_init(void);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h  Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/arch-x86_32.h  Tue Mar 28 08:54:58 2006 -0700
@@ -170,6 +170,18 @@ typedef struct {
 
 #endif /* !__ASSEMBLY__ */
 
+/*
+ * Prefix forces emulation of some non-trapping instructions.
+ * Currently only CPUID.
+ */
+#ifdef __ASSEMBLY__
+#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
+#define XEN_CPUID          XEN_EMULATE_PREFIX cpuid
+#else
+#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
+#define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
+#endif
+
 #endif
 
 /*
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h  Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/arch-x86_64.h  Tue Mar 28 08:54:58 2006 -0700
@@ -246,6 +246,18 @@ typedef struct {
 
 #endif /* !__ASSEMBLY__ */
 
+/*
+ * Prefix forces emulation of some non-trapping instructions.
+ * Currently only CPUID.
+ */
+#ifdef __ASSEMBLY__
+#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
+#define XEN_CPUID          XEN_EMULATE_PREFIX cpuid
+#else
+#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
+#define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
+#endif
+
 #endif
 
 /*
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/io/netif.h     Tue Mar 28 08:54:58 2006 -0700
@@ -20,8 +20,12 @@
  */
 
 /* Protocol checksum field is blank in the packet (hardware offload)? */
-#define _NETTXF_csum_blank (0)
-#define  NETTXF_csum_blank (1U<<_NETTXF_csum_blank)
+#define _NETTXF_csum_blank     (0)
+#define  NETTXF_csum_blank     (1U<<_NETTXF_csum_blank)
+
+/* Packet data has been validated against protocol checksum. */
+#define _NETTXF_data_validated (1)
+#define  NETTXF_data_validated (1U<<_NETTXF_data_validated)
 
 typedef struct netif_tx_request {
     grant_ref_t gref;      /* Reference to buffer page */
@@ -41,9 +45,13 @@ typedef struct {
     grant_ref_t gref;      /* Reference to incoming granted frame */
 } netif_rx_request_t;
 
-/* Protocol checksum already validated (e.g., performed by hardware)? */
-#define _NETRXF_csum_valid (0)
-#define  NETRXF_csum_valid (1U<<_NETRXF_csum_valid)
+/* Packet data has been validated against protocol checksum. */
+#define _NETRXF_data_validated (0)
+#define  NETRXF_data_validated (1U<<_NETRXF_data_validated)
+
+/* Protocol checksum field is blank in the packet (hardware offload)? */
+#define _NETRXF_csum_blank     (1)
+#define  NETRXF_csum_blank     (1U<<_NETRXF_csum_blank)
 
 typedef struct {
     uint16_t id;
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/trace.h
--- a/xen/include/public/trace.h        Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/trace.h        Tue Mar 28 08:54:58 2006 -0700
@@ -24,7 +24,6 @@
 #define TRC_VMXTIMER 0x00082000   /* VMX timer trace           */
 #define TRC_VMXINT   0x00084000   /* VMX interrupt trace       */
 #define TRC_VMXIO    0x00088000   /* VMX io emulation trace  */
-#define TRC_VMEXIT_HANDLER    0x00090000   /* VMX handler trace  */
 
 /* Trace events per class */
 
@@ -50,14 +49,11 @@
 
 /* trace events per subclass */
 #define TRC_VMX_VMEXIT          (TRC_VMXEXIT + 1)
-#define TRC_VMX_VECTOR          (TRC_VMXEXIT + 2)
+#define TRC_VMX_VMENTRY         (TRC_VMXEXIT + 2)
 
 #define TRC_VMX_TIMER_INTR      (TRC_VMXTIMER + 1)
 
 #define TRC_VMX_INT             (TRC_VMXINT + 1)
-
-#define TRC_VMEXIT              (TRC_VMEXIT_HANDLER + 1)
-#define TRC_VMENTRY             (TRC_VMEXIT_HANDLER + 2)
 
 
 /* This structure represents a single trace buffer record. */
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/xen/lib.h
--- a/xen/include/xen/lib.h     Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/xen/lib.h     Tue Mar 28 08:54:58 2006 -0700
@@ -47,7 +47,8 @@ extern void debugtrace_printk(const char
 #define printk(_f , _a...) printf( _f , ## _a )
 extern void printf(const char *format, ...)
     __attribute__ ((format (printf, 1, 2)));
-extern void panic(const char *format, ...);
+extern void panic(const char *format, ...)
+    __attribute__ ((format (printf, 1, 2)));
 extern long vm_assist(struct domain *, unsigned int, unsigned int);
 
 /* vsprintf.c */
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/xen/mm.h      Tue Mar 28 08:54:58 2006 -0700
@@ -68,6 +68,9 @@ unsigned long avail_domheap_pages(void);
 
 #define ALLOC_DOM_DMA 1
 
+/* Up to 2^20 pages can be allocated at once. */
+#define MAX_ORDER 20
+
 /* Automatic page scrubbing for dead domains. */
 extern struct list_head page_scrub_list;
 #define page_scrub_schedule_work()              \
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/xen/serial.h
--- a/xen/include/xen/serial.h  Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/xen/serial.h  Tue Mar 28 08:54:58 2006 -0700
@@ -42,7 +42,7 @@ struct serial_port {
     char                rxbuf[SERIAL_RXBUFSZ];
     unsigned int        rxbufp, rxbufc;
     /* Serial I/O is concurrency-safe. */
-    spinlock_t          lock;
+    spinlock_t          rx_lock, tx_lock;
 };
 
 struct uart_driver {
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xen_ia64
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/buildconfigs/linux-defconfig_xen_ia64     Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,1523 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16-xen
+# Mon Mar 27 14:36:21 2006
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Processor type and features
+#
+CONFIG_IA64=y
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_SWIOTLB=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_TIME_INTERPOLATION=y
+CONFIG_EFI=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_XEN=y
+CONFIG_ARCH_XEN=y
+CONFIG_XEN_PRIVILEGED_GUEST=y
+CONFIG_XEN_BLKDEV_GRANT=y
+CONFIG_XEN_BLKDEV_FRONTEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_SYSFS=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_DMA_IS_DMA32=y
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_PGTABLE_3=y
+# CONFIG_PGTABLE_4 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_CYCLONE=y
+CONFIG_IOSAPIC=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_SMT is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+# CONFIG_VIRTUAL_MEM_MAP is not set
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+
+#
+# Firmware Drivers
+#
+CONFIG_EFI_VARS=y
+CONFIG_EFI_PCDP=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management and ACPI
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_ACPI=y
+# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_QLOGIC_1280=y
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_DM is not set
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=y
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=y
+
+#
+# ARCnet devices
+#
+CONFIG_ARCNET=y
+# CONFIG_ARCNET_1201 is not set
+# CONFIG_ARCNET_1051 is not set
+# CONFIG_ARCNET_RAW is not set
+# CONFIG_ARCNET_CAP is not set
+# CONFIG_ARCNET_COM90xx is not set
+# CONFIG_ARCNET_COM90xxIO is not set
+# CONFIG_ARCNET_RIM_I is not set
+# CONFIG_ARCNET_COM20020 is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+CONFIG_TULIP_MWI=y
+CONFIG_TULIP_MMIO=y
+CONFIG_TULIP_NAPI=y
+CONFIG_TULIP_NAPI_HW_MITIGATION=y
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+# CONFIG_ISDN_I4L is not set
+
+#
+# CAPI subsystem
+#
+# CONFIG_ISDN_CAPI is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=y
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_FM801 is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_EFI_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_I460=y
+CONFIG_DRM=y
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_R128 is not set
+# CONFIG_DRM_RADEON is not set
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=y
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_DPC is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_VIDEO_AUDIO_DECODER is not set
+# CONFIG_VIDEO_DECODER is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_DEBUG=y
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_SEQ_DUMMY=y
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=y
+CONFIG_SND_OPL3_LIB=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
+CONFIG_SND_DUMMY=y
+CONFIG_SND_VIRMIDI=y
+CONFIG_SND_MTPAV=y
+CONFIG_SND_SERIAL_U16550=y
+CONFIG_SND_MPU401=y
+
+#
+# PCI devices
+#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALI5451 is not set
+CONFIG_SND_ATIIXP=y
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+CONFIG_SND_FM801=y
+CONFIG_SND_FM801_TEA575X=y
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_BANDWIDTH=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_PWC is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=y
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+# CONFIG_NLS_CODEPAGE_1250 is not set
+CONFIG_NLS_CODEPAGE_1251=y
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_IA64_GRANULE_16MB=y
+# CONFIG_IA64_GRANULE_64MB is not set
+CONFIG_IA64_PRINT_HAZARDS=y
+# CONFIG_DISABLE_VHPT is not set
+# CONFIG_IA64_DEBUG_CMPXCHG is not set
+# CONFIG_IA64_DEBUG_IRQ is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/console.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/console.h  Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,49 @@
+/* 
+ ****************************************************************************
+ * (C) 2006 - Grzegorz Milos - Cambridge University
+ ****************************************************************************
+ *
+ *        File: console.h
+ *      Author: Grzegorz Milos
+ *     Changes: 
+ *              
+ *        Date: Mar 2006
+ * 
+ * Environment: Xen Minimal OS
+ * Description: Console interface.
+ *
+ * Handles console I/O. Defines printk.
+ *
+ ****************************************************************************
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _LIB_CONSOLE_H_
+#define _LIB_CONSOLE_H_
+
+#include<traps.h>
+
+void printk(const char *fmt, ...);
+void xprintk(const char *fmt, ...);
+
+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
+void xencons_tx(void);
+
+void init_console(void);
+
+#endif /* _LIB_CONSOLE_H_ */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/xenbus/xenbus.c    Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,387 @@
+/* 
+ ****************************************************************************
+ * (C) 2006 - Cambridge University
+ ****************************************************************************
+ *
+ *        File: mm.c
+ *      Author: Steven Smith (sos22@xxxxxxxxx) 
+ *     Changes: Grzegorz Milos (gm281@xxxxxxxxx)
+ *              
+ *        Date: Mar 2006, chages Aug 2005
+ * 
+ * Environment: Xen Minimal OS
+ * Description: Minimal implementation of xenbus
+ *
+ ****************************************************************************
+ **/
+#include <os.h>
+#include <mm.h>
+#include <traps.h>
+#include <lib.h>
+#include <xenbus.h>
+#include <events.h>
+#include <errno.h>
+#include <sched.h>
+#include <wait.h>
+#include <xen/io/xs_wire.h>
+#include <spinlock.h>
+#include <xmalloc.h>
+
+#define BUG_ON(x) do { \
+    if (x) {printk("BUG at %s:%d\n", __FILE__, __LINE__); BUG(); } \
+} while (0)
+
+#define min(x,y) ({                       \
+        typeof(x) tmpx = (x);                 \
+        typeof(y) tmpy = (y);                 \
+        tmpx < tmpy ? tmpx : tmpy;            \
+        })
+
+#ifdef XENBUS_DEBUG
+#define DEBUG(_f, _a...) \
+    printk("MINI_OS(file=xenbus.c, line=%d) " _f , __LINE__, ## _a)
+#else
+#define DEBUG(_f, _a...)    ((void)0)
+#endif
+
+
+static struct xenstore_domain_interface *xenstore_buf;
+static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
+struct xenbus_req_info 
+{
+    int in_use:1;
+    struct wait_queue_head waitq;
+    void *reply;
+};
+
+#define NR_REQS 32
+static struct xenbus_req_info req_info[NR_REQS];
+
+static void memcpy_from_ring(const void *Ring,
+        void *Dest,
+        int off,
+        int len)
+{
+    int c1, c2;
+    const char *ring = Ring;
+    char *dest = Dest;
+    c1 = min(len, XENSTORE_RING_SIZE - off);
+    c2 = len - c1;
+    memcpy(dest, ring + off, c1);
+    memcpy(dest + c1, ring, c2);
+}
+
+static void xenbus_thread_func(void *ign)
+{
+    struct xsd_sockmsg msg;
+    unsigned prod;
+
+    for (;;) 
+    {
+        wait_event(xb_waitq, prod != xenstore_buf->rsp_prod);
+        while (1) 
+        {
+            prod = xenstore_buf->rsp_prod;
+            DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons,
+                    xenstore_buf->rsp_prod);
+            if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
+                break;
+            rmb();
+            memcpy_from_ring(xenstore_buf->rsp,
+                    &msg,
+                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
+                    sizeof(msg));
+            DEBUG("Msg len %d, %d avail, id %d.\n",
+                    msg.len + sizeof(msg),
+                    xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
+                    msg.req_id);
+            if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
+                    sizeof(msg) + msg.len)
+                break;
+
+            DEBUG("Message is good.\n");
+            req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
+            memcpy_from_ring(xenstore_buf->rsp,
+                    req_info[msg.req_id].reply,
+                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
+                    msg.len + sizeof(msg));
+            wake_up(&req_info[msg.req_id].waitq);
+            xenstore_buf->rsp_cons += msg.len + sizeof(msg);
+        }
+    }
+}
+
+static void xenbus_evtchn_handler(int port, struct pt_regs *regs)
+{
+    wake_up(&xb_waitq);
+}
+
+static int nr_live_reqs;
+static spinlock_t req_lock = SPIN_LOCK_UNLOCKED;
+static DECLARE_WAIT_QUEUE_HEAD(req_wq);
+
+/* Release a xenbus identifier */
+static void release_xenbus_id(int id)
+{
+    BUG_ON(!req_info[id].in_use);
+    spin_lock(&req_lock);
+    nr_live_reqs--;
+    if (nr_live_reqs == NR_REQS - 1)
+        wake_up(&req_wq);
+    spin_unlock(&req_lock);
+}
+
+/* Allocate an identifier for a xenbus request.  Blocks if none are
+   available. */
+static int allocate_xenbus_id(void)
+{
+    static int probe;
+    int o_probe;
+
+    while (1) 
+    {
+        spin_lock(&req_lock);
+        if (nr_live_reqs < NR_REQS)
+            break;
+        spin_unlock(&req_lock);
+        wait_event(req_wq, (nr_live_reqs < NR_REQS));
+    }
+
+    o_probe = probe;
+    for (;;) 
+    {
+        if (!req_info[o_probe].in_use)
+            break;
+        o_probe = (o_probe + 1) % NR_REQS;
+        BUG_ON(o_probe == probe);
+    }
+    nr_live_reqs++;
+    req_info[o_probe].in_use = 1;
+    probe = o_probe + 1;
+    spin_unlock(&req_lock);
+    init_waitqueue_head(&req_info[o_probe].waitq);
+    return o_probe;
+}
+
+/* Initialise xenbus. */
+void init_xenbus(void)
+{
+    int err;
+    DEBUG("init_xenbus called.\n");
+    xenstore_buf = mfn_to_virt(start_info.store_mfn);
+    create_thread("xenstore", xenbus_thread_func, NULL);
+    DEBUG("buf at %p.\n", xenstore_buf);
+    err = bind_evtchn(start_info.store_evtchn,
+            xenbus_evtchn_handler);
+    DEBUG("xenbus on irq %d\n", err);
+}
+
+struct write_req {
+    const void *data;
+    unsigned len;
+};
+
+/* Send data to xenbus.  This can block.  All of the requests are seen
+   by xenbus as if sent atomically.  The header is added
+   automatically, using type %type, req_id %req_id, and trans_id
+   %trans_id. */
+static void xb_write(int type, int req_id, int trans_id,
+        const struct write_req *req, int nr_reqs)
+{
+    XENSTORE_RING_IDX prod;
+    int r;
+    int len = 0;
+    const struct write_req *cur_req;
+    int req_off;
+    int total_off;
+    int this_chunk;
+    struct xsd_sockmsg m = {.type = type, .req_id = req_id,
+        .tx_id = trans_id };
+    struct write_req header_req = { &m, sizeof(m) };
+
+    for (r = 0; r < nr_reqs; r++)
+        len += req[r].len;
+    m.len = len;
+    len += sizeof(m);
+
+    cur_req = &header_req;
+
+    BUG_ON(len > XENSTORE_RING_SIZE);
+    /* Wait for the ring to drain to the point where we can send the
+       message. */
+    prod = xenstore_buf->req_prod;
+    if (prod + len - xenstore_buf->req_cons > XENSTORE_RING_SIZE) 
+    {
+        /* Wait for there to be space on the ring */
+        DEBUG("prod %d, len %d, cons %d, size %d; waiting.\n",
+                prod, len, xenstore_buf->req_cons, XENSTORE_RING_SIZE);
+        wait_event(xb_waitq,
+                xenstore_buf->req_prod + len - xenstore_buf->req_cons <=
+                XENSTORE_RING_SIZE);
+        DEBUG("Back from wait.\n");
+        prod = xenstore_buf->req_prod;
+    }
+
+    /* We're now guaranteed to be able to send the message without
+       overflowing the ring.  Do so. */
+    total_off = 0;
+    req_off = 0;
+    while (total_off < len) 
+    {
+        this_chunk = min(cur_req->len - req_off,
+                XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
+        memcpy((char *)xenstore_buf->req + MASK_XENSTORE_IDX(prod),
+                (char *)cur_req->data + req_off, this_chunk);
+        prod += this_chunk;
+        req_off += this_chunk;
+        total_off += this_chunk;
+        if (req_off == cur_req->len) 
+        {
+            req_off = 0;
+            if (cur_req == &header_req)
+                cur_req = req;
+            else
+                cur_req++;
+        }
+    }
+
+    DEBUG("Complete main loop of xb_write.\n");
+    BUG_ON(req_off != 0);
+    BUG_ON(total_off != len);
+    BUG_ON(prod > xenstore_buf->req_cons + XENSTORE_RING_SIZE);
+
+    /* Remote must see entire message before updating indexes */
+    wmb();
+
+    xenstore_buf->req_prod += len;
+
+    /* Send evtchn to notify remote */
+    notify_remote_via_evtchn(start_info.store_evtchn);
+}
+
+/* Send a mesasge to xenbus, in the same fashion as xb_write, and
+   block waiting for a reply.  The reply is malloced and should be
+   freed by the caller. */
+static void *xenbus_msg_reply(int type,
+        int trans,
+        struct write_req *io,
+        int nr_reqs)
+{
+    int id;
+    DEFINE_WAIT(w);
+    void *rep;
+    struct xsd_sockmsg *repmsg;
+
+    id = allocate_xenbus_id();
+    add_waiter(w, req_info[id].waitq);
+
+    xb_write(type, id, trans, io, nr_reqs);
+
+    schedule();
+    wake(current);
+
+    rep = req_info[id].reply;
+    repmsg = rep;
+    BUG_ON(repmsg->req_id != id);
+    release_xenbus_id(id);
+
+    return rep;
+}
+
+/* Send a debug message to xenbus.  Can block. */
+static void xenbus_debug_msg(const char *msg)
+{
+    int len = strlen(msg);
+    struct write_req req[] = {
+        { "print", sizeof("print") },
+        { msg, len },
+        { "", 1 }};
+    void *reply;
+    struct xsd_sockmsg *repmsg;
+
+    reply = xenbus_msg_reply(XS_DEBUG, 0, req, 3);
+    repmsg = reply;
+    DEBUG("Got a reply, type %d, id %d, len %d.\n",
+            repmsg->type, repmsg->req_id, repmsg->len);
+}
+
+/* List the contents of a directory.  Returns a malloc()ed array of
+   pointers to malloc()ed strings.  The array is NULL terminated.  May
+   block. */
+static char **xenbus_ls(const char *pre)
+{
+    void *reply;
+    struct xsd_sockmsg *repmsg;
+    struct write_req req[] = { { pre, strlen(pre)+1 } };
+    int nr_elems, x, i;
+    char **res;
+
+    repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, 1);
+    reply = repmsg + 1;
+    for (x = nr_elems = 0; x < repmsg->len; x++)
+        nr_elems += (((char *)reply)[x] == 0);
+    res = malloc(sizeof(res[0]) * (nr_elems + 1));
+    for (x = i = 0; i < nr_elems; i++) {
+        int l = strlen((char *)reply + x);
+        res[i] = malloc(l + 1);
+        memcpy(res[i], (char *)reply + x, l + 1);
+        x += l + 1;
+    }
+    res[i] = NULL;
+    free(repmsg);
+    return res;
+}
+
+static char *xenbus_read(const char *path)
+{
+    struct write_req req[] = { {path, strlen(path) + 1}};
+    struct xsd_sockmsg *rep;
+    char *res;
+    rep = xenbus_msg_reply(XS_READ, 0, req, 1);
+    res = malloc(rep->len + 1);
+    memcpy(res, rep + 1, rep->len);
+    res[rep->len] = 0;
+    free(rep);
+    return res;
+}
+
+static void do_ls_test(const char *pre)
+{
+    char **dirs;
+    int x;
+
+    DEBUG("ls %s...\n", pre);
+    dirs = xenbus_ls(pre);
+    for (x = 0; dirs[x]; x++) 
+    {
+        DEBUG("ls %s[%d] -> %s\n", pre, x, dirs[x]);
+        free(dirs[x]);
+    }
+    free(dirs);
+}
+
+static void do_read_test(const char *path)
+{
+    char *res;
+    DEBUG("Read %s...\n", path);
+    res = xenbus_read(path);
+    DEBUG("Read %s -> %s.\n", path, res);
+    free(res);
+}
+
+/* Simple testing thing */
+void test_xenbus(void)
+{
+    DEBUG("Doing xenbus test.\n");
+    xenbus_debug_msg("Testing xenbus...\n");
+
+    DEBUG("Doing ls test.\n");
+    do_ls_test("device");
+    do_ls_test("device/vif");
+    do_ls_test("device/vif/0");
+
+    DEBUG("Doing read test.\n");
+    do_read_test("device/vif/0/mac");
+    do_read_test("device/vif/0/backend");
+    printk("Xenbus initialised.\n");
+}
diff -r 7e3cbc409676 -r d75a6cc5e68a 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/msr.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/msr.h        Tue Mar 
28 08:54:58 2006 -0700
@@ -0,0 +1,399 @@
+#ifndef X86_64_MSR_H
+#define X86_64_MSR_H 1
+
+#ifndef __ASSEMBLY__
+/*
+ * Access to machine-specific registers (available on 586 and better only)
+ * Note: the rd* operations modify the parameters directly (without using
+ * pointer indirection), this allows gcc to optimize better
+ */
+
+#define rdmsr(msr,val1,val2) \
+       __asm__ __volatile__("rdmsr" \
+                           : "=a" (val1), "=d" (val2) \
+                           : "c" (msr))
+
+
+#define rdmsrl(msr,val) do { unsigned long a__,b__; \
+       __asm__ __volatile__("rdmsr" \
+                           : "=a" (a__), "=d" (b__) \
+                           : "c" (msr)); \
+       val = a__ | (b__<<32); \
+} while(0)
+
+#define wrmsr(msr,val1,val2) \
+     __asm__ __volatile__("wrmsr" \
+                         : /* no outputs */ \
+                         : "c" (msr), "a" (val1), "d" (val2))
+
+#define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) 
+
+/* wrmsr with exception handling */
+#define wrmsr_safe(msr,a,b) ({ int ret__;                      \
+       asm volatile("2: wrmsr ; xorl %0,%0\n"                  \
+                    "1:\n\t"                                   \
+                    ".section .fixup,\"ax\"\n\t"               \
+                    "3:  movl %4,%0 ; jmp 1b\n\t"              \
+                    ".previous\n\t"                            \
+                    ".section __ex_table,\"a\"\n"              \
+                    "   .align 8\n\t"                          \
+                    "   .quad  2b,3b\n\t"                      \
+                    ".previous"                                \
+                    : "=a" (ret__)                             \
+                    : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \
+       ret__; })
+
+#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32))
+
+#define rdmsr_safe(msr,a,b) \
+       ({ int ret__;                                           \
+         asm volatile ("1:       rdmsr\n"                      \
+                      "2:\n"                                   \
+                      ".section .fixup,\"ax\"\n"               \
+                      "3:       movl %4,%0\n"                  \
+                      " jmp 2b\n"                              \
+                      ".previous\n"                            \
+                      ".section __ex_table,\"a\"\n"            \
+                      " .align 8\n"                            \
+                      " .quad 1b,3b\n"                         \
+                      ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b))\
+                      :"c"(msr), "i"(-EIO), "0"(0));           \
+         ret__; })             
+
+#define rdtsc(low,high) \
+     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
+
+#define rdtscl(low) \
+     __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
+
+#define rdtscll(val) do { \
+     unsigned int __a,__d; \
+     asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
+     (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
+} while(0)
+
+#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
+
+#define rdpmc(counter,low,high) \
+     __asm__ __volatile__("rdpmc" \
+                         : "=a" (low), "=d" (high) \
+                         : "c" (counter))
+
+static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
+                        unsigned int *ecx, unsigned int *edx)
+{
+       __asm__(XEN_CPUID
+               : "=a" (*eax),
+                 "=b" (*ebx),
+                 "=c" (*ecx),
+                 "=d" (*edx)
+               : "0" (op));
+}
+
+/* Some CPUID calls want 'count' to be placed in ecx */
+static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
+               int *edx)
+{
+       __asm__(XEN_CPUID
+               : "=a" (*eax),
+                 "=b" (*ebx),
+                 "=c" (*ecx),
+                 "=d" (*edx)
+               : "0" (op), "c" (count));
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+       unsigned int eax;
+
+       __asm__(XEN_CPUID
+               : "=a" (eax)
+               : "0" (op)
+               : "bx", "cx", "dx");
+       return eax;
+}
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+       unsigned int eax, ebx;
+
+       __asm__(XEN_CPUID
+               : "=a" (eax), "=b" (ebx)
+               : "0" (op)
+               : "cx", "dx" );
+       return ebx;
+}
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+       unsigned int eax, ecx;
+
+       __asm__(XEN_CPUID
+               : "=a" (eax), "=c" (ecx)
+               : "0" (op)
+               : "bx", "dx" );
+       return ecx;
+}
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+       unsigned int eax, edx;
+
+       __asm__(XEN_CPUID
+               : "=a" (eax), "=d" (edx)
+               : "0" (op)
+               : "bx", "cx");
+       return edx;
+}
+
+#define MSR_IA32_UCODE_WRITE           0x79
+#define MSR_IA32_UCODE_REV             0x8b
+
+
+#endif
+
+/* AMD/K8 specific MSRs */ 
+#define MSR_EFER 0xc0000080            /* extended feature register */
+#define MSR_STAR 0xc0000081            /* legacy mode SYSCALL target */
+#define MSR_LSTAR 0xc0000082           /* long mode SYSCALL target */
+#define MSR_CSTAR 0xc0000083           /* compatibility mode SYSCALL target */
+#define MSR_SYSCALL_MASK 0xc0000084    /* EFLAGS mask for syscall */
+#define MSR_FS_BASE 0xc0000100         /* 64bit GS base */
+#define MSR_GS_BASE 0xc0000101         /* 64bit FS base */
+#define MSR_KERNEL_GS_BASE  0xc0000102 /* SwapGS GS shadow (or USER_GS from 
kernel) */ 
+/* EFER bits: */ 
+#define _EFER_SCE 0  /* SYSCALL/SYSRET */
+#define _EFER_LME 8  /* Long mode enable */
+#define _EFER_LMA 10 /* Long mode active (read-only) */
+#define _EFER_NX 11  /* No execute enable */
+
+#define EFER_SCE (1<<_EFER_SCE)
+#define EFER_LME (1<<_EFER_LME)
+#define EFER_LMA (1<<_EFER_LMA)
+#define EFER_NX (1<<_EFER_NX)
+
+/* Intel MSRs. Some also available on other CPUs */
+#define MSR_IA32_TSC           0x10
+#define MSR_IA32_PLATFORM_ID   0x17
+
+#define MSR_IA32_PERFCTR0      0xc1
+#define MSR_IA32_PERFCTR1      0xc2
+
+#define MSR_MTRRcap            0x0fe
+#define MSR_IA32_BBL_CR_CTL        0x119
+
+#define MSR_IA32_SYSENTER_CS   0x174
+#define MSR_IA32_SYSENTER_ESP  0x175
+#define MSR_IA32_SYSENTER_EIP  0x176
+
+#define MSR_IA32_MCG_CAP       0x179
+#define MSR_IA32_MCG_STATUS        0x17a
+#define MSR_IA32_MCG_CTL       0x17b
+
+#define MSR_IA32_EVNTSEL0      0x186
+#define MSR_IA32_EVNTSEL1      0x187
+
+#define MSR_IA32_DEBUGCTLMSR       0x1d9
+#define MSR_IA32_LASTBRANCHFROMIP  0x1db
+#define MSR_IA32_LASTBRANCHTOIP        0x1dc
+#define MSR_IA32_LASTINTFROMIP     0x1dd
+#define MSR_IA32_LASTINTTOIP       0x1de
+
+#define MSR_MTRRfix64K_00000   0x250
+#define MSR_MTRRfix16K_80000   0x258
+#define MSR_MTRRfix16K_A0000   0x259
+#define MSR_MTRRfix4K_C0000    0x268
+#define MSR_MTRRfix4K_C8000    0x269
+#define MSR_MTRRfix4K_D0000    0x26a
+#define MSR_MTRRfix4K_D8000    0x26b
+#define MSR_MTRRfix4K_E0000    0x26c
+#define MSR_MTRRfix4K_E8000    0x26d
+#define MSR_MTRRfix4K_F0000    0x26e
+#define MSR_MTRRfix4K_F8000    0x26f
+#define MSR_MTRRdefType                0x2ff
+
+#define MSR_IA32_MC0_CTL       0x400
+#define MSR_IA32_MC0_STATUS        0x401
+#define MSR_IA32_MC0_ADDR      0x402
+#define MSR_IA32_MC0_MISC      0x403
+
+#define MSR_P6_PERFCTR0                        0xc1
+#define MSR_P6_PERFCTR1                        0xc2
+#define MSR_P6_EVNTSEL0                        0x186
+#define MSR_P6_EVNTSEL1                        0x187
+
+/* K7/K8 MSRs. Not complete. See the architecture manual for a more complete 
list. */
+#define MSR_K7_EVNTSEL0            0xC0010000
+#define MSR_K7_PERFCTR0            0xC0010004
+#define MSR_K7_EVNTSEL1            0xC0010001
+#define MSR_K7_PERFCTR1            0xC0010005
+#define MSR_K7_EVNTSEL2            0xC0010002
+#define MSR_K7_PERFCTR2            0xC0010006
+#define MSR_K7_EVNTSEL3            0xC0010003
+#define MSR_K7_PERFCTR3            0xC0010007
+#define MSR_K8_TOP_MEM1                   0xC001001A
+#define MSR_K8_TOP_MEM2                   0xC001001D
+#define MSR_K8_SYSCFG             0xC0010010
+#define MSR_K8_HWCR               0xC0010015
+
+/* K6 MSRs */
+#define MSR_K6_EFER                    0xC0000080
+#define MSR_K6_STAR                    0xC0000081
+#define MSR_K6_WHCR                    0xC0000082
+#define MSR_K6_UWCCR                   0xC0000085
+#define MSR_K6_PSOR                    0xC0000087
+#define MSR_K6_PFIR                    0xC0000088
+
+/* Centaur-Hauls/IDT defined MSRs. */
+#define MSR_IDT_FCR1                   0x107
+#define MSR_IDT_FCR2                   0x108
+#define MSR_IDT_FCR3                   0x109
+#define MSR_IDT_FCR4                   0x10a
+
+#define MSR_IDT_MCR0                   0x110
+#define MSR_IDT_MCR1                   0x111
+#define MSR_IDT_MCR2                   0x112
+#define MSR_IDT_MCR3                   0x113
+#define MSR_IDT_MCR4                   0x114
+#define MSR_IDT_MCR5                   0x115
+#define MSR_IDT_MCR6                   0x116
+#define MSR_IDT_MCR7                   0x117
+#define MSR_IDT_MCR_CTRL               0x120
+
+/* VIA Cyrix defined MSRs*/
+#define MSR_VIA_FCR                    0x1107
+#define MSR_VIA_LONGHAUL               0x110a
+#define MSR_VIA_RNG                    0x110b
+#define MSR_VIA_BCR2                   0x1147
+
+/* Intel defined MSRs. */
+#define MSR_IA32_P5_MC_ADDR            0
+#define MSR_IA32_P5_MC_TYPE            1
+#define MSR_IA32_PLATFORM_ID           0x17
+#define MSR_IA32_EBL_CR_POWERON                0x2a
+
+#define MSR_IA32_APICBASE               0x1b
+#define MSR_IA32_APICBASE_BSP           (1<<8)
+#define MSR_IA32_APICBASE_ENABLE        (1<<11)
+#define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
+
+/* P4/Xeon+ specific */
+#define MSR_IA32_MCG_EAX               0x180
+#define MSR_IA32_MCG_EBX               0x181
+#define MSR_IA32_MCG_ECX               0x182
+#define MSR_IA32_MCG_EDX               0x183
+#define MSR_IA32_MCG_ESI               0x184
+#define MSR_IA32_MCG_EDI               0x185
+#define MSR_IA32_MCG_EBP               0x186
+#define MSR_IA32_MCG_ESP               0x187
+#define MSR_IA32_MCG_EFLAGS            0x188
+#define MSR_IA32_MCG_EIP               0x189
+#define MSR_IA32_MCG_RESERVED          0x18A
+
+#define MSR_P6_EVNTSEL0                        0x186
+#define MSR_P6_EVNTSEL1                        0x187
+
+#define MSR_IA32_PERF_STATUS           0x198
+#define MSR_IA32_PERF_CTL              0x199
+
+#define MSR_IA32_THERM_CONTROL         0x19a
+#define MSR_IA32_THERM_INTERRUPT       0x19b
+#define MSR_IA32_THERM_STATUS          0x19c
+#define MSR_IA32_MISC_ENABLE           0x1a0
+
+#define MSR_IA32_DEBUGCTLMSR           0x1d9
+#define MSR_IA32_LASTBRANCHFROMIP      0x1db
+#define MSR_IA32_LASTBRANCHTOIP                0x1dc
+#define MSR_IA32_LASTINTFROMIP         0x1dd
+#define MSR_IA32_LASTINTTOIP           0x1de
+
+#define MSR_IA32_MC0_CTL               0x400
+#define MSR_IA32_MC0_STATUS            0x401
+#define MSR_IA32_MC0_ADDR              0x402
+#define MSR_IA32_MC0_MISC              0x403
+
+/* Pentium IV performance counter MSRs */
+#define MSR_P4_BPU_PERFCTR0            0x300
+#define MSR_P4_BPU_PERFCTR1            0x301
+#define MSR_P4_BPU_PERFCTR2            0x302
+#define MSR_P4_BPU_PERFCTR3            0x303
+#define MSR_P4_MS_PERFCTR0             0x304
+#define MSR_P4_MS_PERFCTR1             0x305
+#define MSR_P4_MS_PERFCTR2             0x306
+#define MSR_P4_MS_PERFCTR3             0x307
+#define MSR_P4_FLAME_PERFCTR0          0x308
+#define MSR_P4_FLAME_PERFCTR1          0x309
+#define MSR_P4_FLAME_PERFCTR2          0x30a
+#define MSR_P4_FLAME_PERFCTR3          0x30b
+#define MSR_P4_IQ_PERFCTR0             0x30c
+#define MSR_P4_IQ_PERFCTR1             0x30d
+#define MSR_P4_IQ_PERFCTR2             0x30e
+#define MSR_P4_IQ_PERFCTR3             0x30f
+#define MSR_P4_IQ_PERFCTR4             0x310
+#define MSR_P4_IQ_PERFCTR5             0x311
+#define MSR_P4_BPU_CCCR0               0x360
+#define MSR_P4_BPU_CCCR1               0x361
+#define MSR_P4_BPU_CCCR2               0x362
+#define MSR_P4_BPU_CCCR3               0x363
+#define MSR_P4_MS_CCCR0                0x364
+#define MSR_P4_MS_CCCR1                0x365
+#define MSR_P4_MS_CCCR2                0x366
+#define MSR_P4_MS_CCCR3                0x367
+#define MSR_P4_FLAME_CCCR0             0x368
+#define MSR_P4_FLAME_CCCR1             0x369
+#define MSR_P4_FLAME_CCCR2             0x36a
+#define MSR_P4_FLAME_CCCR3             0x36b
+#define MSR_P4_IQ_CCCR0                0x36c
+#define MSR_P4_IQ_CCCR1                0x36d
+#define MSR_P4_IQ_CCCR2                0x36e
+#define MSR_P4_IQ_CCCR3                0x36f
+#define MSR_P4_IQ_CCCR4                0x370
+#define MSR_P4_IQ_CCCR5                0x371
+#define MSR_P4_ALF_ESCR0               0x3ca
+#define MSR_P4_ALF_ESCR1               0x3cb
+#define MSR_P4_BPU_ESCR0               0x3b2
+#define MSR_P4_BPU_ESCR1               0x3b3
+#define MSR_P4_BSU_ESCR0               0x3a0
+#define MSR_P4_BSU_ESCR1               0x3a1
+#define MSR_P4_CRU_ESCR0               0x3b8
+#define MSR_P4_CRU_ESCR1               0x3b9
+#define MSR_P4_CRU_ESCR2               0x3cc
+#define MSR_P4_CRU_ESCR3               0x3cd
+#define MSR_P4_CRU_ESCR4               0x3e0
+#define MSR_P4_CRU_ESCR5               0x3e1
+#define MSR_P4_DAC_ESCR0               0x3a8
+#define MSR_P4_DAC_ESCR1               0x3a9
+#define MSR_P4_FIRM_ESCR0              0x3a4
+#define MSR_P4_FIRM_ESCR1              0x3a5
+#define MSR_P4_FLAME_ESCR0             0x3a6
+#define MSR_P4_FLAME_ESCR1             0x3a7
+#define MSR_P4_FSB_ESCR0               0x3a2
+#define MSR_P4_FSB_ESCR1               0x3a3
+#define MSR_P4_IQ_ESCR0                0x3ba
+#define MSR_P4_IQ_ESCR1                0x3bb
+#define MSR_P4_IS_ESCR0                0x3b4
+#define MSR_P4_IS_ESCR1                0x3b5
+#define MSR_P4_ITLB_ESCR0              0x3b6
+#define MSR_P4_ITLB_ESCR1              0x3b7
+#define MSR_P4_IX_ESCR0                0x3c8
+#define MSR_P4_IX_ESCR1                0x3c9
+#define MSR_P4_MOB_ESCR0               0x3aa
+#define MSR_P4_MOB_ESCR1               0x3ab
+#define MSR_P4_MS_ESCR0                0x3c0
+#define MSR_P4_MS_ESCR1                0x3c1
+#define MSR_P4_PMH_ESCR0               0x3ac
+#define MSR_P4_PMH_ESCR1               0x3ad
+#define MSR_P4_RAT_ESCR0               0x3bc
+#define MSR_P4_RAT_ESCR1               0x3bd
+#define MSR_P4_SAAT_ESCR0              0x3ae
+#define MSR_P4_SAAT_ESCR1              0x3af
+#define MSR_P4_SSU_ESCR0               0x3be
+#define MSR_P4_SSU_ESCR1               0x3bf    /* guess: not defined in 
manual */
+#define MSR_P4_TBPU_ESCR0              0x3c2
+#define MSR_P4_TBPU_ESCR1              0x3c3
+#define MSR_P4_TC_ESCR0                0x3c4
+#define MSR_P4_TC_ESCR1                0x3c5
+#define MSR_P4_U2L_ESCR0               0x3b0
+#define MSR_P4_U2L_ESCR1               0x3b1
+
+#endif
diff -r 7e3cbc409676 -r d75a6cc5e68a patches/linux-2.6.16/device_bind.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16/device_bind.patch    Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,14 @@
+--- linux-2.6.16/drivers/base/bus.c    2006-03-16 10:50:20.000000000 -0500
++++ linux-2.6.16/drivers/base/bus.c    2006-03-16 11:02:08.000000000 -0500
+@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
+               up(&dev->sem);
+               if (dev->parent)
+                       up(&dev->parent->sem);
++
++              if (err > 0)            /* success */
++                      err = count;
++              else if (err == 0)      /* driver didn't accept device */
++                      err = -ENODEV;
+       }
+       put_device(dev);
+       put_bus(bus);
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/util/xmlrpclib2.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xmlrpclib2.py       Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,111 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+# Copyright (C) 2006 XenSource Ltd.
+#============================================================================
+
+"""
+An enhanced XML-RPC client/server interface for Python.
+"""
+
+from httplib import HTTPConnection, HTTP
+from xmlrpclib import Transport
+from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
+import xmlrpclib, socket, os, traceback
+import SocketServer
+
+# A new ServerProxy that also supports httpu urls.  An http URL comes in the
+# form:
+#
+# httpu:///absolute/path/to/socket.sock
+#
+# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
+
+class HTTPUnixConnection(HTTPConnection):
+    def connect(self):
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.sock.connect(self.host)
+
+class HTTPUnix(HTTP):
+    _connection_class = HTTPUnixConnection
+
+class UnixTransport(Transport):
+    def request(self, host, handler, request_body, verbose=0):
+        self.__handler = handler
+        return Transport.request(self, host, '/RPC2', request_body, verbose)
+    def make_connection(self, host):
+        return HTTPUnix(self.__handler)
+
+class ServerProxy(xmlrpclib.ServerProxy):
+    def __init__(self, uri, transport=None, encoding=None, verbose=0,
+                 allow_none=1):
+        if transport == None:
+            (protocol, rest) = uri.split(':', 1)
+            if protocol == 'httpu':
+                uri = 'http:' + rest
+                transport = UnixTransport()
+        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+                                       verbose, allow_none)
+
+# This is a base XML-RPC server for TCP.  It sets allow_reuse_address to
+# true, and has an improved marshaller that serializes unknown exceptions
+# with full traceback information.
+
+class TCPXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
+    allow_reuse_address = True
+
+    def _marshaled_dispatch(self, data, dispatch_method = None):
+        params, method = xmlrpclib.loads(data)
+        try:
+            if dispatch_method is not None:
+                response = dispatch_method(method, params)
+            else:
+                response = self._dispatch(method, params)
+
+            response = (response,)
+            response = xmlrpclib.dumps(response,
+                                       methodresponse=1,
+                                       allow_none=1)
+        except xmlrpclib.Fault, fault:
+            response = xmlrpclib.dumps(fault)
+        except:
+            response = xmlrpclib.dumps(
+                xmlrpclib.Fault(1, traceback.format_exc())
+                )
+
+        return response
+
+# This is a XML-RPC server that sits on a Unix domain socket.
+# It implements proper support for allow_reuse_address by
+# unlink()'ing an existing socket.
+
+class UnixXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
+    def address_string(self):
+        try:
+            return SimpleXMLRPCRequestHandler.address_string(self)
+        except ValueError, e:
+            return self.client_address[:2]
+
+class UnixXMLRPCServer(TCPXMLRPCServer):
+    address_family = socket.AF_UNIX
+
+    def __init__(self, addr, logRequests):
+        if self.allow_reuse_address:
+            try:
+                os.unlink(addr)
+            except OSError, exc:
+                pass
+        TCPXMLRPCServer.__init__(self, addr, UnixXMLRPCRequestHandler,
+                                 logRequests)
diff -r 7e3cbc409676 -r d75a6cc5e68a 
tools/python/xen/xend/server/XMLRPCServer.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/XMLRPCServer.py      Tue Mar 28 08:54:58 
2006 -0700
@@ -0,0 +1,113 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+# Copyright (C) 2006 XenSource Ltd.
+#============================================================================
+
+import xmlrpclib
+
+from xen.xend import XendDomain, XendDomainInfo, XendNode, \
+                     XendLogging, XendDmesg
+from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
+
+from xen.xend.XendClient import XML_RPC_SOCKET, ERROR_INVALID_DOMAIN
+from xen.xend.XendError import *
+
+def lookup(domid):
+    info = XendDomain.instance().domain_lookup_by_name_or_id(domid)
+    if not info:
+        raise XendInvalidDomain(str(domid))
+    return info
+
+def dispatch(domid, fn, args):
+    info = lookup(domid)
+    return getattr(info, fn)(*args)
+
+def domain(domid):
+    info = lookup(domid)
+    return info.sxpr()
+
+def domains(detail=1):
+    if detail < 1:
+        return XendDomain.instance().list_names()
+    else:
+        domains = XendDomain.instance().list_sorted()
+        return map(lambda dom: dom.sxpr(), domains)
+
+def domain_create(config):
+    info = XendDomain.instance().domain_create(config)
+    return info.sxpr()
+
+def domain_restore(src):
+    info = XendDomain.instance().domain_restore(src)
+    return info.sxpr()    
+
+def get_log():
+    f = open(XendLogging.getLogFilename(), 'r')
+    try:
+        return f.read()
+    finally:
+        f.close()
+
+methods = ['device_create', 'destroyDevice', 'getDeviceSxprs',
+           'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
+           'send_sysrq', 'getVCPUInfo', 'waitForDevices']
+
+exclude = ['domain_create', 'domain_restore']
+
+class XMLRPCServer:
+    def __init__(self, use_tcp=False):
+        self.ready = False
+        self.use_tcp = use_tcp
+        
+    def run(self):
+        if self.use_tcp:
+            # bind to something fixed for now as we may eliminate
+            # tcp support completely.
+            self.server = TCPXMLRPCServer(("localhost", 8005), 
logRequests=False)
+        else:
+            self.server = UnixXMLRPCServer(XML_RPC_SOCKET, False)
+
+        # Functions in XendDomainInfo
+        for name in methods:
+            fn = eval("lambda domid, *args: dispatch(domid, '%s', args)"%name)
+            self.server.register_function(fn, "xend.domain.%s" % name)
+
+        # Functions in XendDomain
+        inst = XendDomain.instance()
+        for name in dir(inst):
+            fn = getattr(inst, name)
+            if name.startswith("domain_") and callable(fn):
+                if name not in exclude:
+                    self.server.register_function(fn, "xend.domain.%s" % 
name[7:])
+
+        # Functions in XendNode and XendDmesg
+        for type, lst, n in [(XendNode, ['info', 'cpu_bvt_slice_set'], 'node'),
+                             (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
+            inst = type.instance()
+            for name in lst:
+                self.server.register_function(getattr(inst, name),
+                                              "xend.%s.%s" % (n, name))
+
+        # A few special cases
+        self.server.register_function(domain, 'xend.domain')
+        self.server.register_function(domains, 'xend.domains')
+        self.server.register_function(get_log, 'xend.node.log')
+        self.server.register_function(domain_create, 'xend.domain.create')
+        self.server.register_function(domain_restore, 'xend.domain.restore')
+
+        self.server.register_introspection_functions()
+        self.ready = True
+        self.server.serve_forever()
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/README
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenstore/README     Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,5 @@
+The following files are imported from the Samba project.  We use the versions
+from Samba 3, the current stable branch.
+
+talloc.c: samba-trunk/source/lib/talloc.c     r14291 2006-03-13 04:27:47 +0000
+talloc.h: samba-trunk/source/include/talloc.h r11986 2005-12-01 00:43:36 +0000
diff -r 7e3cbc409676 -r d75a6cc5e68a 
tools/xm-test/ramdisk/README-XenSource-initrd-0.7-img
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/ramdisk/README-XenSource-initrd-0.7-img     Tue Mar 28 
08:54:58 2006 -0700
@@ -0,0 +1,42 @@
+XenSource xm-test 0.7 initrd.img
+================================
+
+http://xm-test.xensource.com/ramdisks/initrd-0.7.img is an initrd suitable for
+use with Xen's xm-test regression testing suite.  It has been built and
+provided by XenSource, for the convenience of Xen users.  xm-test initrds may
+be mixed across minor xm-test versions, but not across major versions; this
+initrd is suitable for all 0.7.x versions of xm-test (as shipped with Xen
+3.0.x).
+
+In order to use this initrd, run "./autogen; ./configure; make existing"
+inside the xm-test directory, and the initrd will be downloaded automatically.
+Alternatively, if you have already downloaded this file, place it into the
+xm-test/ramdisk directory and run the same command.  In either case,
+runtest.sh can then be used as normal.  See xm-test/README for more details.
+
+This initrd was built using the infrastructure provided by xm-test.  It is a
+full guest operating system and filesystem, and as such includes a large
+number of pieces of software.  The source code for the majority of these are
+included in full inside the file
+http://xm-test.xensource.com/ramdisks/initrd.0.7.img-buildroot.tar.bz2, or
+alongside this file.  Copyright statements and licences are contained therein.
+The remaining source code is included in the Xen distribution, at
+http://www.xensource.com/xen/downloads/archives.html.  The configurations used
+for BusyBox, uClibc, and Buildroot are available as
+http://xm-test.xensource.com/ramdisks/initrd-0.7-busybox-config,
+http://xm-test.xensource.com/ramdisks/initrd-0.7-uClibc-config, and
+http://xm-test.xensource.com/ramdisks/initrd-0.7-buildroot-config
+respectively, or alongside this file.
+
+XenSource and the Xen contributors are grateful to the authors of these
+software packages for their contributions to free and open-source software.
+
+
+Buildroot and BusyBox are Copyright (c) Erik Andersen <andersen@xxxxxxxxxxxx>.
+BusyBox is licensed under the GNU General Public License (GPL).  A copy of
+this license is available in the file GPL-2,
+http://xm-test.xensource.com/ramdisks/GPL-2, or alongside this file.
+
+uClibc is licensed under the GNU Lesser General Public License (LGPL).  A copy
+of this license is available in the file
+http://xm-test.xensource.com/ramdisks/LGPL-2, or alongside this file.
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/Makefile
--- a/extras/mini-os/xenbus/Makefile    Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-all: xenstore.h xenbus_comms.o xenbus_xs.o xenbus_probe.o
-
-xenstore.h:
-       [ -e xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h 
xenstored.h
-
-clean:
-       #Taken care of by main Makefile
-       #rm xenstored.h
-       #rm *.o
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus_comms.c
--- a/extras/mini-os/xenbus/xenbus_comms.c      Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/******************************************************************************
- * xenbus_comms.c
- *
- * Low level code to talks to Xen Store: ringbuffer and event channel.
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- * 
- * This file may be 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.
- */
-#include <types.h>
-#include <wait.h>
-#include <mm.h>
-#include <hypervisor.h>
-#include <events.h>
-#include <os.h>
-#include <lib.h>
-#include <xenbus.h>
-#include "xenbus_comms.h"
-
-static int xenbus_irq;
-
-extern void xenbus_probe(void *);
-extern int xenstored_ready;
-
-DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
-
-static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
-{
-       return mfn_to_virt(start_info.store_mfn);
-}
-
-static void wake_waiting(int port, struct pt_regs *regs)
-{
-       wake_up(&xb_waitq);
-}
-
-static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
-{
-       return ((prod - cons) <= XENSTORE_RING_SIZE);
-}
-
-static void *get_output_chunk(XENSTORE_RING_IDX cons,
-                             XENSTORE_RING_IDX prod,
-                             char *buf, uint32_t *len)
-{
-       *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
-       if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
-               *len = XENSTORE_RING_SIZE - (prod - cons);
-       return buf + MASK_XENSTORE_IDX(prod);
-}
-
-static const void *get_input_chunk(XENSTORE_RING_IDX cons,
-                                  XENSTORE_RING_IDX prod,
-                                  const char *buf, uint32_t *len)
-{
-       *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
-       if ((prod - cons) < *len)
-               *len = prod - cons;
-       return buf + MASK_XENSTORE_IDX(cons);
-}
-
-int xb_write(const void *data, unsigned len)
-{
-       struct xenstore_domain_interface *intf = xenstore_domain_interface();
-       XENSTORE_RING_IDX cons, prod;
-
-       while (len != 0) {
-               void *dst;
-               unsigned int avail;
-
-               wait_event(xb_waitq, (intf->req_prod - intf->req_cons) !=
-                          XENSTORE_RING_SIZE);
-
-               /* Read indexes, then verify. */
-               cons = intf->req_cons;
-               prod = intf->req_prod;
-               mb();
-               if (!check_indexes(cons, prod))
-                       return -EIO;
-
-               dst = get_output_chunk(cons, prod, intf->req, &avail);
-               if (avail == 0)
-                       continue;
-               if (avail > len)
-                       avail = len;
-
-               memcpy(dst, data, avail);
-               data = (void*) ( (unsigned long)data + avail );
-               len -= avail;
-
-               /* Other side must not see new header until data is there. */
-               wmb();
-               intf->req_prod += avail;
-
-               /* This implies mb() before other side sees interrupt. */
-               notify_remote_via_evtchn(start_info.store_evtchn);
-       }
-
-       return 0;
-}
-
-int xb_read(void *data, unsigned len)
-{
-       struct xenstore_domain_interface *intf = xenstore_domain_interface();
-       XENSTORE_RING_IDX cons, prod;
-
-       while (len != 0) {
-               unsigned int avail;
-               const char *src;
-
-               wait_event(xb_waitq,
-                          intf->rsp_cons != intf->rsp_prod);
-
-               /* Read indexes, then verify. */
-               cons = intf->rsp_cons;
-               prod = intf->rsp_prod;
-               mb();
-               if (!check_indexes(cons, prod))
-                       return -EIO;
-
-               src = get_input_chunk(cons, prod, intf->rsp, &avail);
-               if (avail == 0)
-                       continue;
-               if (avail > len)
-                       avail = len;
-
-               /* We must read header before we read data. */
-               rmb();
-
-               memcpy(data, src, avail);
-               data = (void*) ( (unsigned long)data + avail );
-               len -= avail;
-
-               /* Other side must not see free space until we've copied out */
-               mb();
-               intf->rsp_cons += avail;
-
-               printk("Finished read of %i bytes (%i to go)\n", avail, len);
-
-               /* Implies mb(): they will see new header. */
-               notify_remote_via_evtchn(start_info.store_evtchn);
-       }
-
-       return 0;
-}
-
-/* Set up interrupt handler off store event channel. */
-int xb_init_comms(void)
-{
-       int err;
-
-       if (xenbus_irq)
-               unbind_evtchn(xenbus_irq);
-
-       err = bind_evtchn(
-               start_info.store_evtchn, wake_waiting);
-       if (err <= 0) {
-               printk("XENBUS request irq failed %i\n", err);
-               return err;
-       }
-
-       xenbus_irq = err;
-
-       return 0;
-}
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus_comms.h
--- a/extras/mini-os/xenbus/xenbus_comms.h      Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Private include for xenbus communications.
- * 
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- *
- * This file may be 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_COMMS_H
-#define _XENBUS_COMMS_H
-
-int xs_init(void);
-int xb_init_comms(void);
-
-/* Low level routines. */
-int xb_write(const void *data, unsigned len);
-int xb_read(void *data, unsigned len);
-int xs_input_avail(void);
-extern struct wait_queue_head xb_waitq;
-
-#endif /* _XENBUS_COMMS_H */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus_xs.c
--- a/extras/mini-os/xenbus/xenbus_xs.c Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,796 +0,0 @@
-/******************************************************************************
- * xenbus_xs.c
- *
- * This is the kernel equivalent of the "xs" library.  We don't need everything
- * and we use xenbus_comms for communication.
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- * 
- * This file may be 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.
- */
-#include <errno.h>
-#include <types.h>
-#include <list.h>
-#include <lib.h>
-#include <err.h>
-#include <os.h>
-#include <xmalloc.h>
-#include <fcntl.h>
-#include <xenbus.h>
-#include <wait.h>
-#include <sched.h>
-#include <semaphore.h>
-#include <spinlock.h>
-#include <xen/io/xs_wire.h>
-#include "xenbus_comms.h"
-
-#define streq(a, b) (strcmp((a), (b)) == 0)
-
-struct xs_stored_msg {
-       struct list_head list;
-
-       struct xsd_sockmsg hdr;
-
-       union {
-               /* Queued replies. */
-               struct {
-                       char *body;
-               } reply;
-
-               /* Queued watch events. */
-               struct {
-                       struct xenbus_watch *handle;
-                       char **vec;
-                       unsigned int vec_size;
-               } watch;
-       } u;
-};
-
-struct xs_handle {
-       /* A list of replies. Currently only one will ever be outstanding. */
-       struct list_head reply_list;
-       spinlock_t reply_lock;
-       struct wait_queue_head reply_waitq;
-
-       /* One request at a time. */
-       struct semaphore request_mutex;
-
-       /* Protect transactions against save/restore. */
-       struct rw_semaphore suspend_mutex;
-};
-
-static struct xs_handle xs_state;
-
-/* List of registered watches, and a lock to protect it. */
-static LIST_HEAD(watches);
-static DEFINE_SPINLOCK(watches_lock);
-
-/* List of pending watch callback events, and a lock to protect it. */
-static LIST_HEAD(watch_events);
-static DEFINE_SPINLOCK(watch_events_lock);
-
-/*
- * Details of the xenwatch callback kernel thread. The thread waits on the
- * watch_events_waitq for work to do (queued on watch_events list). When it
- * wakes up it acquires the xenwatch_mutex before reading the list and
- * carrying out work.
- */
-/* static */ DECLARE_MUTEX(xenwatch_mutex);
-static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq);
-
-static int get_error(const char *errorstring)
-{
-       unsigned int i;
-
-       for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
-               if (i == ARRAY_SIZE(xsd_errors) - 1) {
-                       printk("XENBUS xen store gave: unknown error %s",
-                              errorstring);
-                       return EINVAL;
-               }
-       }
-       return xsd_errors[i].errnum;
-}
-
-static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
-{
-       struct xs_stored_msg *msg;
-       char *body;
-
-       spin_lock(&xs_state.reply_lock);
-
-       while (list_empty(&xs_state.reply_list)) {
-               spin_unlock(&xs_state.reply_lock);
-               wait_event(xs_state.reply_waitq,
-                          !list_empty(&xs_state.reply_list));
-               spin_lock(&xs_state.reply_lock);
-       }
-
-       msg = list_entry(xs_state.reply_list.next,
-                        struct xs_stored_msg, list);
-       list_del(&msg->list);
-
-       spin_unlock(&xs_state.reply_lock);
-
-       *type = msg->hdr.type;
-       if (len)
-               *len = msg->hdr.len;
-       body = msg->u.reply.body;
-
-       free(msg);
-
-       return body;
-}
-
-/* Emergency write. */
-void xenbus_debug_write(const char *str, unsigned int count)
-{
-       struct xsd_sockmsg msg = { 0 };
-
-       msg.type = XS_DEBUG;
-       msg.len = sizeof("print") + count + 1;
-
-       down(&xs_state.request_mutex);
-       xb_write(&msg, sizeof(msg));
-       xb_write("print", sizeof("print"));
-       xb_write(str, count);
-       xb_write("", 1);
-       up(&xs_state.request_mutex);
-}
-
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
-{
-       void *ret;
-       struct xsd_sockmsg req_msg = *msg;
-       int err;
-
-       if (req_msg.type == XS_TRANSACTION_START)
-               down_read(&xs_state.suspend_mutex);
-
-       down(&xs_state.request_mutex);
-
-       err = xb_write(msg, sizeof(*msg) + msg->len);
-       if (err) {
-               msg->type = XS_ERROR;
-               ret = ERR_PTR(err);
-       } else {
-               ret = read_reply(&msg->type, &msg->len);
-       }
-
-       up(&xs_state.request_mutex);
-
-       if ((msg->type == XS_TRANSACTION_END) ||
-           ((req_msg.type == XS_TRANSACTION_START) &&
-            (msg->type == XS_ERROR)))
-               up_read(&xs_state.suspend_mutex);
-
-       return ret;
-}
-
-/* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
-static void *xs_talkv(struct xenbus_transaction *t,
-                     enum xsd_sockmsg_type type,
-                     const struct kvec *iovec,
-                     unsigned int num_vecs,
-                     unsigned int *len)
-{
-       struct xsd_sockmsg msg;
-       void *ret = NULL;
-       unsigned int i;
-       int err;
-
-       msg.tx_id = (u32)(unsigned long)t;
-       msg.req_id = 0;
-       msg.type = type;
-       msg.len = 0;
-       for (i = 0; i < num_vecs; i++)
-               msg.len += iovec[i].iov_len;
-
-       down(&xs_state.request_mutex);
-
-       err = xb_write(&msg, sizeof(msg));
-       if (err) {
-               up(&xs_state.request_mutex);
-               return ERR_PTR(err);
-       }
-
-       for (i = 0; i < num_vecs; i++) {
-               err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
-               if (err) {
-                       up(&xs_state.request_mutex);
-                       return ERR_PTR(err);
-               }
-       }
-
-       ret = read_reply(&msg.type, len);
-
-       up(&xs_state.request_mutex);
-
-       if (IS_ERR(ret))
-               return ret;
-
-       if (msg.type == XS_ERROR) {
-               err = get_error(ret);
-               free(ret);
-               return ERR_PTR(-err);
-       }
-
-       //      BUG_ON(msg.type != type);
-       return ret;
-}
-
-/* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xenbus_transaction *t,
-                      enum xsd_sockmsg_type type,
-                      const char *string,
-                      unsigned int *len)
-{
-       struct kvec iovec;
-
-       iovec.iov_base = (void *)string;
-       iovec.iov_len = strlen(string) + 1;
-       return xs_talkv(t, type, &iovec, 1, len);
-}
-
-/* Many commands only need an ack, don't care what it says. */
-static int xs_error(char *reply)
-{
-       if (IS_ERR(reply))
-               return PTR_ERR(reply);
-       free(reply);
-       return 0;
-}
-
-static unsigned int count_strings(const char *strings, unsigned int len)
-{
-       unsigned int num;
-       const char *p;
-
-       for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
-               num++;
-
-       return num;
-}
-
-/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */ 
-static char *join(const char *dir, const char *name)
-{
-       char *buffer;
-
-       buffer = malloc(strlen(dir) + strlen("/") + strlen(name) + 1);
-       if (buffer == NULL)
-               return ERR_PTR(-ENOMEM);
-
-       strcpy(buffer, dir);
-       if (!streq(name, "")) {
-               strcat(buffer, "/");
-               strcat(buffer, name);
-       }
-
-       return buffer;
-}
-
-static char **split(char *strings, unsigned int len, unsigned int *num)
-{
-       char *p, **ret;
-
-       /* Count the strings. */
-       *num = count_strings(strings, len);
-
-       /* Transfer to one big alloc for easy freeing. */
-       ret = malloc(*num * sizeof(char *) + len);
-       if (!ret) {
-               free(strings);
-               return ERR_PTR(-ENOMEM);
-       }
-       memcpy(&ret[*num], strings, len);
-       free(strings);
-
-       strings = (char *)&ret[*num];
-       for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
-               ret[(*num)++] = p;
-
-       return ret;
-}
-
-char **xenbus_directory(struct xenbus_transaction *t,
-                       const char *dir, const char *node, unsigned int *num)
-{
-       char *strings, *path;
-       unsigned int len;
-
-       path = join(dir, node);
-       if (IS_ERR(path))
-               return (char **)path;
-
-       strings = xs_single(t, XS_DIRECTORY, path, &len);
-       free(path);
-       if (IS_ERR(strings))
-               return (char **)strings;
-
-       return split(strings, len, num);
-}
-
-/* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(struct xenbus_transaction *t,
-                 const char *dir, const char *node)
-{
-       char **d;
-       int dir_n;
-
-       d = xenbus_directory(t, dir, node, &dir_n);
-       if (IS_ERR(d))
-               return 0;
-       free(d);
-       return 1;
-}
-
-/* Get the value of a single file.
- * Returns a kmalloced value: call free() on it after use.
- * len indicates length in bytes.
- */
-void *xenbus_read(struct xenbus_transaction *t,
-                 const char *dir, const char *node, unsigned int *len)
-{
-       char *path;
-       void *ret;
-
-       path = join(dir, node);
-       if (IS_ERR(path))
-               return (void *)path;
-
-       ret = xs_single(t, XS_READ, path, len);
-       free(path);
-       return ret;
-}
-
-/* Write the value of a single file.
- * Returns -err on failure.
- */
-int xenbus_write(struct xenbus_transaction *t,
-                const char *dir, const char *node, const char *string)
-{
-       const char *path;
-       struct kvec iovec[2];
-       int ret;
-
-       path = join(dir, node);
-       if (IS_ERR(path))
-               return PTR_ERR(path);
-
-       iovec[0].iov_base = (void *)path;
-       iovec[0].iov_len = strlen(path) + 1;
-       iovec[1].iov_base = (void *)string;
-       iovec[1].iov_len = strlen(string);
-
-       ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
-       free(path);
-       return ret;
-}
-
-/* Create a new directory. */
-int xenbus_mkdir(struct xenbus_transaction *t,
-                const char *dir, const char *node)
-{
-       char *path;
-       int ret;
-
-       path = join(dir, node);
-       if (IS_ERR(path))
-               return PTR_ERR(path);
-
-       ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
-       free(path);
-       return ret;
-}
-
-/* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
-{
-       char *path;
-       int ret;
-
-       path = join(dir, node);
-       if (IS_ERR(path))
-               return PTR_ERR(path);
-
-       ret = xs_error(xs_single(t, XS_RM, path, NULL));
-       free(path);
-       return ret;
-}
-
-/* Start a transaction: changes by others will not be seen during this
- * transaction, and changes will not be visible to others until end.
- */
-struct xenbus_transaction *xenbus_transaction_start(void)
-{
-       char *id_str;
-       unsigned long id;
-
-       down_read(&xs_state.suspend_mutex);
-
-       id_str = xs_single(NULL, XS_TRANSACTION_START, "", NULL);
-       if (IS_ERR(id_str)) {
-               up_read(&xs_state.suspend_mutex);
-               return (struct xenbus_transaction *)id_str;
-       }
-
-       id = simple_strtoul(id_str, NULL, 0);
-       free(id_str);
-
-       return (struct xenbus_transaction *)id;
-}
-
-/* End a transaction.
- * If abandon is true, transaction is discarded instead of committed.
- */
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
-{
-       char abortstr[2];
-       int err;
-
-       if (abort)
-               strcpy(abortstr, "F");
-       else
-               strcpy(abortstr, "T");
-
-       err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
-
-       up_read(&xs_state.suspend_mutex);
-
-       return err;
-}
-
-/* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(struct xenbus_transaction *t,
-                const char *dir, const char *node, const char *fmt, ...)
-{
-       va_list ap;
-       int ret;
-       char *val;
-
-       val = xenbus_read(t, dir, node, NULL);
-       if (IS_ERR(val))
-               return PTR_ERR(val);
-
-       va_start(ap, fmt);
-       ret = vsscanf(val, fmt, ap);
-       va_end(ap);
-       free(val);
-       /* Distinctive errno. */
-       if (ret == 0)
-               return -ERANGE;
-       return ret;
-}
-
-/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
-                 const char *dir, const char *node, const char *fmt, ...)
-{
-       va_list ap;
-       int ret;
-#define PRINTF_BUFFER_SIZE 4096
-       char *printf_buffer;
-
-       printf_buffer = malloc(PRINTF_BUFFER_SIZE);
-       if (printf_buffer == NULL)
-               return -ENOMEM;
-
-       va_start(ap, fmt);
-       ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
-       va_end(ap);
-
-       //      BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
-       ret = xenbus_write(t, dir, node, printf_buffer);
-
-       free(printf_buffer);
-
-       return ret;
-}
-
-/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
-{
-       va_list ap;
-       const char *name;
-       int ret = 0;
-
-       va_start(ap, dir);
-       while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
-               const char *fmt = va_arg(ap, char *);
-               void *result = va_arg(ap, void *);
-               char *p;
-
-               p = xenbus_read(t, dir, name, NULL);
-               if (IS_ERR(p)) {
-                       ret = PTR_ERR(p);
-                       break;
-               }
-               if (fmt) {
-                       if (sscanf(p, fmt, result) == 0)
-                               ret = -EINVAL;
-                       free(p);
-               } else
-                       *(char **)result = p;
-       }
-       va_end(ap);
-       return ret;
-}
-
-static int xs_watch(const char *path, const char *token)
-{
-       struct kvec iov[2];
-
-       iov[0].iov_base = (void *)path;
-       iov[0].iov_len = strlen(path) + 1;
-       iov[1].iov_base = (void *)token;
-       iov[1].iov_len = strlen(token) + 1;
-
-       return xs_error(xs_talkv(NULL, XS_WATCH, iov,
-                                ARRAY_SIZE(iov), NULL));
-}
-
-static int xs_unwatch(const char *path, const char *token)
-{
-       struct kvec iov[2];
-
-       iov[0].iov_base = (char *)path;
-       iov[0].iov_len = strlen(path) + 1;
-       iov[1].iov_base = (char *)token;
-       iov[1].iov_len = strlen(token) + 1;
-
-       return xs_error(xs_talkv(NULL, XS_UNWATCH, iov,
-                                ARRAY_SIZE(iov), NULL));
-}
-
-static struct xenbus_watch *find_watch(const char *token)
-{
-       struct xenbus_watch *i, *cmp;
-
-       cmp = (void *)simple_strtoul(token, NULL, 16);
-
-       list_for_each_entry(i, &watches, list)
-               if (i == cmp)
-                       return i;
-
-       return NULL;
-}
-
-/* Register callback to watch this node. */
-int register_xenbus_watch(struct xenbus_watch *watch)
-{
-       /* Pointer in ascii is the token. */
-       char token[sizeof(watch) * 2 + 1];
-       int err;
-
-       sprintf(token, "%lX", (long)watch);
-
-       down_read(&xs_state.suspend_mutex);
-
-       spin_lock(&watches_lock);
-       //      BUG_ON(find_watch(token));
-       list_add(&watch->list, &watches);
-       spin_unlock(&watches_lock);
-
-       err = xs_watch(watch->node, token);
-
-       /* Ignore errors due to multiple registration. */
-       if ((err != 0) && (err != -EEXIST)) {
-               spin_lock(&watches_lock);
-               list_del(&watch->list);
-               spin_unlock(&watches_lock);
-       }
-
-       up_read(&xs_state.suspend_mutex);
-
-       return err;
-}
-
-void unregister_xenbus_watch(struct xenbus_watch *watch)
-{
-       struct xs_stored_msg *msg, *tmp;
-       char token[sizeof(watch) * 2 + 1];
-       int err;
-
-       sprintf(token, "%lX", (long)watch);
-
-       down_read(&xs_state.suspend_mutex);
-
-       spin_lock(&watches_lock);
-       //      BUG_ON(!find_watch(token));
-       list_del(&watch->list);
-       spin_unlock(&watches_lock);
-
-       err = xs_unwatch(watch->node, token);
-       if (err)
-               printk("XENBUS Failed to release watch %s: %i\n",
-                      watch->node, err);
-
-       up_read(&xs_state.suspend_mutex);
-
-       /* Cancel pending watch events. */
-       spin_lock(&watch_events_lock);
-       list_for_each_entry_safe(msg, tmp, &watch_events, list) {
-               if (msg->u.watch.handle != watch)
-                       continue;
-               list_del(&msg->list);
-               free(msg->u.watch.vec);
-               free(msg);
-       }
-       spin_unlock(&watch_events_lock);
-}
-
-void xs_suspend(void)
-{
-       down_write(&xs_state.suspend_mutex);
-       down(&xs_state.request_mutex);
-}
-
-void xs_resume(void)
-{
-       struct xenbus_watch *watch;
-       char token[sizeof(watch) * 2 + 1];
-
-       up(&xs_state.request_mutex);
-
-       /* No need for watches_lock: the suspend_mutex is sufficient. */
-       list_for_each_entry(watch, &watches, list) {
-               sprintf(token, "%lX", (long)watch);
-               xs_watch(watch->node, token);
-       }
-
-       up_write(&xs_state.suspend_mutex);
-}
-
-static void xenwatch_thread(void *unused)
-{
-       struct list_head *ent;
-       struct xs_stored_msg *msg;
-
-       for (;;) {
-               wait_event(watch_events_waitq,
-                          !list_empty(&watch_events));
-
-               down(&xenwatch_mutex);
-
-               spin_lock(&watch_events_lock);
-               ent = watch_events.next;
-               if (ent != &watch_events)
-                       list_del(ent);
-               spin_unlock(&watch_events_lock);
-
-               if (ent != &watch_events) {
-                       msg = list_entry(ent, struct xs_stored_msg, list);
-                       msg->u.watch.handle->callback(
-                               msg->u.watch.handle,
-                               (const char **)msg->u.watch.vec,
-                               msg->u.watch.vec_size);
-                       free(msg->u.watch.vec);
-                       free(msg);
-               }
-
-               up(&xenwatch_mutex);
-       }
-}
-
-static int process_msg(void)
-{
-       struct xs_stored_msg *msg;
-       char *body;
-       int err;
-
-       msg = malloc(sizeof(*msg));
-       if (msg == NULL)
-               return -ENOMEM;
-
-       err = xb_read(&msg->hdr, sizeof(msg->hdr));
-       if (err) {
-               free(msg);
-               return err;
-       }
-
-       body = malloc(msg->hdr.len + 1);
-       if (body == NULL) {
-               free(msg);
-               return -ENOMEM;
-       }
-
-       err = xb_read(body, msg->hdr.len);
-       if (err) {
-               free(body);
-               free(msg);
-               return err;
-       }
-       body[msg->hdr.len] = '\0';
-
-       if (msg->hdr.type == XS_WATCH_EVENT) {
-               msg->u.watch.vec = split(body, msg->hdr.len,
-                                        &msg->u.watch.vec_size);
-               if (IS_ERR(msg->u.watch.vec)) {
-                       free(msg);
-                       return PTR_ERR(msg->u.watch.vec);
-               }
-
-               spin_lock(&watches_lock);
-               msg->u.watch.handle = find_watch(
-                       msg->u.watch.vec[XS_WATCH_TOKEN]);
-               if (msg->u.watch.handle != NULL) {
-                       spin_lock(&watch_events_lock);
-                       list_add_tail(&msg->list, &watch_events);
-                       wake_up(&watch_events_waitq);
-                       spin_unlock(&watch_events_lock);
-               } else {
-                       free(msg->u.watch.vec);
-                       free(msg);
-               }
-               spin_unlock(&watches_lock);
-       } else {
-               msg->u.reply.body = body;
-               spin_lock(&xs_state.reply_lock);
-               list_add_tail(&msg->list, &xs_state.reply_list);
-               spin_unlock(&xs_state.reply_lock);
-               wake_up(&xs_state.reply_waitq);
-       }
-
-       return 0;
-}
-
-static void xenbus_thread(void *unused)
-{
-       int err;
-
-       for (;;) {
-               err = process_msg();
-               if (err)
-                       printk("XENBUS error %d while reading "
-                              "message\n", err);
-       }
-}
-
-int xs_init(void)
-{
-       int err;
-       struct thread *kxwatcher_thread;
-       struct thread *kxenbus_thread;
-
-       INIT_LIST_HEAD(&xs_state.reply_list);
-       spin_lock_init(&xs_state.reply_lock);
-       init_waitqueue_head(&xs_state.reply_waitq);
-
-       init_MUTEX(&xs_state.request_mutex);
-       init_rwsem(&xs_state.suspend_mutex);
-
-       /* Initialize the shared memory rings to talk to xenstored */
-       err = xb_init_comms();
-       if (err)
-               return err;
-
-       kxwatcher_thread = create_thread("kxwatch", xenwatch_thread, NULL);
-       if (IS_ERR(kxwatcher_thread))
-               return PTR_ERR(kxwatcher_thread);
-
-       kxenbus_thread = create_thread("kxenbus", xenbus_thread, NULL);
-       if (IS_ERR(kxenbus_thread))
-               return PTR_ERR(kxenbus_thread);
-
-       return 0;
-}

_______________________________________________
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®.