WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] 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

<Prev in Thread] Current Thread [Next in Thread>