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

# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID 4e0c94871be28ce4936169205430d1cb1b0b451b
# Parent  0ba10f7fef519e0a9065c570653f955b66d930ea
# Parent  2144de6eabcc7fc6272a8ca088008ef92c05aa6b
Merge

diff -r 0ba10f7fef51 -r 4e0c94871be2 .hgignore
--- a/.hgignore Sat Oct  8 17:37:45 2005
+++ b/.hgignore Sat Oct  8 20:28:24 2005
@@ -155,7 +155,7 @@
 ^tools/xenstore/xenstore-read$
 ^tools/xenstore/xenstore-rm$
 ^tools/xenstore/xenstore-write$
-^tools/xenstore/xs_dom0_test$
+^tools/xenstore/xs_crashme$
 ^tools/xenstore/xs_random$
 ^tools/xenstore/xs_stress$
 ^tools/xenstore/xs_tdb_dump$
diff -r 0ba10f7fef51 -r 4e0c94871be2 Config.mk
--- a/Config.mk Sat Oct  8 17:37:45 2005
+++ b/Config.mk Sat Oct  8 20:28:24 2005
@@ -19,6 +19,13 @@
 STRIP      = $(CROSS_COMPILE)strip
 OBJCOPY    = $(CROSS_COMPILE)objcopy
 OBJDUMP    = $(CROSS_COMPILE)objdump
+
+DISTDIR     ?= $(XEN_ROOT)/dist
+
+INSTALL      = install
+INSTALL_DIR  = $(INSTALL) -d -m0755
+INSTALL_DATA = $(INSTALL) -m0644
+INSTALL_PROG = $(INSTALL) -m0755
 
 ifeq ($(XEN_TARGET_ARCH),x86_64)
 LIBDIR = lib64
@@ -49,3 +56,5 @@
 XENSTAT_XENTOP ?= y
 
 VTPM_TOOLS ?= n
+
+-include $(XEN_ROOT)/.config
diff -r 0ba10f7fef51 -r 4e0c94871be2 Makefile
--- a/Makefile  Sat Oct  8 17:37:45 2005
+++ b/Makefile  Sat Oct  8 20:28:24 2005
@@ -2,22 +2,10 @@
 # Grand Unified Makefile for Xen.
 #
 
-# Default is to install to local 'dist' directory.
-DISTDIR ?= $(CURDIR)/dist
-DESTDIR ?= $(DISTDIR)/install
-
-INSTALL                := install
-INSTALL_DIR    := $(INSTALL) -d -m0755
-INSTALL_DATA   := $(INSTALL) -m0644
-INSTALL_PROG   := $(INSTALL) -m0755
-
 KERNELS ?= linux-2.6-xen0 linux-2.6-xenU
-# linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU
-# You may use wildcards in the above e.g. KERNELS=*2.4*
+# You may use wildcards in the above e.g. KERNELS=*2.6*
 
 XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst 
buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) )
-
-export DESTDIR
 
 # Export target architecture overrides to Xen and Linux sub-trees.
 ifneq ($(XEN_TARGET_ARCH),)
@@ -28,6 +16,7 @@
 # Default target must appear before any include lines
 all: dist
 
+XEN_ROOT=$(CURDIR)
 include Config.mk
 include buildconfigs/Rules.mk
 
@@ -46,24 +35,40 @@
        $(MAKE) -C tools build
        $(MAKE) -C docs build
 
+# The test target is for unit tests that can run without an installation.  Of
+# course, many tests require a machine running Xen itself, and these are
+# handled elsewhere.
+test:
+       $(MAKE) -C tools/python test
+
 # build and install everything into local dist directory
-dist: xen kernels tools docs
+dist: DESTDIR=$(DISTDIR)/install
+dist: dist-xen dist-kernels dist-tools dist-docs
        $(INSTALL_DIR) $(DISTDIR)/check
        $(INSTALL_DATA) ./COPYING $(DISTDIR)
        $(INSTALL_DATA) ./README $(DISTDIR)
        $(INSTALL_PROG) ./install.sh $(DISTDIR)
        $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DISTDIR)/check
+dist-%: DESTDIR=$(DISTDIR)/install
+dist-%: install-%
+       @: # do nothing
 
-xen:
+# Legacy dist targets
+xen: dist-xen
+tools: dist-tools
+kernels: dist-kernels
+docs: dist-docs
+
+install-xen:
        $(MAKE) -C xen install
 
-tools:
+install-tools:
        $(MAKE) -C tools install
 
-kernels:
+install-kernels:
        for i in $(XKERNELS) ; do $(MAKE) $$i-build || exit 1; done
 
-docs:
+install-docs:
        sh ./docs/check_pkgs && $(MAKE) -C docs install || true
 
 dev-docs:
@@ -119,10 +124,6 @@
        tar -jxf iptables-1.2.11.tar.bz2
        $(MAKE) -C iptables-1.2.11 PREFIX= 
KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install
 
-install-%: DESTDIR=
-install-%: %
-       @: # do nothing
-
 help:
        @echo 'Installation targets:'
        @echo '  install          - build and install everything'
@@ -161,7 +162,6 @@
        @echo '                     with extreme care!)'
 
 # Use this target with extreme care!
-uninstall: DESTDIR=
 uninstall: D=$(DESTDIR)
 uninstall:
        [ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s` 
|| true
@@ -187,12 +187,5 @@
        rm -rf $(D)/usr/share/man/man8/xen*
 
 # Legacy targets for compatibility
-linux24:
-       $(MAKE) 'KERNELS=linux-2.4*' kernels
-
 linux26:
        $(MAKE) 'KERNELS=linux-2.6*' kernels
-
-netbsd20:
-       $(MAKE) netbsd-2.0-xenU-build
-
diff -r 0ba10f7fef51 -r 4e0c94871be2 README
--- a/README    Sat Oct  8 17:37:45 2005
+++ b/README    Sat Oct  8 20:28:24 2005
@@ -22,7 +22,7 @@
 GNU GPL.
 
 The 2.0 release offers excellent performance, hardware support and
-enterprise-grade features such as live migration. Linux 2.6, 2.4 and
+enterprise-grade features such as live migration. Linux 2.6 and
 NetBSD 2.0 are already available for Xen, with more operating system
 ports on the way.
 
@@ -97,8 +97,8 @@
    version for unstable.
 
 2. cd to xen-unstable (or whatever you sensibly rename it to).
-   The Linux (2.4 and 2.6), netbsd and freebsd kernel source
-   trees are in the $os-$version-xen-sparse directories.
+   The Linux, netbsd and freebsd kernel source trees are in
+   the $os-$version-xen-sparse directories.
 
 On Linux:
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 buildconfigs/Rules.mk
--- a/buildconfigs/Rules.mk     Sat Oct  8 17:37:45 2005
+++ b/buildconfigs/Rules.mk     Sat Oct  8 20:28:24 2005
@@ -1,10 +1,7 @@
 
 include Config.mk
 
-# We expect these two to already be set if people 
-# are using the top-level Makefile
-DISTDIR        ?= $(CURDIR)/dist
-DESTDIR        ?= $(DISTDIR)/install
+export DESTDIR
 
 ALLKERNELS = $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.*))
 ALLSPARSETREES = $(patsubst %-xen-sparse,%,$(wildcard *-xen-sparse))
diff -r 0ba10f7fef51 -r 4e0c94871be2 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Sat Oct  8 17:37:45 2005
+++ b/buildconfigs/mk.linux-2.6-xen     Sat Oct  8 20:28:24 2005
@@ -4,7 +4,7 @@
 LINUX_SERIES = 2.6
 LINUX_VER    = 2.6.12
 
-EXTRAVERSION = xen
+EXTRAVERSION ?= xen
 
 LINUX_DIR    = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 buildconfigs/mk.linux-2.6-xen0
--- a/buildconfigs/mk.linux-2.6-xen0    Sat Oct  8 17:37:45 2005
+++ b/buildconfigs/mk.linux-2.6-xen0    Sat Oct  8 20:28:24 2005
@@ -1,51 +1,2 @@
-
-OS           = linux
-
-LINUX_SERIES = 2.6
-LINUX_VER    = 2.6.12
-
 EXTRAVERSION = xen0
-
-LINUX_DIR    = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
-
-include buildconfigs/Rules.mk
-
-.PHONY: build clean delete
-
-# The real action starts here!
-build: $(LINUX_DIR)/include/linux/autoconf.h
-       if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) 
INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \
-       fi
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) 
install
-
-$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
-       rm -rf $(LINUX_DIR)
-       cp -al $(<D) $(LINUX_DIR)
-       # Apply arch-xen patches
-       ( cd linux-$(LINUX_SERIES)-xen-sparse ; \
-          LINUX_ARCH=$(LINUX_ARCH) ./mkbuildtree ../$(LINUX_DIR) )
-       # Re-use config from install dir if one exits else use default config
-       CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p' 
$(LINUX_DIR)/Makefile); \
-       [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
-         cp 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) 
$(LINUX_DIR)/.config \
-         || cp 
$(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH) \
-               $(LINUX_DIR)/.config
-       # See if we need to munge config to enable PAE
-       $(MAKE) CONFIG_FILE=$(LINUX_DIR)/.config -f buildconfigs/Rules.mk 
config-update-pae
-       # Patch kernel Makefile to set EXTRAVERSION
-       ( cd $(LINUX_DIR) ; \
-         sed -e 's/^EXTRAVERSION.*/&$$(XENGUEST)\nXENGUEST = 
-$(EXTRAVERSION)/' Makefile >Mk.tmp ; \
-         rm -f Makefile ; mv Mk.tmp Makefile )
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) oldconfig
-
-config: CONFIGMODE = menuconfig
-config: $(LINUX_DIR)/include/linux/autoconf.h
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) $(CONFIGMODE)
-
-clean::
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
-
-delete: 
-       rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR) 
+include buildconfigs/mk.linux-2.6-xen
diff -r 0ba10f7fef51 -r 4e0c94871be2 buildconfigs/mk.linux-2.6-xenU
--- a/buildconfigs/mk.linux-2.6-xenU    Sat Oct  8 17:37:45 2005
+++ b/buildconfigs/mk.linux-2.6-xenU    Sat Oct  8 20:28:24 2005
@@ -1,51 +1,2 @@
-
-OS           = linux
-
-LINUX_SERIES = 2.6
-LINUX_VER    = 2.6.12
-
 EXTRAVERSION = xenU
-
-LINUX_DIR    = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
-
-include buildconfigs/Rules.mk
-
-.PHONY: build clean delete
-
-# The real action starts here!
-build: $(LINUX_DIR)/include/linux/autoconf.h
-       if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) 
INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \
-       fi
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) 
install
-
-$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
-       rm -rf $(LINUX_DIR)
-       cp -al $(<D) $(LINUX_DIR)
-       # Apply arch-xen patches
-       ( cd linux-$(LINUX_SERIES)-xen-sparse ; \
-          LINUX_ARCH=$(LINUX_ARCH) ./mkbuildtree ../$(LINUX_DIR) )
-       # Re-use config from install dir if one exits else use default config
-       CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p' 
$(LINUX_DIR)/Makefile); \
-       [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
-         cp 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) 
$(LINUX_DIR)/.config \
-         || cp 
$(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH) \
-               $(LINUX_DIR)/.config
-       # See if we need to munge config to enable PAE
-       $(MAKE) CONFIG_FILE=$(LINUX_DIR)/.config -f buildconfigs/Rules.mk 
config-update-pae
-       # Patch kernel Makefile to set EXTRAVERSION
-       ( cd $(LINUX_DIR) ; \
-         sed -e 's/^EXTRAVERSION.*/&$$(XENGUEST)\nXENGUEST = 
-$(EXTRAVERSION)/' Makefile >Mk.tmp ; \
-         rm -f Makefile ; mv Mk.tmp Makefile )
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) oldconfig
-
-config: CONFIGMODE = menuconfig
-config: $(LINUX_DIR)/include/linux/autoconf.h
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) $(CONFIGMODE)
-
-clean::
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
-
-delete: 
-       rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR) 
+include buildconfigs/mk.linux-2.6-xen
diff -r 0ba10f7fef51 -r 4e0c94871be2 docs/misc/xen_config.html
--- a/docs/misc/xen_config.html Sat Oct  8 17:37:45 2005
+++ b/docs/misc/xen_config.html Sat Oct  8 20:28:24 2005
@@ -154,7 +154,7 @@
     (memory 64)
     (image
         (linux
-            (kernel /boot/vmlinuz-2.4.26-xen)
+            (kernel /boot/vmlinuz-2.6.12-xen)
             (ip ::::xendom1:eth0:dhcp)
             (root /dev/xda1)
             (args 'rw fastboot 4')
diff -r 0ba10f7fef51 -r 4e0c94871be2 docs/src/user/installation.tex
--- a/docs/src/user/installation.tex    Sat Oct  8 17:37:45 2005
+++ b/docs/src/user/installation.tex    Sat Oct  8 20:28:24 2005
@@ -1,7 +1,7 @@
 \chapter{Installation}
 
 The Xen distribution includes three main components: Xen itself, ports
-of Linux 2.4 and 2.6 and NetBSD to run on Xen, and the userspace
+of Linux and NetBSD to run on Xen, and the userspace
 tools required to manage a Xen-based system.  This chapter describes
 how to install the Xen~2.0 distribution from source.  Alternatively,
 there may be pre-built packages available as part of your operating
@@ -169,7 +169,7 @@
 
 You can edit this line to include any set of operating system kernels
 which have configurations in the top-level \path{buildconfigs/}
-directory, for example \path{mk.linux-2.4-xenU} to build a Linux 2.4
+directory, for example \path{mk.linux-2.6-xenU} to build a Linux 2.6
 kernel containing only virtual device drivers.
 
 %% Inspect the Makefile if you want to see what goes on during a
@@ -190,10 +190,6 @@
 %%   mkbuildtree} script to add the Xen patches to the kernel.
 
 
-%% The procedure is similar to build the Linux 2.4 port: \\
-%% \verb!# LINUX_SRC=/path/to/linux2.4/source make linux24!
-
-
 %% \framebox{\parbox{5in}{
 %%     {\bf Distro specific:} \\
 %%     {\it Gentoo} --- if not using udev (most installations,
diff -r 0ba10f7fef51 -r 4e0c94871be2 docs/src/user/introduction.tex
--- a/docs/src/user/introduction.tex    Sat Oct  8 17:37:45 2005
+++ b/docs/src/user/introduction.tex    Sat Oct  8 20:28:24 2005
@@ -28,7 +28,7 @@
 space applications and libraries \emph{do not} require modification.
 
 Xen support is available for increasingly many operating systems:
-right now, Linux 2.4, Linux 2.6 and NetBSD are available for Xen 2.0.
+right now, Linux and NetBSD are available for Xen 2.0.
 A FreeBSD port is undergoing testing and will be incorporated into the
 release soon. Other OS ports, including Plan 9, are in progress.  We
 hope that that arch-xen patches will be incorporated into the
diff -r 0ba10f7fef51 -r 4e0c94871be2 install.sh
--- a/install.sh        Sat Oct  8 17:37:45 2005
+++ b/install.sh        Sat Oct  8 20:28:24 2005
@@ -23,9 +23,15 @@
 fi
 
 echo "Installing Xen from '$src' to '$dst'..."
-(cd $src; tar -cf - --exclude etc/init.d * ) | tar -C $dst -xf -
+(cd $src; tar -cf - --exclude etc/init.d --exclude etc/hotplug --exclude 
etc/udev * ) | tar -C $dst -xf -
 cp -fdRL $src/etc/init.d/* $dst/etc/init.d/
 echo "All done."
+
+if [ -x /sbin/udev ] && [ ! -z `udev -V` ] && [ `/sbin/udev -V` -ge 059 ]; then
+  cp -f $src/etc/udev/rules.d/*.rules $dst/etc/udev/rules.d/
+else
+  cp -f $src/etc/hotplug/*.agent $dst/etc/hotplug/
+fi
 
 echo "Checking to see whether prerequisite tools are installed..."
 cd $src/../check
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.6-xen-sparse/arch/ia64/Makefile
--- a/linux-2.6-xen-sparse/arch/ia64/Makefile   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/ia64/Makefile   Sat Oct  8 20:28:24 2005
@@ -88,7 +88,6 @@
 
 CLEAN_FILES += include/asm-ia64/.offsets.h.stamp vmlinux.gz bootloader
 #CLEAN_FILES += include/asm-xen/xen-public 
include/asm-ia64/xen/asm-xsi-offsets.h
-#CLEAN_FILES += include/asm-xen/linux-public/xenstored.h
 #CLEAN_FILES += include/asm-xen/linux-public 
include/asm-xen/asm-ia64/hypervisor.h
 
 MRPROPER_FILES += include/asm-ia64/offsets.h
@@ -119,9 +118,6 @@
 #      [ -e include/asm-xen/linux-public ] \
 #       || ln -s $(XEN_PATH)/linux-2.6-xen-sparse/include/asm-xen/linux-public 
\
                include/asm-xen/linux-public
-       [ -e include/asm-xen/linux-public/xenstored.h ] \
-        || ln -s $(XEN_PATH)/tools/xenstore/xenstored.h \
-               include/asm-xen/linux-public/xenstored.h
        [ -e include/asm-xen/asm-ia64/hypervisor.h ] \
         || ln -s 
$(XEN_PATH)/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypervisor.h \
                include/asm-xen/asm-ia64/hypervisor.h
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.6-xen-sparse/arch/xen/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/Makefile    Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/Makefile    Sat Oct  8 20:28:24 2005
@@ -63,6 +63,9 @@
 vmlinuz: vmlinux
        $(Q)$(MAKE) $(build)=arch/xen/boot vmlinuz
 
+bzImage: vmlinuz
+       $(Q)$(MAKE) $(build)=arch/xen/boot bzImage
+
 XINSTALL_NAME ?= $(KERNELRELEASE)
 install: vmlinuz
 install kernel_install:
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.6-xen-sparse/arch/xen/boot/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/boot/Makefile       Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/boot/Makefile       Sat Oct  8 20:28:24 2005
@@ -6,3 +6,6 @@
 
 vmlinux-stripped: vmlinux FORCE
        $(call if_changed,objcopy)
+
+bzImage: vmlinuz
+       $(Q)$(LN) -sf ../../../vmlinuz $(srctree)/arch/xen/boot/bzImage
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile        Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile        Sat Oct  8 
20:28:24 2005
@@ -86,7 +86,7 @@
        $(call if_changed,syscall)
 
 c-link :=
-s-link := vsyscall-int80.o vsyscall-sysenter.o vsyscall-sigreturn.o 
vsyscall.lds.o vsyscall-note.o
+s-link := vsyscall-int80.o vsyscall-sysenter.o vsyscall-sigreturn.o 
vsyscall.lds.o
 
 $(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-obj-m) $(c-link)) $(patsubst 
%.o,$(obj)/%.S,$(s-obj-y) $(s-link)):
        @ln -fsn $(srctree)/arch/i386/kernel/$(notdir $@) $@
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c       Sat Oct  8 
20:28:24 2005
@@ -49,6 +49,7 @@
 #include <asm/irq.h>
 #include <asm/desc.h>
 #include <asm-xen/xen-public/physdev.h>
+#include <asm-xen/xen-public/vcpu.h>
 #ifdef CONFIG_MATH_EMULATION
 #include <asm/math_emu.h>
 #endif
@@ -105,7 +106,8 @@
                local_irq_enable();
        } else {
                stop_hz_timer();
-               HYPERVISOR_block(); /* implicit local_irq_enable() */
+               /* Blocking includes an implicit local_irq_enable(). */
+               HYPERVISOR_sched_op(SCHEDOP_block, 0);
                start_hz_timer();
        }
 }
@@ -121,7 +123,7 @@
 {
        /* Death loop */
        while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
-               HYPERVISOR_yield();
+               HYPERVISOR_sched_op(SCHEDOP_yield, 0);
 
        __flush_tlb_all();
    /* 
@@ -140,6 +142,13 @@
        BUG();
 }
 #endif /* CONFIG_HOTPLUG_CPU */
+
+void cpu_restore(void)
+{
+       play_dead();
+       local_irq_enable();
+       cpu_idle();
+}
 
 /*
  * The idle thread. There's no useful work to be
@@ -171,7 +180,7 @@
                                   don't printk. */
                                __get_cpu_var(cpu_state) = CPU_DEAD;
                                /* Tell hypervisor to take vcpu down. */
-                               HYPERVISOR_vcpu_down(cpu);
+                               HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL);
 #endif
                                play_dead();
                                local_irq_enable();
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Sat Oct  8 20:28:24 2005
@@ -365,6 +365,7 @@
 
 /* Raw start-of-day parameters from the hypervisor. */
 start_info_t *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
 
 static void __init limit_regions(unsigned long long size)
 {
@@ -1783,7 +1784,7 @@
 static int
 xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
-       HYPERVISOR_crash();    
+       HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
        /* we're never actually going to get here... */
        return NOTIFY_DONE;
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c       Sat Oct  8 
20:28:24 2005
@@ -63,6 +63,7 @@
 #include <smpboot_hooks.h>
 
 #include <asm-xen/evtchn.h>
+#include <asm-xen/xen-public/vcpu.h>
 
 /* Set if we find a B stepping CPU */
 static int __initdata smp_b_stepping;
@@ -802,7 +803,6 @@
        extern void hypervisor_callback(void);
        extern void failsafe_callback(void);
        extern void smp_trap_init(trap_info_t *);
-       int i;
 
        cpu = ++cpucount;
        /*
@@ -853,12 +853,6 @@
        /* FPU is set up to default initial state. */
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
 
-       /* Virtual IDT is empty at start-of-day. */
-       for ( i = 0; i < 256; i++ )
-       {
-               ctxt.trap_ctxt[i].vector = i;
-               ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-       }
        smp_trap_init(ctxt.trap_ctxt);
 
        /* No LDT. */
@@ -889,11 +883,13 @@
 
        ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
 
-       boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
+       boot_error = HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, &ctxt);
        if (boot_error)
                printk("boot error: %ld\n", boot_error);
 
        if (!boot_error) {
+               HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
+
                /*
                 * allow APs to start initializing.
                 */
@@ -1506,7 +1502,7 @@
 #ifdef CONFIG_HOTPLUG_CPU
 #ifdef CONFIG_XEN
        /* Tell hypervisor to bring vcpu up. */
-       HYPERVISOR_vcpu_up(cpu);
+       HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
 #endif
        /* Already up, and in cpu_quiescent now? */
        if (cpu_isset(cpu, smp_commenced_mask)) {
@@ -1585,61 +1581,49 @@
        local_setup_timer_irq();
 }
 
-static atomic_t vcpus_rebooting;
-
-static void restore_vcpu_ready(void)
-{
-
-       atomic_dec(&vcpus_rebooting);
-}
-
-void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       int r;
-       int gdt_pages;
-       r = HYPERVISOR_vcpu_pickle(vcpu, ctxt);
-       if (r != 0)
-               panic("pickling vcpu %d -> %d!\n", vcpu, r);
-
-       /* Translate from machine to physical addresses where necessary,
-          so that they can be translated to our new machine address space
-          after resume.  libxc is responsible for doing this to vcpu0,
-          but we do it to the others. */
-       gdt_pages = (ctxt->gdt_ents + 511) / 512;
-       ctxt->ctrlreg[3] = machine_to_phys(ctxt->ctrlreg[3]);
-       for (r = 0; r < gdt_pages; r++)
-               ctxt->gdt_frames[r] = mfn_to_pfn(ctxt->gdt_frames[r]);
-}
-
-int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       int r;
-       int gdt_pages = (ctxt->gdt_ents + 511) / 512;
-
-       /* This is kind of a hack, and implicitly relies on the fact that
-          the vcpu stops in a place where all of the call clobbered
-          registers are already dead. */
-       ctxt->user_regs.esp -= 4;
-       ((unsigned long *)ctxt->user_regs.esp)[0] = ctxt->user_regs.eip;
-       ctxt->user_regs.eip = (unsigned long)restore_vcpu_ready;
-
-       /* De-canonicalise.  libxc handles this for vcpu 0, but we need
-          to do it for the other vcpus. */
-       ctxt->ctrlreg[3] = phys_to_machine(ctxt->ctrlreg[3]);
-       for (r = 0; r < gdt_pages; r++)
-               ctxt->gdt_frames[r] = pfn_to_mfn(ctxt->gdt_frames[r]);
-
-       atomic_set(&vcpus_rebooting, 1);
-       r = HYPERVISOR_boot_vcpu(vcpu, ctxt);
-       if (r != 0) {
-               printk(KERN_EMERG "Failed to reboot vcpu %d (%d)\n", vcpu, r);
-               return -1;
-       }
-
-       /* Make sure we wait for the new vcpu to come up before trying to do
-          anything with it or starting the next one. */
-       while (atomic_read(&vcpus_rebooting))
-               barrier();
-
-       return 0;
-}
+void vcpu_prepare(int vcpu)
+{
+       extern void hypervisor_callback(void);
+       extern void failsafe_callback(void);
+       extern void smp_trap_init(trap_info_t *);
+       extern void cpu_restore(void);
+       vcpu_guest_context_t ctxt;
+       struct task_struct *idle = idle_task(vcpu);
+
+       if (vcpu == 0)
+               return;
+
+       memset(&ctxt, 0, sizeof(ctxt));
+
+       ctxt.user_regs.ds = __USER_DS;
+       ctxt.user_regs.es = __USER_DS;
+       ctxt.user_regs.fs = 0;
+       ctxt.user_regs.gs = 0;
+       ctxt.user_regs.ss = __KERNEL_DS;
+       ctxt.user_regs.cs = __KERNEL_CS;
+       ctxt.user_regs.eip = (unsigned long)cpu_restore;
+       ctxt.user_regs.esp = idle->thread.esp;
+       ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1;
+
+       memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
+
+       smp_trap_init(ctxt.trap_ctxt);
+
+       ctxt.ldt_ents = 0;
+
+       ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[vcpu].address);
+       ctxt.gdt_ents      = cpu_gdt_descr[vcpu].size / 8;
+
+       ctxt.kernel_ss = __KERNEL_DS;
+       ctxt.kernel_sp = idle->thread.esp0;
+
+       ctxt.event_callback_cs     = __KERNEL_CS;
+       ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
+       ctxt.failsafe_callback_cs  = __KERNEL_CS;
+       ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
+
+       ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
+
+       (void)HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt);
+       (void)HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL);
+}
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Sat Oct  8 20:28:24 2005
@@ -1012,6 +1012,12 @@
 void smp_trap_init(trap_info_t *trap_ctxt)
 {
        trap_info_t *t = trap_table;
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               trap_ctxt[i].vector = i;
+               trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+       }
 
        for (t = trap_table; t->address; t++) {
                trap_ctxt[t->vector].flags = t->flags;
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c   Sat Oct  8 20:28:24 2005
@@ -52,24 +52,30 @@
                                    pgprot_t prot,
                                    domid_t  domid)
 {
-       int i;
+       int i, rc;
        unsigned long start_address;
-#define MAX_DIRECTMAP_MMU_QUEUE 130
-       mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u, *w = u;
+       mmu_update_t *u, *v, *w;
+
+       u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+       if (u == NULL)
+               return -ENOMEM;
 
        start_address = address;
 
        flush_cache_all();
 
        for (i = 0; i < size; i += PAGE_SIZE) {
-               if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
+               if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
                        /* Fill in the PTE pointers. */
-                       generic_page_range(mm, start_address, 
-                                          address - start_address,
-                                          direct_remap_area_pte_fn, &w);
+                       rc = generic_page_range(mm, start_address, 
+                                               address - start_address,
+                                               direct_remap_area_pte_fn, &w);
+                       if (rc)
+                               goto out;
                        w = u;
+                       rc = -EFAULT;
                        if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
-                               return -EFAULT;
+                               goto out;
                        v = u;
                        start_address = address;
                }
@@ -89,13 +95,19 @@
                /* get the ptep's filled in */
                generic_page_range(mm, start_address, address - start_address,
                                   direct_remap_area_pte_fn, &w);
+               rc = -EFAULT;
                if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
-                       return -EFAULT;
-       }
-
+                       goto out;
+       }
+
+       rc = 0;
+
+ out:
        flush_tlb_all();
 
-       return 0;
+       free_page((unsigned long)u);
+
+       return rc;
 }
 
 int direct_remap_pfn_range(struct vm_area_struct *vma,
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Sat Oct  8 20:28:24 2005
@@ -180,15 +180,15 @@
 
 int bind_virq_to_irq(int virq)
 {
-       evtchn_op_t op;
+       evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq };
        int evtchn, irq;
        int cpu = smp_processor_id();
 
        spin_lock(&irq_mapping_update_lock);
 
        if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
-               op.cmd              = EVTCHNOP_bind_virq;
                op.u.bind_virq.virq = virq;
+               op.u.bind_virq.vcpu = cpu;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_virq.port;
 
@@ -211,7 +211,7 @@
 
 void unbind_virq_from_irq(int virq)
 {
-       evtchn_op_t op;
+       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        int cpu    = smp_processor_id();
        int irq    = per_cpu(virq_to_irq, cpu)[virq];
        int evtchn = irq_to_evtchn[irq];
@@ -219,8 +219,6 @@
        spin_lock(&irq_mapping_update_lock);
 
        if (--irq_bindcount[irq] == 0) {
-               op.cmd          = EVTCHNOP_close;
-               op.u.close.dom  = DOMID_SELF;
                op.u.close.port = evtchn;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
 
@@ -244,14 +242,14 @@
 
 int bind_ipi_to_irq(int ipi)
 {
-       evtchn_op_t op;
+       evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi };
        int evtchn, irq;
        int cpu = smp_processor_id();
 
        spin_lock(&irq_mapping_update_lock);
 
        if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
-               op.cmd = EVTCHNOP_bind_ipi;
+               op.u.bind_ipi.vcpu = cpu;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_ipi.port;
 
@@ -276,7 +274,7 @@
 
 void unbind_ipi_from_irq(int ipi)
 {
-       evtchn_op_t op;
+       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        int cpu    = smp_processor_id();
        int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
        int irq    = evtchn_to_irq[evtchn];
@@ -284,8 +282,6 @@
        spin_lock(&irq_mapping_update_lock);
 
        if (--irq_bindcount[irq] == 0) {
-               op.cmd          = EVTCHNOP_close;
-               op.u.close.dom  = DOMID_SELF;
                op.u.close.port = evtchn;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
 
@@ -300,7 +296,7 @@
 }
 EXPORT_SYMBOL(unbind_ipi_from_irq);
 
-int bind_evtchn_to_irq(unsigned int evtchn)
+static int bind_evtchn_to_irq(unsigned int evtchn)
 {
        int irq;
 
@@ -318,18 +314,15 @@
     
        return irq;
 }
-EXPORT_SYMBOL(bind_evtchn_to_irq);
-
-void unbind_evtchn_from_irq(unsigned int irq)
-{
-       evtchn_op_t op;
+
+static void unbind_evtchn_from_irq(unsigned int irq)
+{
+       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        int evtchn = irq_to_evtchn[irq];
 
        spin_lock(&irq_mapping_update_lock);
 
        if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
-               op.cmd          = EVTCHNOP_close;
-               op.u.close.dom  = DOMID_SELF;
                op.u.close.port = evtchn;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
 
@@ -339,7 +332,6 @@
 
        spin_unlock(&irq_mapping_update_lock);
 }
-EXPORT_SYMBOL(unbind_evtchn_from_irq);
 
 int bind_evtchn_to_irqhandler(
        unsigned int evtchn,
@@ -353,8 +345,10 @@
 
        irq = bind_evtchn_to_irq(evtchn);
        retval = request_irq(irq, handler, irqflags, devname, dev_id);
-       if (retval != 0)
+       if (retval != 0) {
                unbind_evtchn_from_irq(irq);
+               return retval;
+       }
 
        return irq;
 }
@@ -376,7 +370,7 @@
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
 static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 {
-       evtchn_op_t op;
+       evtchn_op_t op = { .cmd = EVTCHNOP_bind_vcpu };
        int evtchn;
 
        spin_lock(&irq_mapping_update_lock);
@@ -387,7 +381,6 @@
        }
 
        /* Send future instances of this interrupt to other vcpu. */
-       op.cmd = EVTCHNOP_bind_vcpu;
        op.u.bind_vcpu.port = evtchn;
        op.u.bind_vcpu.vcpu = tcpu;
 
@@ -516,10 +509,12 @@
 
 static unsigned int startup_pirq(unsigned int irq)
 {
-       evtchn_op_t op;
-       int evtchn;
-
-       op.cmd               = EVTCHNOP_bind_pirq;
+       evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               goto out;
+
        op.u.bind_pirq.pirq  = irq;
        /* NB. We are happy to share unless we are probing. */
        op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
@@ -537,6 +532,7 @@
        evtchn_to_irq[evtchn] = irq;
        irq_to_evtchn[irq]    = evtchn;
 
+ out:
        unmask_evtchn(evtchn);
        pirq_unmask_notify(irq_to_pirq(irq));
 
@@ -545,7 +541,7 @@
 
 static void shutdown_pirq(unsigned int irq)
 {
-       evtchn_op_t op;
+       evtchn_op_t op = { .cmd = EVTCHNOP_close };
        int evtchn = irq_to_evtchn[irq];
 
        if (!VALID_EVTCHN(evtchn))
@@ -553,8 +549,6 @@
 
        mask_evtchn(evtchn);
 
-       op.cmd          = EVTCHNOP_close;
-       op.u.close.dom  = DOMID_SELF;
        op.u.close.port = evtchn;
        BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
 
@@ -629,6 +623,7 @@
        if (VALID_EVTCHN(evtchn))
                notify_remote_via_evtchn(evtchn);
 }
+EXPORT_SYMBOL(notify_remote_via_irq);
 
 void irq_resume(void)
 {
@@ -663,8 +658,10 @@
                        continue;
 
                /* Get a new binding from Xen. */
+               memset(&op, 0, sizeof(op));
                op.cmd              = EVTCHNOP_bind_virq;
                op.u.bind_virq.virq = virq;
+               op.u.bind_virq.vcpu = 0;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_virq.port;
         
@@ -685,7 +682,9 @@
                evtchn_to_irq[evtchn] = -1;
 
                /* Get a new binding from Xen. */
+               memset(&op, 0, sizeof(op));
                op.cmd = EVTCHNOP_bind_ipi;
+               op.u.bind_ipi.vcpu = 0;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_ipi.port;
         
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Sat Oct  8 20:28:24 2005
@@ -20,13 +20,19 @@
 #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!
+// HALT is the same as POWEROFF, as far as we're concerned.  The tools use
+// the distinction when we return the reason code to them.
+#define SHUTDOWN_HALT      4
+
 
 void machine_restart(char * __unused)
 {
        /* We really want to get pending console data out before we die. */
        extern void xencons_force_flush(void);
        xencons_force_flush();
-       HYPERVISOR_reboot();
+       HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_reboot);
 }
 
 void machine_halt(void)
@@ -39,7 +45,7 @@
        /* We really want to get pending console data out before we die. */
        extern void xencons_force_flush(void);
        xencons_force_flush();
-       HYPERVISOR_shutdown();
+       HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_poweroff);
 }
 
 int reboot_thru_bios = 0;      /* for dmi_scan.c */
@@ -74,11 +80,8 @@
        extern unsigned long *pfn_to_mfn_frame_list[];
 
 #ifdef CONFIG_SMP
-       static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
-       cpumask_t prev_online_cpus, prev_present_cpus;
-
-       void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
-       int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
+       cpumask_t prev_online_cpus;
+       int vcpu_prepare(int vcpu);
 #endif
 
        extern void xencons_resume(void);
@@ -98,25 +101,20 @@
 
        xenbus_suspend();
 
-       preempt_disable();
+       lock_cpu_hotplug();
 #ifdef CONFIG_SMP
-       /* Take all of the other cpus offline.  We need to be careful not
-          to get preempted between the final test for num_online_cpus()
-          == 1 and disabling interrupts, since otherwise userspace could
-          bring another cpu online, and then we'd be stuffed.  At the
-          same time, cpu_down can reschedule, so we need to enable
-          preemption while doing that.  This kind of sucks, but should be
-          correct. */
-       /* (We don't need to worry about other cpus bringing stuff up,
-          since by the time num_online_cpus() == 1, there aren't any
-          other cpus) */
+       /*
+        * Take all other CPUs offline. We hold the hotplug semaphore to
+        * avoid other processes bringing up CPUs under our feet.
+        */
        cpus_clear(prev_online_cpus);
        while (num_online_cpus() > 1) {
-               preempt_enable();
                for_each_online_cpu(i) {
                        if (i == 0)
                                continue;
+                       unlock_cpu_hotplug();
                        err = cpu_down(i);
+                       lock_cpu_hotplug();
                        if (err != 0) {
                                printk(KERN_CRIT "Failed to take all CPUs "
                                       "down: %d.\n", err);
@@ -124,39 +122,32 @@
                        }
                        cpu_set(i, prev_online_cpus);
                }
-               preempt_disable();
-       }
-#endif
-
-       __cli();
-
-       preempt_enable();
-
-#ifdef CONFIG_SMP
-       cpus_clear(prev_present_cpus);
-       for_each_present_cpu(i) {
-               if (i == 0)
-                       continue;
-               save_vcpu_context(i, &suspended_cpu_records[i]);
-               cpu_set(i, prev_present_cpus);
-       }
-#endif
-
-       gnttab_suspend();
+       }
+#endif
+
+       preempt_disable();
 
 #ifdef __i386__
        mm_pin_all();
        kmem_cache_shrink(pgd_cache);
 #endif
 
+       __cli();
+       preempt_enable();
+       unlock_cpu_hotplug();
+
+       gnttab_suspend();
+
        HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
        clear_fixmap(FIX_SHARED_INFO);
 
        xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
        xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn);
 
-       /* We'll stop somewhere inside this hypercall.  When it returns,
-          we'll start resuming after the restore. */
+       /*
+        * We'll stop somewhere inside this hypercall. When it returns,
+        * we'll start resuming after the restore.
+        */
        HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
 
        shutting_down = SHUTDOWN_INVALID; 
@@ -189,18 +180,16 @@
 
        time_resume();
 
+       __sti();
+
+       xencons_resume();
+
+       xenbus_resume();
+
 #ifdef CONFIG_SMP
-       for_each_cpu_mask(i, prev_present_cpus)
-               restore_vcpu_context(i, &suspended_cpu_records[i]);
-#endif
-
-       __sti();
-
-       xencons_resume();
-
-       xenbus_resume();
-
-#ifdef CONFIG_SMP
+       for_each_present_cpu(i)
+               vcpu_prepare(i);
+
  out_reenable_cpus:
        for_each_cpu_mask(i, prev_online_cpus) {
                j = cpu_up(i);
@@ -230,6 +219,7 @@
 
        switch (shutting_down) {
        case SHUTDOWN_POWEROFF:
+       case SHUTDOWN_HALT:
                if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
                        sys_reboot(LINUX_REBOOT_MAGIC1,
                                   LINUX_REBOOT_MAGIC2,
@@ -311,6 +301,8 @@
                shutting_down = SHUTDOWN_REBOOT;
        else if (strcmp(str, "suspend") == 0)
                shutting_down = SHUTDOWN_SUSPEND;
+       else if (strcmp(str, "halt") == 0)
+               shutting_down = SHUTDOWN_HALT;
        else {
                printk("Ignoring shutdown request: %s\n", str);
                shutting_down = SHUTDOWN_INVALID;
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile      Sat Oct  8 
20:28:24 2005
@@ -51,7 +51,7 @@
 cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../../i386/kernel/cpuid.o
 topology-y                     += ../../../i386/mach-default/topology.o
 #swiotlb-$(CONFIG_SWIOTLB)      += ../../../ia64/lib/swiotlb.o
-microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../../i386/kernel/microcode.o
+microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
 intel_cacheinfo-y              += ../../../i386/kernel/cpu/intel_cacheinfo.o
 quirks-y                       += ../../i386/kernel/quirks.o
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c     Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c     Sat Oct  8 
20:28:24 2005
@@ -96,7 +96,8 @@
                local_irq_enable();
        } else {
                stop_hz_timer();
-               HYPERVISOR_block(); /* implicit local_irq_enable() */
+               /* Blocking includes an implicit local_irq_enable(). */
+               HYPERVISOR_sched_op(SCHEDOP_block, 0);
                start_hz_timer();
        }
 }
@@ -114,7 +115,7 @@
         * it "work" for testing purposes. */
        /* Death loop */
        while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
-               HYPERVISOR_yield();
+               HYPERVISOR_sched_op(SCHEDOP_yield, 0);
 
        local_irq_disable();
        __flush_tlb_all();
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Sat Oct  8 
20:28:24 2005
@@ -86,6 +86,7 @@
 
 /* Raw start-of-day parameters from the hypervisor. */
 start_info_t *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
 #endif
 
 /*
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c     Sat Oct  8 
20:28:24 2005
@@ -62,8 +62,8 @@
 #include <asm/nmi.h>
 #ifdef CONFIG_XEN
 #include <asm/arch_hooks.h>
-
 #include <asm-xen/evtchn.h>
+#include <asm-xen/xen-public/vcpu.h>
 #endif
 
 /* Change for real CPU hotplug. Note other files need to be fixed
@@ -742,12 +742,6 @@
        /* FPU is set up to default initial state. */
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
 
-       /* Virtual IDT is empty at start-of-day. */
-       for ( i = 0; i < 256; i++ )
-       {
-               ctxt.trap_ctxt[i].vector = i;
-               ctxt.trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-       }
        smp_trap_init(ctxt.trap_ctxt);
 
        /* No LDT. */
@@ -777,11 +771,13 @@
 
        ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
 
-       boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt);
+       boot_error  = HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, &ctxt);
        if (boot_error)
                printk("boot error: %ld\n", boot_error);
 
        if (!boot_error) {
+               HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
+
                /*
                 * allow APs to start initializing.
                 */
@@ -1267,13 +1263,8 @@
        local_setup_timer_irq();
 }
 
-void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-}
-
-int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt)
-{
-       return 0;
-}
-
-#endif
+void vcpu_prepare(int vcpu)
+{
+}
+
+#endif
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Sat Oct  8 
20:28:24 2005
@@ -956,6 +956,12 @@
 void smp_trap_init(trap_info_t *trap_ctxt)
 {
        trap_info_t *t = trap_table;
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               trap_ctxt[i].vector = i;
+               trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+       }
 
        for (t = trap_table; t->address; t++) {
                trap_ctxt[t->vector].flags = t->flags;
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/char/tpm/Makefile
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile    Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile    Sat Oct  8 20:28:24 2005
@@ -5,8 +5,9 @@
 obj-$(CONFIG_TCG_TPM) += tpm.o
 obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
 obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
-obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
+obj-$(CONFIG_TCG_TIS) += tpm_tis.o
+obj-$(CONFIG_TCG_XEN) += tpm_xen.o
 else
-obj-$(CONFIG_TCG_TPM) += tpm_nopci.o
+obj-$(CONFIG_TCG_TPM) += tpm.o
 obj-$(CONFIG_TCG_XEN) += tpm_xen.o
 endif
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Sat Oct  8 20:28:24 2005
@@ -25,7 +25,7 @@
 #include <linux/tpmfe.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
-#include "tpm_nopci.h"
+#include "tpm.h"
 
 /* read status bits */
 enum {
@@ -434,6 +434,21 @@
        .release = tpm_release,
 };
 
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute* xen_attrs[] = {
+       &dev_attr_pubek.attr,
+       &dev_attr_pcrs.attr,
+       &dev_attr_caps.attr,
+       &dev_attr_cancel.attr,
+       0,
+};
+
+static struct attribute_group xen_attr_grp = { .attrs = xen_attrs };
+
 static struct tpm_vendor_specific tpm_xen = {
        .recv = tpm_xen_recv,
        .send = tpm_xen_send,
@@ -443,8 +458,9 @@
        .req_complete_val  = STATUS_DATA_AVAIL,
        .req_canceled = STATUS_READY,
        .base = 0,
-       .attr = TPM_DEVICE_ATTRS,
+       .attr_group = &xen_attr_grp,
        .miscdev.fops = &tpm_xen_ops,
+       .buffersize = 64 * 1024,
 };
 
 static struct device tpm_device = {
@@ -477,7 +493,9 @@
                return rc;
        }
 
-       if ((rc = tpm_register_hardware_nopci(&tpm_device, &tpm_xen)) < 0) {
+       tpm_xen.buffersize = tpmfe.max_tx_size;
+
+       if ((rc = tpm_register_hardware(&tpm_device, &tpm_xen)) < 0) {
                device_unregister(&tpm_device);
                tpm_fe_unregister_receiver();
                return rc;
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Sat Oct  8 
20:28:24 2005
@@ -351,7 +351,8 @@
 };
 
 /* React to a change in the target key */
-static void watch_target(struct xenbus_watch *watch, const char *node)
+static void watch_target(struct xenbus_watch *watch,
+                        const char **vec, unsigned int len)
 {
        unsigned long long new_target;
        int err;
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Sat Oct  8 
20:28:24 2005
@@ -68,8 +68,15 @@
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
        blkif_sring_t *sring;
-       evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
+       evtchn_op_t op = {
+               .cmd = EVTCHNOP_bind_interdomain,
+               .u.bind_interdomain.remote_dom = blkif->domid,
+               .u.bind_interdomain.remote_port = evtchn };
+
+       /* Already connected through? */
+       if (blkif->irq)
+               return 0;
 
        if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
                return -ENOMEM;
@@ -80,10 +87,6 @@
                return err;
        }
 
-       op.u.bind_interdomain.dom1 = DOMID_SELF;
-       op.u.bind_interdomain.dom2 = blkif->domid;
-       op.u.bind_interdomain.port1 = 0;
-       op.u.bind_interdomain.port2 = evtchn;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                unmap_frontend_page(blkif);
@@ -91,7 +94,7 @@
                return err;
        }
 
-       blkif->evtchn = op.u.bind_interdomain.port1;
+       blkif->evtchn = op.u.bind_interdomain.local_port;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        SHARED_RING_INIT(sring);
@@ -108,8 +111,12 @@
 {
        blkif_t *blkif = (blkif_t *)arg;
 
-       if (blkif->irq)
-               unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+       /* Already disconnected? */
+       if (!blkif->irq)
+               return;
+
+       unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+       blkif->irq = 0;
 
        vbd_free(&blkif->vbd);
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Sat Oct  8 20:28:24 2005
@@ -55,7 +55,8 @@
 }
 
 /* Front end tells us frame. */
-static void frontend_changed(struct xenbus_watch *watch, const char *node)
+static void frontend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
 {
        unsigned long ring_ref;
        unsigned int evtchn;
@@ -64,7 +65,7 @@
                = container_of(watch, struct backend_info, watch);
 
        /* If other end is gone, delete ourself. */
-       if (node && !xenbus_exists(be->frontpath, "")) {
+       if (vec && !xenbus_exists(be->frontpath, "")) {
                device_unregister(&be->dev->dev);
                return;
        }
@@ -143,7 +144,8 @@
    We provide event channel and device details to front end.
    Frontend supplies shared frame and event channel.
  */
-static void backend_changed(struct xenbus_watch *watch, const char *node)
+static void backend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
 {
        int err;
        char *p;
@@ -195,7 +197,7 @@
                }
 
                /* Pass in NULL node to skip exist test. */
-               frontend_changed(&be->watch, NULL);
+               frontend_changed(&be->watch, NULL, 0);
        }
 }
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sat Oct  8 
20:28:24 2005
@@ -53,8 +53,6 @@
 #define BLKIF_STATE_DISCONNECTED 0
 #define BLKIF_STATE_CONNECTED    1
 
-static unsigned int blkif_state = BLKIF_STATE_DISCONNECTED;
-
 #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
     (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
 #define GRANT_INVALID_REF      0
@@ -444,12 +442,16 @@
        { "" }
 };
 
-static void watch_for_status(struct xenbus_watch *watch, const char *node)
+static void watch_for_status(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
 {
        struct blkfront_info *info;
        unsigned int binfo;
        unsigned long sectors, sector_size;
        int err;
+       const char *node;
+
+       node = vec[XS_WATCH_PATH];
 
        info = container_of(watch, struct blkfront_info, watch);
        node += strlen(watch->node);
@@ -472,8 +474,6 @@
        info->connected = BLKIF_STATE_CONNECTED;
        xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
 
-       blkif_state = BLKIF_STATE_CONNECTED;
-
        xenbus_dev_ok(info->xbdev);
 
        /* Kick pending requests. */
@@ -485,8 +485,11 @@
 static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
 {
        blkif_sring_t *sring;
-       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
        int err;
+       evtchn_op_t op = {
+               .cmd = EVTCHNOP_alloc_unbound,
+               .u.alloc_unbound.dom = DOMID_SELF,
+               .u.alloc_unbound.remote_dom = info->backend_id };
 
        info->ring_ref = GRANT_INVALID_REF;
 
@@ -508,7 +511,6 @@
        }
        info->ring_ref = err;
 
-       op.u.alloc_unbound.dom = info->backend_id;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                gnttab_end_foreign_access(info->ring_ref, 0);
@@ -518,7 +520,9 @@
                xenbus_dev_error(dev, err, "allocating event channel");
                return err;
        }
+
        blkif_connect(info, op.u.alloc_unbound.port);
+
        return 0;
 }
 
@@ -652,8 +656,17 @@
                return err;
        }
 
-       /* Call once in case entries already there. */
-       watch_for_status(&info->watch, info->watch.node);
+       {
+               unsigned int len = max(XS_WATCH_PATH, XS_WATCH_TOKEN) + 1;
+               const char *vec[len];
+
+               vec[XS_WATCH_PATH] = info->watch.node;
+               vec[XS_WATCH_TOKEN] = NULL;
+
+               /* Call once in case entries already there. */
+               watch_for_status(&info->watch, vec, len);
+       }
+
        return 0;
 }
 
@@ -712,29 +725,7 @@
 
 static void __init init_blk_xenbus(void)
 {
-       xenbus_register_device(&blkfront);
-}
-
-static int wait_for_blkif(void)
-{
-       int err = 0;
-       int i;
-
-       /*
-        * We should figure out how many and which devices we need to
-        * proceed and only wait for those.  For now, continue once the
-        * first device is around.
-        */
-       for (i = 0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
-       }
-
-       if (blkif_state != BLKIF_STATE_CONNECTED) {
-               WPRINTK("Timeout connecting to device!\n");
-               err = -ENOSYS;
-       }
-       return err;
+       xenbus_register_driver(&blkfront);
 }
 
 static int __init xlblk_init(void)
@@ -746,8 +737,6 @@
        IPRINTK("Initialising virtual block device driver\n");
 
        init_blk_xenbus();
-
-       wait_for_blkif();
 
        return 0;
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Sat Oct  8 20:28:24 2005
@@ -238,6 +238,7 @@
        gd->first_minor = minor;
        gd->fops = &xlvbd_block_fops;
        gd->private_data = info;
+       gd->driverfs_dev = &(info->xbdev->dev);
        set_capacity(gd, capacity);
 
        if (xlvbd_init_blk_queue(gd, sector_size)) {
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Sat Oct  8 
20:28:24 2005
@@ -68,8 +68,11 @@
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
        blkif_sring_t *sring;
-       evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
+       evtchn_op_t op = {
+               .cmd = EVTCHNOP_bind_interdomain,
+               .u.bind_interdomain.remote_dom  = blkif->domid,
+               .u.bind_interdomain.remote_port = evtchn };
 
        if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
@@ -80,10 +83,6 @@
                return err;
        }
 
-       op.u.bind_interdomain.dom1 = DOMID_SELF;
-       op.u.bind_interdomain.dom2 = blkif->domid;
-       op.u.bind_interdomain.port1 = 0;
-       op.u.bind_interdomain.port2 = evtchn;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                unmap_frontend_page(blkif);
@@ -91,7 +90,7 @@
                return err;
        }
 
-       blkif->evtchn = op.u.bind_interdomain.port1;
+       blkif->evtchn = op.u.bind_interdomain.local_port;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        SHARED_RING_INIT(sring);
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Sat Oct  8 20:28:24 2005
@@ -59,7 +59,8 @@
 }
 
 /* Front end tells us frame. */
-static void frontend_changed(struct xenbus_watch *watch, const char *node)
+static void frontend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
 {
        unsigned long ring_ref;
        unsigned int evtchn;
@@ -68,7 +69,7 @@
                = container_of(watch, struct backend_info, watch);
 
        /* If other end is gone, delete ourself. */
-       if (node && !xenbus_exists(be->frontpath, "")) {
+       if (vec && !xenbus_exists(be->frontpath, "")) {
                xenbus_rm(be->dev->nodename, "");
                device_unregister(&be->dev->dev);
                return;
@@ -106,7 +107,8 @@
    We provide event channel and device details to front end.
    Frontend supplies shared frame and event channel.
  */
-static void backend_changed(struct xenbus_watch *watch, const char *node)
+static void backend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
 {
        int err;
        char *p;
@@ -129,7 +131,7 @@
                }
 
                /* Pass in NULL node to skip exist test. */
-               frontend_changed(&be->watch, NULL);
+               frontend_changed(&be->watch, NULL, 0);
        }
 }
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Sat Oct  8 
20:28:24 2005
@@ -65,7 +65,8 @@
 int xencons_ring_send(const char *data, unsigned len)
 {
        int sent = __xencons_ring_send(outring(), data, len);
-       notify_remote_via_irq(xencons_irq);
+       /* Use evtchn: this is called early, before irq is set up. */
+       notify_remote_via_evtchn(xen_start_info->console_evtchn);
        return sent;
 }      
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Sat Oct  8 20:28:24 2005
@@ -44,9 +44,9 @@
 #include <linux/poll.h>
 #include <linux/irq.h>
 #include <linux/init.h>
-#define XEN_EVTCHN_MASK_OPS
+#include <linux/gfp.h>
 #include <asm-xen/evtchn.h>
-#include <linux/gfp.h>
+#include <asm-xen/linux-public/evtchn.h>
 
 struct per_user_data {
        /* Notification ring, accessed via /dev/xen/evtchn. */
@@ -78,7 +78,8 @@
                        u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port;
                        if (u->ring_cons == u->ring_prod++) {
                                wake_up_interruptible(&u->evtchn_wait);
-                               kill_fasync(&u->evtchn_async_queue, SIGIO, 
POLL_IN);
+                               kill_fasync(&u->evtchn_async_queue,
+                                           SIGIO, POLL_IN);
                        }
                } else {
                        u->ring_overflow = 1;
@@ -205,48 +206,143 @@
        return rc;
 }
 
+static void evtchn_bind_to_user(struct per_user_data *u, int port)
+{
+       spin_lock_irq(&port_user_lock);
+       BUG_ON(port_user[port] != NULL);
+       port_user[port] = u;
+       unmask_evtchn(port);
+       spin_unlock_irq(&port_user_lock);
+}
+
 static int evtchn_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
-       int rc = 0;
+       int rc;
        struct per_user_data *u = file->private_data;
-
-       spin_lock_irq(&port_user_lock);
+       evtchn_op_t op = { 0 };
+
+       switch (cmd) {
+       case IOCTL_EVTCHN_BIND_VIRQ: {
+               struct ioctl_evtchn_bind_virq bind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+                       break;
+
+               op.cmd = EVTCHNOP_bind_virq;
+               op.u.bind_virq.virq = bind.virq;
+               op.u.bind_virq.vcpu = 0;
+               rc = HYPERVISOR_event_channel_op(&op);
+               if (rc != 0)
+                       break;
+
+               rc = op.u.bind_virq.port;
+               evtchn_bind_to_user(u, rc);
+               break;
+       }
+
+       case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
+               struct ioctl_evtchn_bind_interdomain bind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+                       break;
+
+               op.cmd = EVTCHNOP_bind_interdomain;
+               op.u.bind_interdomain.remote_dom  = bind.remote_domain;
+               op.u.bind_interdomain.remote_port = bind.remote_port;
+               rc = HYPERVISOR_event_channel_op(&op);
+               if (rc != 0)
+                       break;
+
+               rc = op.u.bind_interdomain.local_port;
+               evtchn_bind_to_user(u, rc);
+               break;
+       }
+
+       case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
+               struct ioctl_evtchn_bind_unbound_port bind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+                       break;
+
+               op.cmd = EVTCHNOP_alloc_unbound;
+               op.u.alloc_unbound.dom        = DOMID_SELF;
+               op.u.alloc_unbound.remote_dom = bind.remote_domain;
+               rc = HYPERVISOR_event_channel_op(&op);
+               if (rc != 0)
+                       break;
+
+               rc = op.u.alloc_unbound.port;
+               evtchn_bind_to_user(u, rc);
+               break;
+       }
+
+       case IOCTL_EVTCHN_UNBIND: {
+               struct ioctl_evtchn_unbind unbind;
+
+               rc = -EFAULT;
+               if (copy_from_user(&unbind, (void *)arg, sizeof(unbind)))
+                       break;
+
+               rc = -EINVAL;
+               if (unbind.port >= NR_EVENT_CHANNELS)
+                       break;
+
+               spin_lock_irq(&port_user_lock);
     
-       switch (cmd) {
-       case EVTCHN_RESET:
-               /* Initialise the ring to empty. Clear errors. */
-               u->ring_cons = u->ring_prod = u->ring_overflow = 0;
-               break;
-
-       case EVTCHN_BIND:
-               if (arg >= NR_EVENT_CHANNELS) {
+               rc = -ENOTCONN;
+               if (port_user[unbind.port] != u) {
+                       spin_unlock_irq(&port_user_lock);
+                       break;
+               }
+
+               port_user[unbind.port] = NULL;
+               mask_evtchn(unbind.port);
+
+               spin_unlock_irq(&port_user_lock);
+
+               op.cmd = EVTCHNOP_close;
+               op.u.close.port = unbind.port;
+               BUG_ON(HYPERVISOR_event_channel_op(&op));
+
+               rc = 0;
+               break;
+       }
+
+       case IOCTL_EVTCHN_NOTIFY: {
+               struct ioctl_evtchn_notify notify;
+
+               rc = -EFAULT;
+               if (copy_from_user(&notify, (void *)arg, sizeof(notify)))
+                       break;
+
+               if (notify.port >= NR_EVENT_CHANNELS) {
                        rc = -EINVAL;
-               } else if (port_user[arg] != NULL) {
-                       rc = -EISCONN;
-               } else {
-                       port_user[arg] = u;
-                       unmask_evtchn(arg);
-               }
-               break;
-
-       case EVTCHN_UNBIND:
-               if (arg >= NR_EVENT_CHANNELS) {
-                       rc = -EINVAL;
-               } else if (port_user[arg] != u) {
+               } else if (port_user[notify.port] != u) {
                        rc = -ENOTCONN;
                } else {
-                       port_user[arg] = NULL;
-                       mask_evtchn(arg);
-               }
-               break;
+                       notify_remote_via_evtchn(notify.port);
+                       rc = 0;
+               }
+               break;
+       }
+
+       case IOCTL_EVTCHN_RESET: {
+               /* Initialise the ring to empty. Clear errors. */
+               spin_lock_irq(&port_user_lock);
+               u->ring_cons = u->ring_prod = u->ring_overflow = 0;
+               spin_unlock_irq(&port_user_lock);
+               rc = 0;
+               break;
+       }
 
        default:
                rc = -ENOSYS;
                break;
        }
-
-       spin_unlock_irq(&port_user_lock);   
 
        return rc;
 }
@@ -295,6 +391,7 @@
 {
        int i;
        struct per_user_data *u = filp->private_data;
+       evtchn_op_t op = { 0 };
 
        spin_lock_irq(&port_user_lock);
 
@@ -302,11 +399,15 @@
 
        for (i = 0; i < NR_EVENT_CHANNELS; i++)
        {
-               if (port_user[i] == u)
-               {
-                       port_user[i] = NULL;
-                       mask_evtchn(i);
-               }
+               if (port_user[i] != u)
+                       continue;
+
+               port_user[i] = NULL;
+               mask_evtchn(i);
+
+               op.cmd = EVTCHNOP_close;
+               op.u.close.port = i;
+               BUG_ON(HYPERVISOR_event_channel_op(&op));
        }
 
        spin_unlock_irq(&port_user_lock);
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Sat Oct  8 
20:28:24 2005
@@ -177,8 +177,15 @@
 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
              unsigned long rx_ring_ref, unsigned int evtchn)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
+       evtchn_op_t op = {
+               .cmd = EVTCHNOP_bind_interdomain,
+               .u.bind_interdomain.remote_dom = netif->domid,
+               .u.bind_interdomain.remote_port = evtchn };
+
+       /* Already connected through? */
+       if (netif->irq)
+               return 0;
 
        netif->comms_area = alloc_vm_area(2*PAGE_SIZE);
        if (netif->comms_area == NULL)
@@ -190,10 +197,6 @@
                return err;
        }
 
-       op.u.bind_interdomain.dom1 = DOMID_SELF;
-       op.u.bind_interdomain.dom2 = netif->domid;
-       op.u.bind_interdomain.port1 = 0;
-       op.u.bind_interdomain.port2 = evtchn;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                unmap_frontend_pages(netif);
@@ -201,7 +204,7 @@
                return err;
        }
 
-       netif->evtchn = op.u.bind_interdomain.port1;
+       netif->evtchn = op.u.bind_interdomain.local_port;
 
        netif->irq = bind_evtchn_to_irqhandler(
                netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
@@ -228,13 +231,12 @@
 {
        netif_t *netif = (netif_t *)arg;
 
-       /*
-        * This can't be done in netif_disconnect() because at that point
-        * there may be outstanding requests in the network stack whose
-        * asynchronous responses must still be notified to the remote driver.
-        */
-       if (netif->irq)
-               unbind_evtchn_from_irqhandler(netif->irq, netif);
+       /* Already disconnected? */
+       if (!netif->irq)
+               return;
+
+       unbind_evtchn_from_irqhandler(netif->irq, netif);
+       netif->irq = 0;
 
        unregister_netdev(netif->dev);
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Sat Oct  8 
20:28:24 2005
@@ -553,9 +553,9 @@
 
                /* No crossing a page as the payload mustn't fragment. */
                if (unlikely((txreq.offset + txreq.size) >= PAGE_SIZE)) {
-                       DPRINTK("txreq.addr: %lx, size: %u, end: %lu\n", 
-                               txreq.addr, txreq.size, 
-                               (txreq.addr &~PAGE_MASK) + txreq.size);
+                       DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 
+                               txreq.offset, txreq.size, 
+                               (txreq.offset &~PAGE_MASK) + txreq.size);
                        make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
                        netif_put(netif);
                        continue;
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sat Oct  8 20:28:24 2005
@@ -57,7 +57,8 @@
 }
 
 /* Front end tells us frame. */
-static void frontend_changed(struct xenbus_watch *watch, const char *node)
+static void frontend_changed(struct xenbus_watch *watch, 
+                            const char **vec, unsigned int len)
 {
        unsigned long tx_ring_ref, rx_ring_ref;
        unsigned int evtchn;
@@ -68,7 +69,7 @@
        int i;
 
        /* If other end is gone, delete ourself. */
-       if (node && !xenbus_exists(be->frontpath, "")) {
+       if (vec && !xenbus_exists(be->frontpath, "")) {
                xenbus_rm(be->dev->nodename, "");
                device_unregister(&be->dev->dev);
                return;
@@ -126,7 +127,8 @@
    We provide event channel and device details to front end.
    Frontend supplies shared frame and event channel.
  */
-static void backend_changed(struct xenbus_watch *watch, const char *node)
+static void backend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
 {
        int err;
        long int handle;
@@ -163,7 +165,7 @@
                kobject_hotplug(&dev->dev.kobj, KOBJ_ONLINE);
 
                /* Pass in NULL node to skip exist test. */
-               frontend_changed(&be->watch, NULL);
+               frontend_changed(&be->watch, NULL, 0);
        }
 }
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Sat Oct  8 
20:28:24 2005
@@ -87,11 +87,6 @@
 #define TX_TEST_IDX req_cons  /* conservative: not seen all our requests? */
 #endif
 
-
-#define NETIF_STATE_DISCONNECTED 0
-#define NETIF_STATE_CONNECTED    1
-
-static unsigned int netif_state = NETIF_STATE_DISCONNECTED;
 
 static void network_tx_buf_gc(struct net_device *dev);
 static void network_alloc_rx_buffers(struct net_device *dev);
@@ -858,7 +853,7 @@
        np->user_state    = UST_CLOSED;
        np->handle        = handle;
        np->xbdev         = dev;
-    
+
        spin_lock_init(&np->tx_lock);
        spin_lock_init(&np->rx_lock);
 
@@ -902,7 +897,9 @@
        netdev->features        = NETIF_F_IP_CSUM;
 
        SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
-
+       SET_MODULE_OWNER(netdev);
+       SET_NETDEV_DEV(netdev, &dev->dev);
+    
        if ((err = register_netdev(netdev)) != 0) {
                printk(KERN_WARNING "%s> register_netdev err=%d\n",
                       __FUNCTION__, err);
@@ -966,14 +963,18 @@
        { "" }
 };
 
-static void watch_for_status(struct xenbus_watch *watch, const char *node)
+static void watch_for_status(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
 {
 }
 
 static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
        int err;
+       evtchn_op_t op = {
+               .cmd = EVTCHNOP_alloc_unbound,
+               .u.alloc_unbound.dom = DOMID_SELF,
+               .u.alloc_unbound.remote_dom = info->backend_id };
 
        info->tx_ring_ref = GRANT_INVALID_REF;
        info->rx_ring_ref = GRANT_INVALID_REF;
@@ -1010,13 +1011,14 @@
        }
        info->rx_ring_ref = err;
 
-       op.u.alloc_unbound.dom = info->backend_id;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                xenbus_dev_error(dev, err, "allocating event channel");
                goto out;
        }
+
        connect_device(info, op.u.alloc_unbound.port);
+
        return 0;
 
  out:
@@ -1172,8 +1174,6 @@
 
        info->backend = backend;
 
-       netif_state = NETIF_STATE_CONNECTED;
-
        return 0;
 
  abort_transaction:
@@ -1272,30 +1272,7 @@
 
 static void __init init_net_xenbus(void)
 {
-       xenbus_register_device(&netfront);
-}
-
-static int wait_for_netif(void)
-{
-       int err = 0;
-       int i;
-
-       /*
-        * We should figure out how many and which devices we need to
-        * proceed and only wait for those.  For now, continue once the
-        * first device is around.
-        */
-       for ( i=0; netif_state != NETIF_STATE_CONNECTED && (i < 10*HZ); i++ )
-       {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
-       }
-
-       if (netif_state != NETIF_STATE_CONNECTED) {
-               WPRINTK("Timeout connecting to device!\n");
-               err = -ENOSYS;
-       }
-       return err;
+       xenbus_register_driver(&netfront);
 }
 
 static int __init netif_init(void)
@@ -1313,8 +1290,6 @@
        (void)register_inetaddr_notifier(&notifier_inetdev);
 
        init_net_xenbus();
-
-       wait_for_netif();
 
        return err;
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Sat Oct  8 
20:28:24 2005
@@ -67,7 +67,7 @@
                                tpmif_get(tpmif);
                                return tpmif;
                        } else {
-                               return NULL;
+                               return ERR_PTR(-EEXIST);
                        }
                }
        }
@@ -117,8 +117,11 @@
 int
 tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
 {
-       evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain };
        int err;
+       evtchn_op_t op = {
+               .cmd = EVTCHNOP_bind_interdomain,
+               .u.bind_interdomain.remote_dom = tpmif->domid,
+               .u.bind_interdomain.remote_port = evtchn };
 
        if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
@@ -129,10 +132,6 @@
                return err;
        }
 
-       op.u.bind_interdomain.dom1 = DOMID_SELF;
-       op.u.bind_interdomain.dom2 = tpmif->domid;
-       op.u.bind_interdomain.port1 = 0;
-       op.u.bind_interdomain.port2 = evtchn;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                unmap_frontend_page(tpmif);
@@ -140,7 +139,7 @@
                return err;
        }
 
-       tpmif->evtchn = op.u.bind_interdomain.port1;
+       tpmif->evtchn = op.u.bind_interdomain.local_port;
 
        tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Sat Oct  8 
20:28:24 2005
@@ -22,6 +22,7 @@
 #include <asm-xen/xen-public/grant_table.h>
 
 
+/* local data structures */
 struct data_exchange {
        struct list_head pending_pak;
        struct list_head current_pak;
@@ -45,7 +46,7 @@
 
 enum {
        PACKET_FLAG_DISCARD_RESPONSE = 1,
-       PACKET_FLAG_SEND_CONTROLMESSAGE = 2,
+       PACKET_FLAG_CHECK_RESPONSESTATUS = 2,
 };
 
 static struct data_exchange dataex;
@@ -66,9 +67,26 @@
 
 #define MAX_PENDING_REQS TPMIF_TX_RING_SIZE
 
-static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
-
 #define MIN(x,y)  (x) < (y) ? (x) : (y)
+
+
+/***************************************************************
+ Buffer copying
+***************************************************************/
+static inline int
+copy_from_buffer(void *to,
+                 const void *from,
+                 unsigned long size,
+                 int userbuffer)
+{
+       if (userbuffer) {
+               if (copy_from_user(to, from, size))
+                       return -EFAULT;
+       } else {
+               memcpy(to, from, size);
+       }
+       return 0;
+}
 
 /***************************************************************
  Packet-related functions
@@ -188,15 +206,25 @@
        DPRINTK("Supposed to send %d bytes to front-end!\n",
                size);
 
-       if (0 != (pak->flags & PACKET_FLAG_SEND_CONTROLMESSAGE)) {
+       if (0 != (pak->flags & PACKET_FLAG_CHECK_RESPONSESTATUS)) {
 #ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
                u32 res;
-               memcpy(&res, &data[2+4], sizeof(res));
+               if (copy_from_buffer(&res,
+                                    &data[2+4],
+                                    sizeof(res),
+                                    userbuffer)) {
+                       return -EFAULT;
+               }
+
                if (res != 0) {
                        /*
-                        * Will close down this device and have the
+                        * Close down this device. Should have the
                         * FE notified about closure.
                         */
+                       if (!pak->tpmif) {
+                               return -EFAULT;
+                       }
+                       pak->tpmif->status = DISCONNECTING;
                }
 #endif
        }
@@ -226,16 +254,15 @@
        int rc = 0;
        unsigned int i = 0;
        unsigned int offset = 0;
-       multicall_entry_t *mcl;
-
-       if (tpmif == NULL)
+
+       if (tpmif == NULL) {
                return -EFAULT;
-
-       if (tpmif->status != CONNECTED) {
+        }
+
+       if (tpmif->status == DISCONNECTED) {
                return size;
        }
 
-       mcl = tx_mcl;
        while (offset < size && i < TPMIF_TX_RING_SIZE) {
                unsigned int tocopy;
                struct gnttab_map_grant_ref map_op;
@@ -272,22 +299,15 @@
                                        PAGE_SHIFT] =
                        FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
 
-               tocopy = size - offset;
-               if (tocopy > PAGE_SIZE) {
-                       tocopy = PAGE_SIZE;
-               }
-               if (userbuffer) {
-                       if (copy_from_user((void *)(MMAP_VADDR(tpmif,i) |
-                                                  (tx->addr & ~PAGE_MASK)),
-                                          (void __user *)&data[offset],
-                                          tocopy)) {
-                               tpmif_put(tpmif);
-                               return -EFAULT;
-                       }
-               } else {
-                       memcpy((void *)(MMAP_VADDR(tpmif,i) |
-                                       (tx->addr & ~PAGE_MASK)),
-                              &data[offset], tocopy);
+               tocopy = MIN(size - offset, PAGE_SIZE);
+
+               if (copy_from_buffer((void *)(MMAP_VADDR(tpmif,i)|
+                                    (tx->addr & ~PAGE_MASK)),
+                                    &data[offset],
+                                    tocopy,
+                                    userbuffer)) {
+                       tpmif_put(tpmif);
+                       return -EFAULT;
                }
                tx->size = tocopy;
 
@@ -306,8 +326,8 @@
        }
 
        rc = offset;
-       DPRINTK("Notifying frontend via event channel %d\n",
-               tpmif->evtchn);
+       DPRINTK("Notifying frontend via irq %d\n",
+               tpmif->irq);
        notify_remote_via_irq(tpmif->irq);
 
        return rc;
@@ -705,9 +725,13 @@
 int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domid, u32 instance)
 {
        int rc = 0;
-       struct packet *pak = packet_alloc(tpmif, sizeof(create_cmd), 
create_cmd[0],
-           PACKET_FLAG_DISCARD_RESPONSE|
-           PACKET_FLAG_SEND_CONTROLMESSAGE);
+       struct packet *pak;
+
+       pak = packet_alloc(tpmif,
+                          sizeof(create_cmd),
+                          create_cmd[0],
+                          PACKET_FLAG_DISCARD_RESPONSE|
+                          PACKET_FLAG_CHECK_RESPONSESTATUS);
        if (pak) {
                u8 buf[sizeof(create_cmd)];
                u32 domid_no = htonl((u32)domid);
@@ -742,8 +766,7 @@
        pak = packet_alloc(NULL,
                           sizeof(create_cmd),
                           create_cmd[0],
-                          PACKET_FLAG_DISCARD_RESPONSE|
-                          PACKET_FLAG_SEND_CONTROLMESSAGE);
+                          PACKET_FLAG_DISCARD_RESPONSE);
        if (pak) {
                u8 buf[sizeof(destroy_cmd)];
                u32 instid_no = htonl(instid);
@@ -896,7 +919,8 @@
         */
        if (size < 10 ||
            be32_to_cpu(*native_size) != size ||
-           0 == dataex.has_opener) {
+           0 == dataex.has_opener ||
+           tpmif->status != CONNECTED) {
                rc = -EINVAL;
                goto failexit;
        } else {
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Sat Oct  8 20:28:24 2005
@@ -59,7 +59,8 @@
 }
 
 
-static void frontend_changed(struct xenbus_watch *watch, const char *node)
+static void frontend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
 {
        unsigned long ringref;
        unsigned int evtchn;
@@ -69,7 +70,7 @@
                = container_of(watch, struct backend_info, watch);
 
        /* If other end is gone, delete ourself. */
-       if (node && !xenbus_exists(be->frontpath, "")) {
+       if (vec && !xenbus_exists(be->frontpath, "")) {
                xenbus_rm(be->dev->nodename, "");
                device_unregister(&be->dev->dev);
                return;
@@ -142,7 +143,8 @@
 }
 
 
-static void backend_changed(struct xenbus_watch *watch, const char *node)
+static void backend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
 {
        int err;
        long int instance;
@@ -166,6 +168,9 @@
        be->instance = instance;
 
        if (be->tpmif == NULL) {
+               unsigned int len = max(XS_WATCH_PATH, XS_WATCH_TOKEN) + 1;
+               const char *vec[len];
+
                be->tpmif = tpmif_find(be->frontend_id,
                                       instance);
                if (IS_ERR(be->tpmif)) {
@@ -175,8 +180,11 @@
                        return;
                }
 
+               vec[XS_WATCH_PATH] = be->frontpath;
+               vec[XS_WATCH_TOKEN] = NULL;
+
                /* Pass in NULL node to skip exist test. */
-               frontend_changed(&be->watch, be->frontpath);
+               frontend_changed(&be->watch, vec, len);
        }
 }
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Sat Oct  8 
20:28:24 2005
@@ -211,12 +211,14 @@
  XENBUS support code
 **************************************************************/
 
-static void watch_for_status(struct xenbus_watch *watch, const char *node)
+static void watch_for_status(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
 {
        struct tpmfront_info *info;
        int err;
        unsigned long ready;
        struct tpm_private *tp = &my_private;
+       const char *node = vec[XS_WATCH_PATH];
 
        info = container_of(watch, struct tpmfront_info, watch);
        node += strlen(watch->node);
@@ -244,9 +246,11 @@
 {
        tpmif_tx_interface_t *sring;
        struct tpm_private *tp = &my_private;
-
-       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
        int err;
+       evtchn_op_t op = {
+               .cmd = EVTCHNOP_alloc_unbound,
+               .u.alloc_unbound.dom = DOMID_SELF,
+               .u.alloc_unbound.remote_dom = backend_id } ;
 
        sring = (void *)__get_free_page(GFP_KERNEL);
        if (!sring) {
@@ -269,7 +273,6 @@
        }
        info->ring_ref = err;
 
-       op.u.alloc_unbound.dom = backend_id;
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                gnttab_end_foreign_access(info->ring_ref, 0);
@@ -278,7 +281,9 @@
                xenbus_dev_error(dev, err, "allocating event channel");
                return err;
        }
+
        tpmif_connect(op.u.alloc_unbound.port, backend_id);
+
        return 0;
 }
 
@@ -293,9 +298,9 @@
                tp->tx = NULL;
        }
 
-       if (tpm->irq)
+       if (tp->irq)
                unbind_evtchn_from_irqhandler(tp->irq, NULL);
-       tp->evtchn = tpm->irq = 0;
+       tp->evtchn = tp->irq = 0;
 }
 
 
@@ -439,26 +444,32 @@
        return 0;
 }
 
-static int tpmfront_suspend(struct xenbus_device *dev)
+static int
+tpmfront_suspend(struct xenbus_device *dev)
 {
        struct tpmfront_info *info = dev->data;
        struct tpm_private *tp = &my_private;
-
-       /* lock so no app can send */
+       u32 ctr = 0;
+
+       /* lock, so no app can send */
        down(&suspend_lock);
 
-       while (atomic_read(&tp->tx_busy)) {
-               printk("---- TPMIF: Outstanding request.\n");
-#if 0
+       while (atomic_read(&tp->tx_busy) && ctr <= 25) {
+               if ((ctr % 10) == 0)
+                       printk("INFO: Waiting for outstanding request.\n");
                /*
-                * Would like to wait until the outstanding request
-                * has come back, but this does not work properly, yet.
+                * Wait for a request to be responded to.
                 */
-               interruptible_sleep_on_timeout(&tp->wait_q,
-                                              100);
-#else
-               break;
-#endif
+               interruptible_sleep_on_timeout(&tp->wait_q, 100);
+               ctr++;
+       }
+
+       if (atomic_read(&tp->tx_busy)) {
+               /*
+                * A temporary work-around.
+                */
+               printk("WARNING: Resetting busy flag.");
+               atomic_set(&tp->tx_busy, 0);
        }
 
        unregister_xenbus_watch(&info->watch);
@@ -466,44 +477,34 @@
        kfree(info->backend);
        info->backend = NULL;
 
-       destroy_tpmring(info, tp);
-
        return 0;
 }
 
-static int tpmif_recover(void)
-{
-       return 0;
-}
-
-static int tpmfront_resume(struct xenbus_device *dev)
+static int
+tpmfront_resume(struct xenbus_device *dev)
 {
        struct tpmfront_info *info = dev->data;
-       int err;
-
-       err = talk_to_backend(dev, info);
-       if (!err) {
-               tpmif_recover();
-       }
-
-       /* unlock so apps can resume */
+       int err = talk_to_backend(dev, info);
+
+       /* unlock, so apps can resume sending */
        up(&suspend_lock);
 
        return err;
 }
 
-static void tpmif_connect(u16 evtchn, domid_t domid)
+static void
+tpmif_connect(u16 evtchn, domid_t domid)
 {
        int err = 0;
        struct tpm_private *tp = &my_private;
 
        tp->evtchn = evtchn;
-       tp->backend_id  = domid;
-
-       err = bind_evtchn_to_irqhandler(
-               tp->evtchn,
-               tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
-       if ( err <= 0 ) {
+       tp->backend_id = domid;
+
+       err = bind_evtchn_to_irqhandler(tp->evtchn,
+                                       tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
+                                       tp);
+       if (err <= 0) {
                WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
                return;
        }
@@ -528,7 +529,7 @@
 
 static void __init init_tpm_xenbus(void)
 {
-       xenbus_register_device(&tpmfront);
+       xenbus_register_driver(&tpmfront);
 }
 
 
@@ -638,7 +639,7 @@
 
                if (NULL == txb) {
                        DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i);
-                       DPRINTK("Not transmittin anything!\n");
+                       DPRINTK("Not transmitting anything!\n");
                        spin_unlock_irq(&tp->tx_lock);
                        return -EFAULT;
                }
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Sat Oct  8 
20:28:24 2005
@@ -147,7 +147,7 @@
                data += avail;
                len -= avail;
                update_output_chunk(out, avail);
-               notify_remote_via_irq(xenbus_irq);
+               notify_remote_via_evtchn(xen_start_info->store_evtchn);
        } while (len != 0);
 
        return 0;
@@ -192,7 +192,7 @@
                pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
                /* If it was full, tell them we've taken some. */
                if (was_full)
-                       notify_remote_via_irq(xenbus_irq);
+                       notify_remote_via_evtchn(xen_start_info->store_evtchn);
        }
 
        /* If we left something, wake watch thread to deal with it. */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Sat Oct  8 
20:28:24 2005
@@ -44,7 +44,6 @@
 #include <asm-xen/xenbus.h>
 #include <asm-xen/xen_proc.h>
 #include <asm/hypervisor.h>
-#include <asm-xen/linux-public/xenstored.h>
 
 struct xenbus_dev_data {
        /* Are there bytes left to be read in this message? */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Sat Oct  8 
20:28:24 2005
@@ -184,7 +184,7 @@
        return 0;
 }
 
-static int xenbus_probe_backend(const char *type, const char *uuid);
+static int xenbus_probe_backend(const char *type, const char *domid);
 static struct xen_bus_type xenbus_backend = {
        .root = "backend",
        .levels = 3,            /* backend/type/<frontend>/<id> */
@@ -226,8 +226,8 @@
        return drv->remove(dev);
 }
 
-static int xenbus_register_driver(struct xenbus_driver *drv,
-                                 struct xen_bus_type *bus)
+static int xenbus_register_driver_common(struct xenbus_driver *drv,
+                                        struct xen_bus_type *bus)
 {
        int err;
 
@@ -243,15 +243,15 @@
        return err;
 }
 
-int xenbus_register_device(struct xenbus_driver *drv)
-{
-       return xenbus_register_driver(drv, &xenbus_frontend);
-}
-EXPORT_SYMBOL(xenbus_register_device);
+int xenbus_register_driver(struct xenbus_driver *drv)
+{
+       return xenbus_register_driver_common(drv, &xenbus_frontend);
+}
+EXPORT_SYMBOL(xenbus_register_driver);
 
 int xenbus_register_backend(struct xenbus_driver *drv)
 {
-       return xenbus_register_driver(drv, &xenbus_backend);
+       return xenbus_register_driver_common(drv, &xenbus_backend);
 }
 
 void xenbus_unregister_driver(struct xenbus_driver *drv)
@@ -260,6 +260,7 @@
        driver_unregister(&drv->driver);
        up(&xenbus_lock);
 }
+EXPORT_SYMBOL(xenbus_unregister_driver);
 
 struct xb_find_info
 {
@@ -347,6 +348,18 @@
        return p;
 }
 
+static ssize_t xendev_show_nodename(struct device *dev, char *buf)
+{
+       return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
+}
+DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
+
+static ssize_t xendev_show_devtype(struct device *dev, char *buf)
+{
+       return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
+}
+DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
+
 static int xenbus_probe_node(struct xen_bus_type *bus,
                             const char *type,
                             const char *nodename)
@@ -383,6 +396,9 @@
                printk("XENBUS: Registering %s device %s: error %i\n",
                       bus->bus.name, xendev->dev.bus_id, err);
                kfree(xendev);
+       } else {
+               device_create_file(&xendev->dev, &dev_attr_nodename);
+               device_create_file(&xendev->dev, &dev_attr_devtype);
        }
        return err;
 }
@@ -419,15 +435,15 @@
        return err;
 }
 
-/* backend/<typename>/<frontend-uuid> */
-static int xenbus_probe_backend(const char *type, const char *uuid)
+/* backend/<typename>/<frontend-domid> */
+static int xenbus_probe_backend(const char *type, const char *domid)
 {
        char *nodename;
        int err = 0;
        char **dir;
        unsigned int i, dir_n = 0;
 
-       nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, uuid);
+       nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
        if (!nodename)
                return -ENOMEM;
 
@@ -546,14 +562,16 @@
        kfree(root);
 }
 
-static void frontend_changed(struct xenbus_watch *watch, const char *node)
-{
-       dev_changed(node, &xenbus_frontend);
-}
-
-static void backend_changed(struct xenbus_watch *watch, const char *node)
-{
-       dev_changed(node, &xenbus_backend);
+static void frontend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
+{
+       dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
+}
+
+static void backend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
+{
+       dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
 }
 
 /* We watch for devices appearing and vanishing. */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Oct  8 
20:28:24 2005
@@ -38,7 +38,6 @@
 #include <linux/fcntl.h>
 #include <linux/kthread.h>
 #include <asm-xen/xenbus.h>
-#include <asm-xen/linux-public/xenstored.h>
 #include "xenbus_comms.h"
 
 #define streq(a, b) (strcmp((a), (b)) == 0)
@@ -200,14 +199,9 @@
        return buffer;
 }
 
-char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
-{
-       char *strings, *p, **ret;
-       unsigned int len;
-
-       strings = xs_single(XS_DIRECTORY, join(dir, node), &len);
-       if (IS_ERR(strings))
-               return (char **)strings;
+static char **split(char *strings, unsigned int len, unsigned int *num)
+{
+       char *p, **ret;
 
        /* Count the strings. */
        *num = count_strings(strings, len);
@@ -224,7 +218,20 @@
        strings = (char *)&ret[*num];
        for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
                ret[(*num)++] = p;
+
        return ret;
+}
+
+char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
+{
+       char *strings;
+       unsigned int len;
+
+       strings = xs_single(XS_DIRECTORY, join(dir, node), &len);
+       if (IS_ERR(strings))
+               return (char **)strings;
+
+       return split(strings, len, num);
 }
 EXPORT_SYMBOL(xenbus_directory);
 
@@ -425,18 +432,19 @@
        return xs_error(xs_talkv(XS_WATCH, iov, ARRAY_SIZE(iov), NULL));
 }
 
-static char *xs_read_watch(char **token)
+static char **xs_read_watch(unsigned int *num)
 {
        enum xsd_sockmsg_type type;
-       char *ret;
-
-       ret = read_reply(&type, NULL);
-       if (IS_ERR(ret))
-               return ret;
+       char *strings;
+       unsigned int len;
+
+       strings = read_reply(&type, &len);
+       if (IS_ERR(strings))
+               return (char **)strings;
 
        BUG_ON(type != XS_WATCH_EVENT);
-       *token = ret + strlen(ret) + 1;
-       return ret;
+
+       return split(strings, len, num);
 }
 
 static int xs_acknowledge_watch(const char *token)
@@ -519,8 +527,8 @@
 static int watch_thread(void *unused)
 {
        for (;;) {
-               char *token;
-               char *node = NULL;
+               char **vec = NULL;
+               unsigned int num;
 
                wait_event(xb_waitq, xs_input_avail());
 
@@ -530,23 +538,23 @@
                 */
                down(&xenbus_lock);
                if (xs_input_avail())
-                       node = xs_read_watch(&token);
-
-               if (node && !IS_ERR(node)) {
+                       vec = xs_read_watch(&num);
+
+               if (vec && !IS_ERR(vec)) {
                        struct xenbus_watch *w;
                        int err;
 
-                       err = xs_acknowledge_watch(token);
+                       err = xs_acknowledge_watch(vec[XS_WATCH_TOKEN]);
                        if (err)
                                printk(KERN_WARNING "XENBUS ack %s fail %i\n",
-                                      node, err);
-                       w = find_watch(token);
+                                      vec[XS_WATCH_TOKEN], err);
+                       w = find_watch(vec[XS_WATCH_TOKEN]);
                        BUG_ON(!w);
-                       w->callback(w, node);
-                       kfree(node);
-               } else if (node)
+                       w->callback(w, (const char **)vec, num);
+                       kfree(vec);
+               } else if (vec)
                        printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
-                              PTR_ERR(node));
+                              PTR_ERR(vec));
                up(&xenbus_lock);
        }
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Sat Oct  8 
20:28:24 2005
@@ -31,6 +31,7 @@
 #define __HYPERCALL_H__
 
 #include <asm-xen/xen-public/xen.h>
+#include <asm-xen/xen-public/sched.h>
 
 #define _hypercall0(type, name)                        \
 ({                                             \
@@ -160,41 +161,10 @@
 }
 
 static inline int
-HYPERVISOR_yield(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_yield, 0);
-}
-
-static inline int
-HYPERVISOR_block(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_block, 0);
-}
-
-static inline int
-HYPERVISOR_shutdown(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_shutdown |
-                          (SHUTDOWN_poweroff << SCHEDOP_reasonshift), 0);
-}
-
-static inline int
-HYPERVISOR_reboot(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_shutdown |
-                          (SHUTDOWN_reboot << SCHEDOP_reasonshift), 0);
-}
-
-static inline int
-HYPERVISOR_crash(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_shutdown |
-                          (SHUTDOWN_crash << SCHEDOP_reasonshift), 0);
+HYPERVISOR_sched_op(
+       int cmd, unsigned long arg)
+{
+       return _hypercall2(int, sched_op, cmd, arg);
 }
 
 static inline long
@@ -316,63 +286,18 @@
 }
 
 static inline int
-HYPERVISOR_boot_vcpu(
-       unsigned long vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, boot_vcpu, vcpu, ctxt);
-}
-
-static inline int
-HYPERVISOR_vcpu_up(
-       int vcpu)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
-                          (vcpu << SCHEDOP_vcpushift), 0);
-}
-
-static inline int
-HYPERVISOR_vcpu_pickle(
-       int vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
-                          (vcpu << SCHEDOP_vcpushift), ctxt);
+HYPERVISOR_vcpu_op(
+       int cmd, int vcpuid, void *extra_args)
+{
+       return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
 }
 
 static inline int
 HYPERVISOR_suspend(
        unsigned long srec)
 {
-       int ret;
-       unsigned long ign1, ign2;
-
-       /* On suspend, control software expects a suspend record in %esi. */
-       __asm__ __volatile__ (
-               TRAP_INSTR
-               : "=a" (ret), "=b" (ign1), "=S" (ign2)
-               : "0" (__HYPERVISOR_sched_op),
-               "1" (SCHEDOP_shutdown | (SHUTDOWN_suspend <<
-                                        SCHEDOP_reasonshift)), 
-               "2" (srec) : "memory", "ecx");
-
-       return ret;
-}
-
-static inline int
-HYPERVISOR_vcpu_down(
-       int vcpu)
-{
-       int ret;
-       unsigned long ign1;
-       /* Yes, I really do want to clobber edx here: when we resume a
-          vcpu after unpickling a multi-processor domain, it returns
-          here, but clobbers all of the call clobbered registers. */
-       __asm__ __volatile__ (
-               TRAP_INSTR
-               : "=a" (ret), "=b" (ign1)
-               : "0" (__HYPERVISOR_sched_op),
-               "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
-               : "memory", "ecx", "edx" );
-       return ret;
+       return _hypercall3(int, sched_op, SCHEDOP_shutdown,
+                          SHUTDOWN_suspend, srec);
 }
 
 #endif /* __HYPERCALL_H__ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h   Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h   Sat Oct  8 
20:28:24 2005
@@ -412,17 +412,6 @@
        ptep_set_access_flags(__vma, __address, __ptep, __entry, 1);    \
 } while (0)
 
-#define __HAVE_ARCH_PTEP_ESTABLISH_NEW
-#define ptep_establish_new(__vma, __address, __ptep, __entry)          \
-do {                                                                   \
-       if (likely((__vma)->vm_mm == current->mm)) {                    \
-               BUG_ON(HYPERVISOR_update_va_mapping((__address),        \
-                                            __entry, 0));              \
-       } else {                                                        \
-               xen_l1_entry_update((__ptep), (__entry));       \
-       }                                                               \
-} while (0)
-
 #ifndef CONFIG_XEN_SHADOW_MODE
 void make_lowmem_page_readonly(void *va);
 void make_lowmem_page_writable(void *va);
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h Sat Oct  8 
17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h Sat Oct  8 
20:28:24 2005
@@ -29,7 +29,9 @@
 
 #ifndef __HYPERCALL_H__
 #define __HYPERCALL_H__
+
 #include <asm-xen/xen-public/xen.h>
+#include <asm-xen/xen-public/sched.h>
 
 /* FIXME: temp place to hold these page related macros */
 #include <asm/page.h>
@@ -184,77 +186,9 @@
 }
 
 static inline int
-HYPERVISOR_yield(
-    void)
-{
-#if 0
-    int ret;
-    unsigned long ign;
-
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign)
-       : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
-       : "memory" );
-
-    return ret;
-#endif
-    return 1;
-}
-
-static inline int
-HYPERVISOR_block(
-    void)
-{
-#if 0
-    int ret;
-    unsigned long ign1;
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1)
-       : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
-       : "memory" );
-
-    return ret;
-#endif
-    return 1;
-}
-
-static inline int
-HYPERVISOR_shutdown(
-    void)
-{
-#if 0
-    int ret;
-    unsigned long ign1;
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1)
-       : "0" (__HYPERVISOR_sched_op),
-         "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
-        : "memory" );
-
-    return ret;
-#endif
-    return 1;
-}
-
-static inline int
-HYPERVISOR_reboot(
-    void)
-{
-#if 0
-    int ret;
-    unsigned long ign1;
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1)
-       : "0" (__HYPERVISOR_sched_op),
-         "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
-        : "memory" );
-
-    return ret;
-#endif
+HYPERVISOR_sched_op(
+    int cmd, unsigned long arg)
+{
     return 1;
 }
 
@@ -262,39 +196,6 @@
 HYPERVISOR_suspend(
     unsigned long srec)
 {
-#if 0
-    int ret;
-    unsigned long ign1, ign2;
-
-    /* NB. On suspend, control software expects a suspend record in %esi. */
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=S" (ign2)
-       : "0" (__HYPERVISOR_sched_op),
-        "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 
-        "S" (srec) : "memory");
-
-    return ret;
-#endif
-    return 1;
-}
-
-static inline int
-HYPERVISOR_crash(
-    void)
-{
-#if 0
-    int ret;
-    unsigned long ign1;
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1)
-       : "0" (__HYPERVISOR_sched_op),
-         "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift))
-        : "memory" );
-
-    return ret;
-#endif
     return 1;
 }
 
@@ -601,24 +502,6 @@
     return 1;
 }
 
-static inline int
-HYPERVISOR_boot_vcpu(
-    unsigned long vcpu, vcpu_guest_context_t *ctxt)
-{
-#if 0
-    int ret;
-    unsigned long ign1, ign2;
-
-    __asm__ __volatile__ (
-        TRAP_INSTR
-        : "=a" (ret), "=b" (ign1), "=c" (ign2)
-       : "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt)
-       : "memory");
-
-    return ret;
-#endif
-    return 1;
-}
 #endif
 
 #endif /* __HYPERCALL_H__ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Sat Oct 
 8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Sat Oct 
 8 20:28:24 2005
@@ -35,6 +35,7 @@
 #define __HYPERCALL_H__
 
 #include <asm-xen/xen-public/xen.h>
+#include <asm-xen/xen-public/sched.h>
 
 #define __syscall_clobber "r11","rcx","memory"
 
@@ -165,33 +166,10 @@
 }
 
 static inline int
-HYPERVISOR_yield(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_yield, 0);
-}
-
-static inline int
-HYPERVISOR_block(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_block, 0);
-}
-
-static inline int
-HYPERVISOR_shutdown(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_shutdown |
-                          (SHUTDOWN_poweroff << SCHEDOP_reasonshift), 0);
-}
-
-static inline int
-HYPERVISOR_reboot(
-       void)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_shutdown |
-                          (SHUTDOWN_reboot << SCHEDOP_reasonshift), 0);
+HYPERVISOR_sched_op(
+       int cmd, unsigned long arg)
+{
+       return _hypercall2(int, sched_op, cmd, arg);
 }
 
 static inline long
@@ -302,26 +280,10 @@
 }
 
 static inline int
-HYPERVISOR_boot_vcpu(
-       unsigned long vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, boot_vcpu, vcpu, ctxt);
-}
-
-static inline int
-HYPERVISOR_vcpu_up(
-       int vcpu)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
-                          (vcpu << SCHEDOP_vcpushift), 0);
-}
-
-static inline int
-HYPERVISOR_vcpu_pickle(
-       int vcpu, vcpu_guest_context_t *ctxt)
-{
-       return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
-                          (vcpu << SCHEDOP_vcpushift), ctxt);
+HYPERVISOR_vcpu_op(
+       int cmd, int vcpuid, void *extra_args)
+{
+       return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
 }
 
 static inline int
@@ -341,8 +303,8 @@
 HYPERVISOR_suspend(
        unsigned long srec)
 {
-       return _hypercall2(int, sched_op, SCHEDOP_shutdown |
-                          (SHUTDOWN_suspend << SCHEDOP_reasonshift), srec);
+       return _hypercall3(int, sched_op, SCHEDOP_shutdown,
+                          SHUTDOWN_suspend, srec);
 }
 
 #endif /* __HYPERCALL_H__ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Sat Oct  8 20:28:24 2005
@@ -50,14 +50,6 @@
 /* Dynamically bind an IPI source to Linux IRQ space. */
 extern int  bind_ipi_to_irq(int ipi);
 extern void unbind_ipi_from_irq(int ipi);
-
-/*
- * Dynamically bind an event-channel port to Linux IRQ space.
- * BIND:   Returns IRQ or error.
- * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
- */
-extern int  bind_evtchn_to_irq(unsigned int evtchn);
-extern void unbind_evtchn_from_irq(unsigned int irq);
 
 /*
  * Dynamically bind an event-channel port to an IRQ-like callback handler.
@@ -124,25 +116,10 @@
 static inline void notify_remote_via_evtchn(int port)
 {
        evtchn_op_t op;
-       op.cmd = EVTCHNOP_send;
-       op.u.send.local_port = port;
+       op.cmd         = EVTCHNOP_send,
+       op.u.send.port = port;
        (void)HYPERVISOR_event_channel_op(&op);
 }
-
-/*
- * CHARACTER-DEVICE DEFINITIONS
- */
-
-/* /dev/xen/evtchn resides at device number major=10, minor=201 */
-#define EVTCHN_MINOR 201
-
-/* /dev/xen/evtchn ioctls: */
-/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
-#define EVTCHN_RESET  _IO('E', 1)
-/* EVTCHN_BIND: Bind to teh specified event-channel port. */
-#define EVTCHN_BIND   _IO('E', 2)
-/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
-#define EVTCHN_UNBIND _IO('E', 3)
 
 #endif /* __ASM_EVTCHN_H__ */
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h
--- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Sat Oct 
 8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Sat Oct 
 8 20:28:24 2005
@@ -3,7 +3,7 @@
  * 
  * Interface to /proc/xen/privcmd.
  * 
- * Copyright (c) 2003-2004, K A Fraser
+ * Copyright (c) 2003-2005, K A Fraser
  * 
  * This file may be distributed separately from the Linux kernel, or
  * incorporated into other software packages, subject to the following license:
@@ -27,39 +27,39 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef __PRIVCMD_H__
-#define __PRIVCMD_H__
+#ifndef __LINUX_PUBLIC_PRIVCMD_H__
+#define __LINUX_PUBLIC_PRIVCMD_H__
 
 typedef struct privcmd_hypercall
 {
-    unsigned long op;
-    unsigned long arg[5];
+       unsigned long op;
+       unsigned long arg[5];
 } privcmd_hypercall_t;
 
 typedef struct privcmd_mmap_entry {
-    unsigned long va;
-    unsigned long mfn;
-    unsigned long npages;
+       unsigned long va;
+       unsigned long mfn;
+       unsigned long npages;
 } privcmd_mmap_entry_t; 
 
 typedef struct privcmd_mmap {
-    int num;
-    domid_t dom; /* target domain */
-    privcmd_mmap_entry_t *entry;
+       int num;
+       domid_t dom; /* target domain */
+       privcmd_mmap_entry_t *entry;
 } privcmd_mmap_t; 
 
 typedef struct privcmd_mmapbatch {
-    int num;     /* number of pages to populate */
-    domid_t dom; /* target domain */
-    unsigned long addr;  /* virtual address */
-    unsigned long *arr; /* array of mfns - top nibble set on err */
+       int num;     /* number of pages to populate */
+       domid_t dom; /* target domain */
+       unsigned long addr;  /* virtual address */
+       unsigned long *arr; /* array of mfns - top nibble set on err */
 } privcmd_mmapbatch_t; 
 
 typedef struct privcmd_blkmsg
 {
-    unsigned long op;
-    void         *buf;
-    int           buf_size;
+       unsigned long op;
+       void         *buf;
+       int           buf_size;
 } privcmd_blkmsg_t;
 
 /*
@@ -67,16 +67,26 @@
  * @arg: &privcmd_hypercall_t
  * Return: Value returned from execution of the specified hypercall.
  */
-#define IOCTL_PRIVCMD_HYPERCALL         \
-    _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
+#define IOCTL_PRIVCMD_HYPERCALL                                        \
+       _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
 
-#define IOCTL_PRIVCMD_MMAP             \
-    _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
-#define IOCTL_PRIVCMD_MMAPBATCH             \
-    _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
-#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN \
-    _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
-#define IOCTL_PRIVCMD_INITDOMAIN_STORE \
-    _IOC(_IOC_READ, 'P', 5, 0)
+#define IOCTL_PRIVCMD_MMAP                                     \
+       _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
+#define IOCTL_PRIVCMD_MMAPBATCH                                        \
+       _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
+#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN                  \
+       _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
+#define IOCTL_PRIVCMD_INITDOMAIN_STORE                         \
+       _IOC(_IOC_READ, 'P', 5, 0)
 
-#endif /* __PRIVCMD_H__ */
+#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Sat Oct  8 20:28:24 2005
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <asm/semaphore.h>
+#include <asm-xen/xen-public/io/xs_wire.h>
 
 /* A xenbus device. */
 struct xenbus_device {
@@ -73,7 +74,7 @@
        return container_of(drv, struct xenbus_driver, driver);
 }
 
-int xenbus_register_device(struct xenbus_driver *drv);
+int xenbus_register_driver(struct xenbus_driver *drv);
 int xenbus_register_backend(struct xenbus_driver *drv);
 void xenbus_unregister_driver(struct xenbus_driver *drv);
 
@@ -113,7 +114,8 @@
 {
        struct list_head list;
        char *node;
-       void (*callback)(struct xenbus_watch *, const char *node);
+       void (*callback)(struct xenbus_watch *,
+                        const char **vec, unsigned int len);
 };
 
 /* notifer routines for when the xenstore comes up */
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.6-xen-sparse/mkbuildtree
--- a/linux-2.6-xen-sparse/mkbuildtree  Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/mkbuildtree  Sat Oct  8 20:28:24 2005
@@ -113,9 +113,6 @@
 cd     ${AD}/include/asm-xen/xen-public
 relative_lndir ../../../${RS}/../xen/include/public
 
-cd ${AD}/include/asm-xen/linux-public
-ln -sf ../../../${RS}/../tools/xenstore/xenstored.h
-
 # Arch-specific post-processing
 cd ${AD}
 if [ -x arch/${LINUX_ARCH}/xen-mkbuildtree-post ]; then
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/Makefile
--- a/tools/Makefile    Sat Oct  8 17:37:45 2005
+++ b/tools/Makefile    Sat Oct  8 20:28:24 2005
@@ -22,7 +22,7 @@
 # These don't cross-compile
 ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
 SUBDIRS += python
-#SUBDIRS += pygrub
+SUBDIRS += pygrub
 endif
 
 .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/blktap/xenbus.c
--- a/tools/blktap/xenbus.c     Sat Oct  8 17:37:45 2005
+++ b/tools/blktap/xenbus.c     Sat Oct  8 20:28:24 2005
@@ -116,25 +116,25 @@
 
 
 /* This assumes that the domain name we are looking for is unique! */
-char *get_dom_uuid(struct xs_handle *h, const char *name)
-{
-    char **e, *val, *uuid = NULL;
+char *get_dom_domid(struct xs_handle *h, const char *name)
+{
+    char **e, *val, *domid = NULL;
     int num, i, len;
     char *path;
 
-    e = xs_directory(h, "/domain", &num);
+    e = xs_directory(h, "/local/domain", &num);
 
     i=0;
     while (i < num) {
-        asprintf(&path, "/domain/%s/name", e[i]);
+        asprintf(&path, "/local/domain/%s/name", e[i]);
         val = xs_read(h, path, &len);
         free(path);
         if (val == NULL)
             continue;
         if (strcmp(val, name) == 0) {
             /* match! */
-            asprintf(&path, "/domain/%s/uuid", e[i]);
-            uuid = xs_read(h, path, &len);
+            asprintf(&path, "/local/domain/%s/domid", e[i]);
+            domid = xs_read(h, path, &len);
             free(val);
             free(path);
             break;
@@ -144,7 +144,7 @@
     }
 
     free(e);
-    return uuid;
+    return domid;
 }
 
 static int strsep_len(const char *str, char c, unsigned int len)
@@ -251,13 +251,14 @@
     char *node = NULL;
     struct xenbus_watch *w;
     int er;
-
-    res = xs_read_watch(h);
+    unsigned int num;
+
+    res = xs_read_watch(h, &num);
     if (res == NULL) 
         return -EAGAIN; /* in O_NONBLOCK, read_watch returns 0... */
 
-    node  = res[0];
-    token = res[1];
+    node  = res[XS_WATCH_PATH];
+    token = res[XS_WATCH_TOKEN];
 
     er = xs_acknowledge_watch(h, token);
     if (er == 0)
@@ -553,15 +554,15 @@
 
 int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
 {
-    char *uuid, *path;
+    char *domid, *path;
     struct xenbus_watch *vbd_watch;
     int er;
 
-    uuid = get_dom_uuid(h, domname);
-
-    DPRINTF("%s: %s\n", domname, (uuid != NULL) ? uuid : "[ not found! ]");
-
-    asprintf(&path, "/domain/%s/backend/vbd", uuid);
+    domid = get_dom_domid(h, domname);
+
+    DPRINTF("%s: %s\n", domname, (domid != NULL) ? domid : "[ not found! ]");
+
+    asprintf(&path, "/local/domain/%s/backend/vbd", domid);
     if (path == NULL) 
         return -ENOMEM;
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/check/check_hotplug
--- a/tools/check/check_hotplug Sat Oct  8 17:37:45 2005
+++ b/tools/check/check_hotplug Sat Oct  8 20:28:24 2005
@@ -7,4 +7,8 @@
    exit 1
 }
 
+if [ -x /sbin/udev ] && [ ! -z `udev -V` ] && [ `udev -V` -ge 059 ]; then
+  exit 0
+fi
+
 which hotplug 1>/dev/null 2>&1 || error
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Sat Oct  8 17:37:45 2005
+++ b/tools/console/daemon/io.c Sat Oct  8 20:28:24 2005
@@ -1,4 +1,4 @@
-/*\
+/*
  *  Copyright (C) International Business Machines  Corp., 2005
  *  Author(s): Anthony Liguori <aliguori@xxxxxxxxxx>
  *
@@ -16,14 +16,15 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-\*/
+ */
 
 #define _GNU_SOURCE
 
 #include "utils.h"
 #include "io.h"
-#include "xenctrl.h"
-#include "xs.h"
+#include <xenctrl.h>
+#include <xs.h>
+#include <xen/linux/evtchn.h>
 
 #include <malloc.h>
 #include <stdlib.h>
@@ -80,14 +81,24 @@
 #define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE)
 #define XENCONS_SPACE(ring) (XENCONS_RING_SIZE - ((ring)->prod - (ring)->cons))
 
+static void evtchn_notify(struct domain *dom)
+{
+       struct ioctl_evtchn_notify notify;
+       notify.port = dom->local_port;
+       (void)ioctl(dom->evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+
 static void buffer_append(struct domain *dom)
 {
        struct buffer *buffer = &dom->buffer;
        struct ring_head *ring = (struct ring_head *)dom->page;
        size_t size;
        u32 oldcons;
+       int notify = 0;
 
        while ((size = ring->prod - ring->cons) != 0) {
+               notify = 1;
+
                if ((buffer->capacity - buffer->size) < size) {
                        buffer->capacity += (size + 1024);
                        buffer->data = realloc(buffer->data, buffer->capacity);
@@ -115,6 +126,9 @@
                        buffer->capacity = buffer->max_capacity;
                }
        }
+
+       if (notify)
+               evtchn_notify(dom);
 }
 
 static bool buffer_empty(struct buffer *buffer)
@@ -219,16 +233,14 @@
        return ret;
 }
 
-#define EVENTCHN_BIND          _IO('E', 2)
-#define EVENTCHN_UNBIND        _IO('E', 3)
-
 static int domain_create_ring(struct domain *dom)
 {
-       int err, local_port, ring_ref;
+       int err, remote_port, ring_ref, rc;
+       struct ioctl_evtchn_bind_interdomain bind;
 
        err = xs_gather(xs, dom->conspath,
                        "ring-ref", "%u", &ring_ref,
-                       "port", "%i", &local_port,
+                       "port", "%i", &remote_port,
                        NULL);
        if (err)
                goto out;
@@ -246,26 +258,28 @@
                dom->ring_ref = ring_ref;
        }
 
-       if (local_port != dom->local_port) {
-               dom->local_port = -1;
-               if (dom->evtchn_fd != -1)
-                       close(dom->evtchn_fd);
-               /* Opening evtchn independently for each console is a bit
-                * wastefule, but that's how the code is structured... */
-               dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
-               if (dom->evtchn_fd == -1) {
-                       err = errno;
-                       goto out;
-               }
+       dom->local_port = -1;
+       if (dom->evtchn_fd != -1)
+               close(dom->evtchn_fd);
+
+       /* Opening evtchn independently for each console is a bit
+        * wasteful, but that's how the code is structured... */
+       dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
+       if (dom->evtchn_fd == -1) {
+               err = errno;
+               goto out;
+       }
  
-               if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, local_port) == -1) {
-                       err = errno;
-                       close(dom->evtchn_fd);
-                       dom->evtchn_fd = -1;
-                       goto out;
-               }
-               dom->local_port = local_port;
-       }
+       bind.remote_domain = dom->domid;
+       bind.remote_port   = remote_port;
+       rc = ioctl(dom->evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+       if (rc == -1) {
+               err = errno;
+               close(dom->evtchn_fd);
+               dom->evtchn_fd = -1;
+               goto out;
+       }
+       dom->local_port = rc;
 
  out:
        return err;
@@ -433,7 +447,7 @@
                        inring->buf[XENCONS_IDX(inring->prod)] = msg[i];
                        inring->prod++;
                }
-               xc_evtchn_send(xc, dom->local_port);
+               evtchn_notify(dom);
        } else {
                close(dom->tty_fd);
                dom->tty_fd = -1;
@@ -477,14 +491,15 @@
        char **vec;
        int domid;
        struct domain *dom;
-
-       vec = xs_read_watch(xs);
+       unsigned int num;
+
+       vec = xs_read_watch(xs, &num);
        if (!vec)
                return;
 
-       if (!strcmp(vec[1], "domlist"))
+       if (!strcmp(vec[XS_WATCH_TOKEN], "domlist"))
                enum_domains();
-       else if (sscanf(vec[1], "dom%u", &domid) == 1) {
+       else if (sscanf(vec[XS_WATCH_TOKEN], "dom%u", &domid) == 1) {
                dom = lookup_domain(domid);
                if (dom->is_dead == false)
                        domain_create_ring(dom);
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/debugger/pdb/pdb_xen.c
--- a/tools/debugger/pdb/pdb_xen.c      Sat Oct  8 17:37:45 2005
+++ b/tools/debugger/pdb/pdb_xen.c      Sat Oct  8 20:28:24 2005
@@ -43,11 +43,7 @@
 
 
 #include <sys/ioctl.h>
-
-/* /dev/xen/evtchn ioctls */
-#define EVTCHN_RESET  _IO('E', 1)                   /* clear & reinit buffer */
-#define EVTCHN_BIND   _IO('E', 2)                   /* bind to event channel */
-#define EVTCHN_UNBIND _IO('E', 3)               /* unbind from event channel */
+#include <xen/linux/evtchn.h>
 
 int
 xen_evtchn_bind (int evtchn_fd, int idx)
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/Makefile
--- a/tools/examples/Makefile   Sat Oct  8 17:37:45 2005
+++ b/tools/examples/Makefile   Sat Oct  8 20:28:24 2005
@@ -21,17 +21,30 @@
 XEN_SCRIPT_DIR = /etc/xen/scripts
 XEN_SCRIPTS = network-bridge vif-bridge
 XEN_SCRIPTS += network-route vif-route
-XEN_SCRIPTS += block-phy
-XEN_SCRIPTS += block-file
+XEN_SCRIPTS += network-nat vif-nat
+XEN_SCRIPTS += block
 XEN_SCRIPTS += block-enbd
 
 XEN_HOTPLUG_DIR = /etc/hotplug
 XEN_HOTPLUG_SCRIPTS = xen-backend.agent
 
+UDEV_RULES_DIR = /etc/udev/rules.d
+UDEV_RULES = xen-backend.rules
+
+ifeq ($(findstring $(DISTDIR),$(DESTDIR)),$(DISTDIR))
+HOTPLUGS=install-hotplug install-udev
+else
+ifeq ($(shell [ -x /sbin/udev ] && [ ! -z `udev -V` ] && [ `/sbin/udev -V` -ge 
059 ] && echo 1),1)
+HOTPLUGS=install-udev
+else
+HOTPLUGS=install-hotplug
+endif
+endif
+
 all:
 build:
 
-install: all install-initd install-configs install-scripts install-hotplug
+install: all install-initd install-configs install-scripts $(HOTPLUGS)
 
 install-initd:
        [ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
@@ -44,7 +57,7 @@
        [ -d $(DESTDIR)$(XEN_CONFIG_DIR)/auto ] || \
                $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)/auto
        for i in $(XEN_CONFIGS); \
-           do [ -a $(DESTDIR)$(XEN_CONFIG_DIR)/$$i ] || \
+           do [ -e $(DESTDIR)$(XEN_CONFIG_DIR)/$$i ] || \
            $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \
        done
 
@@ -52,7 +65,7 @@
        [ -d $(DESTDIR)$(XEN_SCRIPT_DIR) ] || \
                $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
        for i in $(XEN_SCRIPTS); \
-           do [ -a $(DESTDIR)$(XEN_SCRIPT_DIR)/$$i ] || \
+           do \
            $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
        done
 
@@ -64,4 +77,12 @@
            $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_HOTPLUG_DIR); \
        done
 
+install-udev:
+       [ -d $(DESTDIR)$(UDEV_RULES_DIR) ] || \
+               $(INSTALL_DIR) $(DESTDIR)$(UDEV_RULES_DIR)
+       for i in $(UDEV_RULES); \
+           do \
+           $(INSTALL_PROG) $$i $(DESTDIR)$(UDEV_RULES_DIR); \
+       done
+
 clean:
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/network-bridge
--- a/tools/examples/network-bridge     Sat Oct  8 17:37:45 2005
+++ b/tools/examples/network-bridge     Sat Oct  8 20:28:24 2005
@@ -38,6 +38,17 @@
 # Print routes.
 #
 #============================================================================
+
+# Gentoo doesn't have ifup/ifdown: define appropriate alternatives
+which ifup >& /dev/null
+if [ "$?" != 0 -a -e /etc/conf.d/net ]; then
+    ifup() {
+        /etc/init.d/net.$1 start
+    }
+    ifdown() {
+        /etc/init.d/net.$1 stop
+    }
+fi
 
 # Exit if anything goes wrong.
 set -e 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Sat Oct  8 17:37:45 2005
+++ b/tools/examples/vif-bridge Sat Oct  8 20:28:24 2005
@@ -33,6 +33,7 @@
 
 # Exit if anything goes wrong
 set -e 
+export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH
 
 echo "*vif-bridge $*" >&2
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/vif-nat
--- a/tools/examples/vif-nat    Sat Oct  8 17:37:45 2005
+++ b/tools/examples/vif-nat    Sat Oct  8 20:28:24 2005
@@ -22,7 +22,7 @@
 
 # Exit if anything goes wrong
 set -e 
-
+export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH
 echo "*vif-nat $*" >&2
 
 # Operation name.
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/vif-route
--- a/tools/examples/vif-route  Sat Oct  8 17:37:45 2005
+++ b/tools/examples/vif-route  Sat Oct  8 20:28:24 2005
@@ -23,7 +23,7 @@
 
 # Exit if anything goes wrong
 set -e 
-
+export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH
 echo "*vif-route $*" >&2
 
 # Operation name.
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent  Sat Oct  8 17:37:45 2005
+++ b/tools/examples/xen-backend.agent  Sat Oct  8 20:28:24 2005
@@ -11,20 +11,14 @@
   add)
     case "$XENBUS_TYPE" in
       vbd)
-        t=$(xenstore-read "$XENBUS_PATH"/type)
-        params=$(xenstore-read "$XENBUS_PATH"/params)
-        [ -x /etc/xen/scripts/block-"$t" ] && \
-            /etc/xen/scripts/block-"$t" bind $params
+       /etc/xen/scripts/block bind
         ;;
     esac
     ;;
   remove)
     case "$XENBUS_TYPE" in
       vbd)
-        t=$(xenstore-read "$XENBUS_PATH"/type)
-        node=$(xenstore-read "$XENBUS_PATH"/node)
-        [ -x /etc/xen/scripts/block-"$t" ] && \
-            /etc/xen/scripts/block-"$t" unbind $node
+       /etc/xen/scripts/block unbind
         ;;
     esac
     # remove device backend store entries
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx      Sat Oct  8 17:37:45 2005
+++ b/tools/examples/xmexample.vmx      Sat Oct  8 20:28:24 2005
@@ -48,12 +48,41 @@
 disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
 
 #----------------------------------------------------------------------------
-# Set according to whether you want the domain restarted when it exits.
-# The default is 'onreboot', which restarts the domain when it shuts down
-# with exit code reboot.
-# Other values are 'always', and 'never'.
+# Configure the behaviour when a domain exits.  There are three 'reasons'
+# for a domain to stop: poweroff, reboot, and crash.  For each of these you
+# may specify:
+#
+#   "destroy",        meaning that the domain is cleaned up as normal;
+#   "restart",        meaning that a new domain is started in place of the old
+#                     one;
+#   "preserve",       meaning that no clean-up is done until the domain is
+#                     manually destroyed (using xm destroy, for example); or
+#   "rename-restart", meaning that the old domain is not cleaned up, but is
+#                     renamed and a new domain started in its place.
+#
+# The default is
+#
+#   on_poweroff = 'destroy'
+#   on_reboot   = 'restart'
+#   on_crash    = 'restart'
+#
+# For backwards compatibility we also support the deprecated option restart
+#
+# restart = 'onreboot' means on_poweroff = 'destroy'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'destroy'
+#
+# restart = 'always'   means on_poweroff = 'restart'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'restart'
+#
+# restart = 'never'    means on_poweroff = 'destroy'
+#                            on_reboot   = 'destroy'
+#                            on_crash    = 'destroy'
 
-#restart = 'onreboot'
+#on_poweroff = 'destroy'
+#on_reboot   = 'restart'
+#on_crash    = 'restart'
 
 #============================================================================
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/xmexample1
--- a/tools/examples/xmexample1 Sat Oct  8 17:37:45 2005
+++ b/tools/examples/xmexample1 Sat Oct  8 20:28:24 2005
@@ -91,11 +91,40 @@
 extra = "4"
 
 #----------------------------------------------------------------------------
-# Set according to whether you want the domain restarted when it exits.
-# The default is 'onreboot', which restarts the domain when it shuts down
-# with exit code reboot.
-# Other values are 'always', and 'never'.
+# Configure the behaviour when a domain exits.  There are three 'reasons'
+# for a domain to stop: poweroff, reboot, and crash.  For each of these you
+# may specify:
+#
+#   "destroy",        meaning that the domain is cleaned up as normal;
+#   "restart",        meaning that a new domain is started in place of the old
+#                     one;
+#   "preserve",       meaning that no clean-up is done until the domain is
+#                     manually destroyed (using xm destroy, for example); or
+#   "rename-restart", meaning that the old domain is not cleaned up, but is
+#                     renamed and a new domain started in its place.
+#
+# The default is
+#
+#   on_poweroff = 'destroy'
+#   on_reboot   = 'restart'
+#   on_crash    = 'restart'
+#
+# For backwards compatibility we also support the deprecated option restart
+#
+# restart = 'onreboot' means on_poweroff = 'destroy'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'destroy'
+#
+# restart = 'always'   means on_poweroff = 'restart'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'restart'
+#
+# restart = 'never'    means on_poweroff = 'destroy'
+#                            on_reboot   = 'destroy'
+#                            on_crash    = 'destroy'
 
-#restart = 'onreboot'
+#on_poweroff = 'destroy'
+#on_reboot   = 'restart'
+#on_crash    = 'restart'
 
 #============================================================================
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/xmexample2
--- a/tools/examples/xmexample2 Sat Oct  8 17:37:45 2005
+++ b/tools/examples/xmexample2 Sat Oct  8 20:28:24 2005
@@ -127,11 +127,40 @@
 extra = "4 VMID=%d usr=/dev/sda6" % vmid
 
 #----------------------------------------------------------------------------
-# Set according to whether you want the domain restarted when it exits.
-# The default is 'onreboot', which restarts the domain when it shuts down
-# with exit code reboot.
-# Other values are 'always', and 'never'.
+# Configure the behaviour when a domain exits.  There are three 'reasons'
+# for a domain to stop: poweroff, reboot, and crash.  For each of these you
+# may specify:
+#
+#   "destroy",        meaning that the domain is cleaned up as normal;
+#   "restart",        meaning that a new domain is started in place of the old
+#                     one;
+#   "preserve",       meaning that no clean-up is done until the domain is
+#                     manually destroyed (using xm destroy, for example); or
+#   "rename-restart", meaning that the old domain is not cleaned up, but is
+#                     renamed and a new domain started in its place.
+#
+# The default is
+#
+#   on_poweroff = 'destroy'
+#   on_reboot   = 'restart'
+#   on_crash    = 'restart'
+#
+# For backwards compatibility we also support the deprecated option restart
+#
+# restart = 'onreboot' means on_poweroff = 'destroy'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'destroy'
+#
+# restart = 'always'   means on_poweroff = 'restart'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'restart'
+#
+# restart = 'never'    means on_poweroff = 'destroy'
+#                            on_reboot   = 'destroy'
+#                            on_crash    = 'destroy'
 
-#restart = 'onreboot'
+#on_poweroff = 'destroy'
+#on_reboot   = 'restart'
+#on_crash    = 'restart'
 
 #============================================================================
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/xmexample3
--- a/tools/examples/xmexample3 Sat Oct  8 17:37:45 2005
+++ b/tools/examples/xmexample3 Sat Oct  8 20:28:24 2005
@@ -124,11 +124,40 @@
 extra = "4 VMID=%d" % vmid
 
 #----------------------------------------------------------------------------
-# Set according to whether you want the domain restarted when it exits.
-# The default is 'onreboot', which restarts the domain when it shuts down
-# with exit code reboot.
-# Other values are 'always', and 'never'.
+# Configure the behaviour when a domain exits.  There are three 'reasons'
+# for a domain to stop: poweroff, reboot, and crash.  For each of these you
+# may specify:
+#
+#   "destroy",        meaning that the domain is cleaned up as normal;
+#   "restart",        meaning that a new domain is started in place of the old
+#                     one;
+#   "preserve",       meaning that no clean-up is done until the domain is
+#                     manually destroyed (using xm destroy, for example); or
+#   "rename-restart", meaning that the old domain is not cleaned up, but is
+#                     renamed and a new domain started in its place.
+#
+# The default is
+#
+#   on_poweroff = 'destroy'
+#   on_reboot   = 'restart'
+#   on_crash    = 'restart'
+#
+# For backwards compatibility we also support the deprecated option restart
+#
+# restart = 'onreboot' means on_poweroff = 'destroy'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'destroy'
+#
+# restart = 'always'   means on_poweroff = 'restart'
+#                            on_reboot   = 'restart'
+#                            on_crash    = 'restart'
+#
+# restart = 'never'    means on_poweroff = 'destroy'
+#                            on_reboot   = 'destroy'
+#                            on_crash    = 'destroy'
 
-#restart = 'onreboot'
+#on_poweroff = 'destroy'
+#on_reboot   = 'restart'
+#on_crash    = 'restart'
 
 #============================================================================
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Sat Oct  8 17:37:45 2005
+++ b/tools/firmware/vmxassist/Makefile Sat Oct  8 20:28:24 2005
@@ -25,9 +25,7 @@
 TEXTADDR=0x000D0000
 
 DEFINES=-DDEBUG -DTEXTADDR=${TEXTADDR}
-XENINC=-I$(XEN_ROOT)/xen/include -I$(XEN_ROOT)/tools/libxc
-#DEFINES=-DDEBUG -DTEST -DTEXTADDR=${TEXTADDR}
-#XENINC=-I/home/leendert/xen/xeno-unstable.bk/xen/include
+XENINC=-I$(XEN_ROOT)/tools/libxc
 
 LD       = ld
 CC       = gcc
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/firmware/vmxassist/vm86.h
--- a/tools/firmware/vmxassist/vm86.h   Sat Oct  8 17:37:45 2005
+++ b/tools/firmware/vmxassist/vm86.h   Sat Oct  8 20:28:24 2005
@@ -33,7 +33,7 @@
 typedef int64_t            s64;
 #endif
 
-#include <public/vmx_assist.h>
+#include <xen/vmx_assist.h>
 
 #define        NR_EXCEPTION_HANDLER    32
 #define        NR_INTERRUPT_HANDLERS   16
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/ioemu/hw/i8254.c
--- a/tools/ioemu/hw/i8254.c    Sat Oct  8 17:37:45 2005
+++ b/tools/ioemu/hw/i8254.c    Sat Oct  8 20:28:24 2005
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
-#include "xenctrl.h"
-#include <io/ioreq.h>
+#include <xenctrl.h>
+#include <xen/io/ioreq.h>
 
 //#define DEBUG_PIT
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/ioemu/hw/i8259.c
--- a/tools/ioemu/hw/i8259.c    Sat Oct  8 17:37:45 2005
+++ b/tools/ioemu/hw/i8259.c    Sat Oct  8 20:28:24 2005
@@ -22,8 +22,8 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
-#include "xenctrl.h"
-#include <io/ioreq.h>
+#include <xenctrl.h>
+#include <xen/io/ioreq.h>
 
 /* debug PIC */
 //#define DEBUG_PIC
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/ioemu/hw/ioapic.h
--- a/tools/ioemu/hw/ioapic.h   Sat Oct  8 17:37:45 2005
+++ b/tools/ioemu/hw/ioapic.h   Sat Oct  8 20:28:24 2005
@@ -26,9 +26,9 @@
 #ifndef __IOAPIC_H
 #define __IOAPIC_H
 
-#include "xenctrl.h"
-#include <io/ioreq.h>
-#include <io/vmx_vlapic.h>
+#include <xenctrl.h>
+#include <xen/io/ioreq.h>
+#include <xen/io/vmx_vlapic.h>
 
 #define IOAPIC_NUM_PINS 24
 #define IOAPIC_VERSION_ID 0x11
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile       Sat Oct  8 17:37:45 2005
+++ b/tools/ioemu/target-i386-dm/Makefile       Sat Oct  8 20:28:24 2005
@@ -6,7 +6,7 @@
 INSTALL_DIR := $(DESTDIR)/usr/$(LIBDIR)/xen/bin
 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
 VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
-DEFINES=-I. -I$(TARGET_PATH) -I$(SRC_PATH) -I$(XEN_ROOT)/xen/include/public
+DEFINES=-I. -I$(TARGET_PATH) -I$(SRC_PATH)
 DEFINES+= -I$(XEN_ROOT)/tools/libxc
 ifdef CONFIG_USER_ONLY
 VPATH+=:$(SRC_PATH)/linux-user
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Sat Oct  8 17:37:45 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c      Sat Oct  8 20:28:24 2005
@@ -47,12 +47,15 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
-#include "xenctrl.h"
-#include <io/ioreq.h>
+#include <xenctrl.h>
+#include <xen/io/ioreq.h>
+#include <xen/linux/evtchn.h>
 
 #include "cpu.h"
 #include "exec-all.h"
 #include "vl.h"
+
+extern int domid;
 
 void *shared_vram;
 
@@ -119,7 +122,7 @@
 //the evtchn fd for polling
 int evtchn_fd = -1;
 //the evtchn port for polling the notification, should be inputed as bochs's 
parameter
-u16 ioreq_port = 0;
+u16 ioreq_remote_port, ioreq_local_port;
 
 //some functions to handle the io req packet
 void
@@ -156,9 +159,9 @@
        int rc;
        u16 buf[2];
        rc = read(evtchn_fd, buf, 2);
-       if (rc == 2 && buf[0] == ioreq_port){//got only one matched 16bit port 
index
+       if (rc == 2 && buf[0] == ioreq_local_port){//got only one matched 16bit 
port index
                // unmask the wanted port again
-               write(evtchn_fd, &ioreq_port, 2);
+               write(evtchn_fd, &ioreq_local_port, 2);
 
                //get the io packet from shared memory
                return __cpu_get_ioreq();
@@ -417,7 +420,6 @@
 void
 destroy_vmx_domain(void)
 {
-    extern int domid;
     extern FILE* logfile;
     char destroy_cmd[20];
     sprintf(destroy_cmd, "xm destroy %d", domid);
@@ -484,11 +486,9 @@
                     do_ioapic();
 #endif
                if (env->send_event) {
-                       int ret;
-                       ret = xc_evtchn_send(xc_handle, ioreq_port);
-                       if (ret == -1) {
-                               fprintf(logfile, "evtchn_send failed on port: 
%d\n", ioreq_port);
-                       }
+                       struct ioctl_evtchn_notify notify;
+                       notify.port = ioreq_local_port;
+                       (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
                }
        }
         destroy_vmx_domain();
@@ -499,7 +499,6 @@
 qemu_vmx_reset(void *unused)
 {
     char cmd[255];
-    extern int domid;
 
     /* pause domain first, to avoid repeated reboot request*/ 
     xc_domain_pause (xc_handle, domid);
@@ -512,6 +511,8 @@
 cpu_init()
 {
        CPUX86State *env;
+       struct ioctl_evtchn_bind_interdomain bind;
+       int rc;
       
         cpu_exec_init();
         qemu_register_reset(qemu_vmx_reset, NULL);
@@ -532,12 +533,14 @@
                return NULL;
        }
 
-       fprintf(logfile, "listening to port: %d\n", ioreq_port);
-       /*unmask the wanted port -- bind*/
-       if (ioctl(evtchn_fd, ('E'<<8)|2, ioreq_port) == -1) {
+       bind.remote_domain = domid;
+       bind.remote_port   = ioreq_remote_port;
+       rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+       if (rc == -1) {
                perror("ioctl");
                return NULL;
        }
+       ioreq_local_port = rc;
 
        return env;
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Sat Oct  8 17:37:45 2005
+++ b/tools/ioemu/vl.c  Sat Oct  8 20:28:24 2005
@@ -2806,9 +2806,9 @@
 
             case QEMU_OPTION_p:
                 {
-                  extern short ioreq_port;
-                  ioreq_port = atoi(optarg);
-                  printf("port: %d\n", ioreq_port);
+                  extern u16 ioreq_remote_port;
+                  ioreq_remote_port = atoi(optarg);
+                  printf("port: %d\n", ioreq_remote_port);
                 }
                 break;
             case QEMU_OPTION_l:
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/libxc/xc_evtchn.c
--- a/tools/libxc/xc_evtchn.c   Sat Oct  8 17:37:45 2005
+++ b/tools/libxc/xc_evtchn.c   Sat Oct  8 20:28:24 2005
@@ -34,92 +34,18 @@
 
 int xc_evtchn_alloc_unbound(int xc_handle,
                             u32 dom,
-                            int *port)
+                            u32 remote_dom)
 {
-    evtchn_op_t op;
     int         rc;
-
-    op.cmd = EVTCHNOP_alloc_unbound;
-    op.u.alloc_unbound.dom  = (domid_t)dom;
-    op.u.alloc_unbound.port = (port != NULL) ? *port : 0;
+    evtchn_op_t op = {
+        .cmd = EVTCHNOP_alloc_unbound,
+        .u.alloc_unbound.dom = (domid_t)dom,
+        .u.alloc_unbound.remote_dom = (domid_t)remote_dom };
 
     if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
-    {
-        if ( port != NULL )
-            *port = op.u.alloc_unbound.port;
-    }
+        rc = op.u.alloc_unbound.port;
     
     return rc;
-}
-
-
-int xc_evtchn_bind_interdomain(int xc_handle,
-                               u32 dom1,
-                               u32 dom2,
-                               int *port1,
-                               int *port2)
-{
-    evtchn_op_t op;
-    int         rc;
-
-    op.cmd = EVTCHNOP_bind_interdomain;
-    op.u.bind_interdomain.dom1  = (domid_t)dom1;
-    op.u.bind_interdomain.dom2  = (domid_t)dom2;
-    op.u.bind_interdomain.port1 = (port1 != NULL) ? *port1 : 0;
-    op.u.bind_interdomain.port2 = (port2 != NULL) ? *port2 : 0;
-
-
-    if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
-    {
-        if ( port1 != NULL )
-            *port1 = op.u.bind_interdomain.port1;
-        if ( port2 != NULL )
-            *port2 = op.u.bind_interdomain.port2;
-    }
-    
-    return rc;
-}
-
-
-int xc_evtchn_bind_virq(int xc_handle,
-                        int virq,
-                        int *port)
-{
-    evtchn_op_t op;
-    int         rc;
-
-    op.cmd = EVTCHNOP_bind_virq;
-    op.u.bind_virq.virq = (u32)virq;
-   
-    if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
-    {
-        if ( port != NULL )
-            *port = op.u.bind_virq.port;
-    }
-    
-    return rc;
-}
-
-
-int xc_evtchn_close(int xc_handle,
-                    u32 dom,
-                    int port)
-{
-    evtchn_op_t op;
-    op.cmd = EVTCHNOP_close;
-    op.u.close.dom  = (domid_t)dom;
-    op.u.close.port = port;
-    return do_evtchn_op(xc_handle, &op);
-}
-
-
-int xc_evtchn_send(int xc_handle,
-                   int local_port)
-{
-    evtchn_op_t op;
-    op.cmd = EVTCHNOP_send;
-    op.u.send.local_port = local_port;
-    return do_evtchn_op(xc_handle, &op);
 }
 
 
@@ -128,13 +54,12 @@
                      int port,
                      xc_evtchn_status_t *status)
 {
-    evtchn_op_t op;
     int         rc;
+    evtchn_op_t op = {
+        .cmd           = EVTCHNOP_status,
+        .u.status.dom  = (domid_t)dom,
+        .u.status.port = port };
 
-    op.cmd = EVTCHNOP_status;
-    op.u.status.dom  = (domid_t)dom;
-    op.u.status.port = port;
-   
     if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
         memcpy(status, &op.u.status, sizeof(*status));
     
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Sat Oct  8 17:37:45 2005
+++ b/tools/libxc/xc_linux_restore.c    Sat Oct  8 20:28:24 2005
@@ -500,13 +500,13 @@
     }
 
     /* Uncanonicalise the suspend-record frame number and poke resume rec. */
-    pfn = ctxt.user_regs.esi;
+    pfn = ctxt.user_regs.edx;
     if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
     {
         ERR("Suspend record frame number is bad");
         goto out;
     }
-    ctxt.user_regs.esi = mfn = pfn_to_mfn_table[pfn];
+    ctxt.user_regs.edx = mfn = pfn_to_mfn_table[pfn];
     start_info = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
     start_info->nr_pages    = nr_pfns;
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Sat Oct  8 17:37:45 2005
+++ b/tools/libxc/xc_linux_save.c       Sat Oct  8 20:28:24 2005
@@ -978,9 +978,9 @@
                     goto out;
                 }
 
-                DPRINTF("SUSPEND shinfo %08lx eip %08u esi %08u\n",
+                DPRINTF("SUSPEND shinfo %08lx eip %08u edx %08u\n",
                         info.shared_info_frame,
-                        ctxt.user_regs.eip, ctxt.user_regs.esi);
+                        ctxt.user_regs.eip, ctxt.user_regs.edx);
             } 
 
             if ( xc_shadow_control( xc_handle, dom, 
@@ -1048,7 +1048,7 @@
     }
 
     /* Canonicalise the suspend-record frame number. */
-    if ( !translate_mfn_to_pfn(&ctxt.user_regs.esi) )
+    if ( !translate_mfn_to_pfn(&ctxt.user_regs.edx) )
     {
         ERR("Suspend record is not in range of pseudophys map");
         goto out;
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Sat Oct  8 17:37:45 2005
+++ b/tools/libxc/xenctrl.h     Sat Oct  8 20:28:24 2005
@@ -25,6 +25,7 @@
 #include <xen/dom0_ops.h>
 #include <xen/version.h>
 #include <xen/event_channel.h>
+#include <xen/sched.h>
 #include <xen/sched_ctl.h>
 #include <xen/acm.h>
 
@@ -305,66 +306,14 @@
  * well-known port within a domain to receive events on.
  *
  * @parm xc_handle a handle to an open hypervisor interface
- * @parm dom the ID of the domain.  This maybe DOMID_SELF
- * @parm port a pointer to a port.  This is an in/out parameter.  If *port is
- *            0, then a new port will be assigned, if port is > 0 then that
- *            port is allocated if the port is unallocated.
- * @return 0 on success, -1 on failure
+ * @parm dom the ID of the local domain (the 'allocatee')
+ * @parm remote_dom the ID of the domain who will later bind
+ * @return allocated port (in @dom) on success, -1 on failure
  */
 int xc_evtchn_alloc_unbound(int xc_handle,
                             u32 dom,
-                            int *port);
-
-/**
- * This function creates a pair of ports between two domains.  A port can only
- * be bound once within a domain.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm dom1 one of the two domains to connect.  Can be DOMID_SELF.
- * @parm dom2 the other domain to connect.  Can be DOMID_SELF.
- * @parm port1 an in/out parameter.  If > 0, then try to connect *port.  If
- *             0, then allocate a new port and store the port in *port.
- * @parm port2 the port connected on port2.  This parameter behaves the same
- *             way as port1.
- * @return 0 on success, -1 on error.
- */
-int xc_evtchn_bind_interdomain(int xc_handle,
-                               u32 dom1,
-                               u32 dom2,
-                               int *port1,
-                               int *port2);
-int xc_evtchn_bind_virq(int xc_handle,
-                        int virq,
-                        int *port);
-
-/**
- * This function will close a single port on an event channel.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm dom the domain that the port exists on.  May be DOMID_SELF.
- * @parm port the port to close
- * @return 0 on success, -1 on error
- */
-int xc_evtchn_close(int xc_handle,
-                    u32 dom,   /* may be DOMID_SELF */
-                    int port);
-
-/**
- * This function generates a notify event on a bound port.
- *
- * Notifies can be read within Linux by opening /dev/xen/evtchn and reading
- * a 16 bit value.  The result will be the port the event occurred on.  When
- * events occur, the port is masked until the 16 bit port value is written back
- * to the file.  When /dev/xen/evtchn is opened, it has to be bound via an
- * ioctl to each port to listen on.  The ioctl for binding is _IO('E', 2).  The
- * parameter is the port to listen on.
- *
- * @parm xc_handle a handle to an open hypervisor interface
- * @parm local_port the port to generate the notify on
- * @return 0 on success, -1 on error
- */
-int xc_evtchn_send(int xc_handle,
-                   int local_port);
+                            u32 remote_dom);
+
 int xc_evtchn_status(int xc_handle,
                      u32 dom, /* may be DOMID_SELF */
                      int port,
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/pygrub/Makefile
--- a/tools/pygrub/Makefile     Sat Oct  8 17:37:45 2005
+++ b/tools/pygrub/Makefile     Sat Oct  8 20:28:24 2005
@@ -15,4 +15,4 @@
 endif
 
 clean:
-       rm -rf build *.pyc *.pyo *.o *.a *~
+       rm -rf build tmp *.pyc *.pyo *.o *.a *~
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/pygrub/setup.py
--- a/tools/pygrub/setup.py     Sat Oct  8 17:37:45 2005
+++ b/tools/pygrub/setup.py     Sat Oct  8 20:28:24 2005
@@ -1,5 +1,7 @@
 from distutils.core import setup, Extension
+from distutils.ccompiler import new_compiler
 import os
+import sys
 
 extra_compile_args  = [ "-fno-strict-aliasing", "-Wall", "-Werror" ]
 
@@ -7,9 +9,19 @@
 fsys_pkgs = []
 
 if os.path.exists("/usr/include/ext2fs/ext2_fs.h"):
+    ext2defines = []
+    cc = new_compiler()
+    cc.add_library("ext2fs")
+    if cc.has_function("ext2fs_open2"):
+        ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) )
+    else:
+        sys.stderr.write("WARNING: older version of e2fsprogs installed, not 
building full\n")
+        sys.stderr.write("         disk support for ext2.\n")
+        
     ext2 = Extension("grub.fsys.ext2._pyext2",
                      extra_compile_args = extra_compile_args,
                      libraries = ["ext2fs"],
+                     define_macros = ext2defines,
                      sources = ["src/fsys/ext2/ext2module.c"])
     fsys_mods.append(ext2)
     fsys_pkgs.append("grub.fsys.ext2")
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/pygrub/src/fsys/ext2/ext2module.c
--- a/tools/pygrub/src/fsys/ext2/ext2module.c   Sat Oct  8 17:37:45 2005
+++ b/tools/pygrub/src/fsys/ext2/ext2module.c   Sat Oct  8 20:28:24 2005
@@ -229,8 +229,13 @@
         snprintf(offsetopt, 29, "offset=%d", offset);
     }
 
+#ifdef HAVE_EXT2FS_OPEN2
     err = ext2fs_open2(name, offsetopt, flags, superblock, block_size, 
                        unix_io_manager, &efs);
+#else
+    err = ext2fs_open(name, flags, superblock, block_size,
+                      unix_io_manager, &efs);
+#endif
     if (err) {
         PyErr_SetString(PyExc_ValueError, "unable to open file");
         return NULL;
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/Makefile
--- a/tools/python/Makefile     Sat Oct  8 17:37:45 2005
+++ b/tools/python/Makefile     Sat Oct  8 20:28:24 2005
@@ -15,5 +15,8 @@
        CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)"
 endif
 
+test:
+       export LD_LIBRARY_PATH=$$(readlink -f ../libxc):$$(readlink -f 
../xenstore); python test.py -b -u
+
 clean:
        rm -rf build *.pyc *.pyo *.o *.a *~
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/setup.py
--- a/tools/python/setup.py     Sat Oct  8 17:37:45 2005
+++ b/tools/python/setup.py     Sat Oct  8 20:28:24 2005
@@ -42,7 +42,9 @@
                          'xen.xend.xenstore',
                          'xen.xm',
                          'xen.web',
-                         'xen.sv'
+                         'xen.sv',
+
+                         'xen.xend.tests'
                          ],
       ext_package = "xen.lowlevel",
       ext_modules = [ xc, xs ]
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Sat Oct  8 20:28:24 2005
@@ -432,104 +432,19 @@
 {
     XcObject *xc = (XcObject *)self;
 
-    u32 dom;
-    int port = 0;
-
-    static char *kwd_list[] = { "dom", "port", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
-                                      &dom, &port) )
-        return NULL;
-
-    if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
+    u32 dom, remote_dom;
+    int port;
+
+    static char *kwd_list[] = { "dom", "remote_dom", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
+                                      &dom, &remote_dom) )
+        return NULL;
+
+    if ( (port = xc_evtchn_alloc_unbound(xc->xc_handle, dom, remote_dom)) < 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return PyInt_FromLong(port);
-}
-
-static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self,
-                                              PyObject *args,
-                                              PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    u32 dom1 = DOMID_SELF, dom2 = DOMID_SELF;
-    int port1 = 0, port2 = 0;
-
-    static char *kwd_list[] = { "dom1", "dom2", "port1", "port2", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiii", kwd_list, 
-                                      &dom1, &dom2, &port1, &port2) )
-        return NULL;
-
-    if ( xc_evtchn_bind_interdomain(xc->xc_handle, dom1, 
-                                    dom2, &port1, &port2) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    return Py_BuildValue("{s:i,s:i}", 
-                         "port1", port1,
-                         "port2", port2);
-}
-
-static PyObject *pyxc_evtchn_bind_virq(PyObject *self,
-                                       PyObject *args,
-                                       PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    int virq, port;
-
-    static char *kwd_list[] = { "virq", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &virq) )
-        return NULL;
-
-    if ( xc_evtchn_bind_virq(xc->xc_handle, virq, &port) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    return PyInt_FromLong(port);
-}
-
-static PyObject *pyxc_evtchn_close(PyObject *self,
-                                   PyObject *args,
-                                   PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    u32 dom = DOMID_SELF;
-    int port;
-
-    static char *kwd_list[] = { "port", "dom", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
-                                      &port, &dom) )
-        return NULL;
-
-    if ( xc_evtchn_close(xc->xc_handle, dom, port) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_evtchn_send(PyObject *self,
-                                  PyObject *args,
-                                  PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    int port;
-
-    static char *kwd_list[] = { "port", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) )
-        return NULL;
-
-    if ( xc_evtchn_send(xc->xc_handle, port) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    Py_INCREF(zero);
-    return zero;
 }
 
 static PyObject *pyxc_evtchn_status(PyObject *self,
@@ -1028,41 +943,10 @@
     { "evtchn_alloc_unbound", 
       (PyCFunction)pyxc_evtchn_alloc_unbound,
       METH_VARARGS | METH_KEYWORDS, "\n"
-      "Allocate an unbound local port that will await a remote connection.\n"
-      " dom [int]: Remote domain to accept connections from.\n\n"
+      "Allocate an unbound port that will await a remote connection.\n"
+      " dom        [int]: Domain whose port space to allocate from.\n"
+      " remote_dom [int]: Remote domain to accept connections from.\n\n"
       "Returns: [int] Unbound event-channel port.\n" },
-
-    { "evtchn_bind_interdomain", 
-      (PyCFunction)pyxc_evtchn_bind_interdomain, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
-      "Open an event channel between two domains.\n"
-      " dom1 [int, SELF]: First domain to be connected.\n"
-      " dom2 [int, SELF]: Second domain to be connected.\n\n"
-      "Returns: [dict] dictionary is empty on failure.\n"
-      " port1 [int]: Port-id for endpoint at dom1.\n"
-      " port2 [int]: Port-id for endpoint at dom2.\n" },
-
-    { "evtchn_bind_virq", 
-      (PyCFunction)pyxc_evtchn_bind_virq, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
-      "Bind an event channel to the specified VIRQ.\n"
-      " virq [int]: VIRQ to bind.\n\n"
-      "Returns: [int] Bound event-channel port.\n" },
-
-    { "evtchn_close", 
-      (PyCFunction)pyxc_evtchn_close, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
-      "Close an event channel. If interdomain, sets remote end to 'unbound'.\n"
-      " dom  [int, SELF]: Dom-id of one endpoint of the channel.\n"
-      " port [int]:       Port-id of one endpoint of the channel.\n\n"
-      "Returns: [int] 0 on success; -1 on error.\n" },
-
-    { "evtchn_send", 
-      (PyCFunction)pyxc_evtchn_send, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
-      "Send an event along a locally-connected event channel.\n"
-      " port [int]: Port-id of a local channel endpoint.\n\n"
-      "Returns: [int] 0 on success; -1 on error.\n" },
 
     { "evtchn_status", 
       (PyCFunction)pyxc_evtchn_status, 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/lowlevel/xs/xs.c Sat Oct  8 20:28:24 2005
@@ -462,19 +462,20 @@
     char **xsval = NULL;
     PyObject *token;
     int i;
+    unsigned int num;
 
     if (!xh)
         goto exit;
     if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
         goto exit;
     Py_BEGIN_ALLOW_THREADS
-    xsval = xs_read_watch(xh);
-    Py_END_ALLOW_THREADS
-    if (!xsval) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
-        goto exit;
-    }
-    if (sscanf(xsval[1], "%li", (unsigned long *)&token) != 1) {
+    xsval = xs_read_watch(xh, &num);
+    Py_END_ALLOW_THREADS
+    if (!xsval) {
+        PyErr_SetFromErrno(PyExc_RuntimeError);
+        goto exit;
+    }
+    if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) {
         PyErr_SetString(PyExc_RuntimeError, "invalid token");
         goto exit;
     }
@@ -487,7 +488,7 @@
         goto exit;
     }
     /* Create tuple (path, token). */
-    val = Py_BuildValue("(sO)", xsval[0], token);
+    val = Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token);
  exit:
     if (xsval)
         free(xsval);
@@ -774,39 +775,6 @@
     return val;
 }
 
-#define xspy_shutdown_doc "\n"                 \
-       "Shutdown the xenstore daemon.\n"       \
-       "\n"                                    \
-       "Returns None on success.\n"            \
-       "Raises RuntimeError on error.\n"       \
-       "\n"
-
-static PyObject *xspy_shutdown(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwd_spec[] = { NULL };
-    static char *arg_spec = "";
-
-    struct xs_handle *xh = xshandle(self);
-    PyObject *val = NULL;
-    int xsval = 0;
-
-    if (!xh)
-        goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_shutdown(xh);
-    Py_END_ALLOW_THREADS
-    if (!xsval) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
-        goto exit;
-    }
-    Py_INCREF(Py_None);
-    val = Py_None;
- exit:
-    return val;
-}
-
 #define xspy_get_domain_path_doc "\n"                  \
        "Return store path of domain.\n"                \
        " domid [int]: domain id\n"                     \
@@ -845,28 +813,6 @@
     }
     val = PyString_FromString(xsval);
     free(xsval);
- exit:
-    return val;
-}
-
-#define xspy_fileno_doc "\n"                                   \
-       "Get the file descriptor of the xenstore socket.\n"     \
-       "Allows an xs object to be passed to select().\n"       \
-       "\n"                                                    \
-       "Returns: [int] file descriptor.\n"                     \
-       "\n"
-
-static PyObject *xspy_fileno(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwd_spec[] = { NULL };
-    static char *arg_spec = "";
-
-    struct xs_handle *xh = xshandle(self);
-    PyObject *val = NULL;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
-        goto exit;
-    val = PyInt_FromLong((xh ? xs_fileno(xh) : -1));
  exit:
     return val;
 }
@@ -894,9 +840,7 @@
      XSPY_METH(introduce_domain),
      XSPY_METH(release_domain),
      XSPY_METH(close),
-     XSPY_METH(shutdown),
      XSPY_METH(get_domain_path),
-     XSPY_METH(fileno),
      { /* Terminator. */ },
 };
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/sv/DomInfo.py
--- a/tools/python/xen/sv/DomInfo.py    Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/sv/DomInfo.py    Sat Oct  8 20:28:24 2005
@@ -139,7 +139,7 @@
         if not dom is None and dom != '0':
           if DEBUG: print ">DomShutDown %s" % dom
            try:
-               server.xend_domain_shutdown( int( dom ), "halt" )
+               server.xend_domain_shutdown( int( dom ), "poweroff" )
            except:
                pass
     
@@ -175,7 +175,7 @@
         if not dom is None and dom != '0':
           if DEBUG: print ">DomDestroy %s" % dom
            try:
-               server.xend_domain_destroy( int( dom ), "halt" )
+               server.xend_domain_destroy(int( dom ))
            except:
                pass
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/web/http.py
--- a/tools/python/xen/web/http.py      Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/web/http.py      Sat Oct  8 20:28:24 2005
@@ -437,6 +437,9 @@
         send_body = self.hasBody()
         if not self.close_connection:
             self.setResponseHeader("Connection", "keep-alive")
+        self.setResponseHeader("Pragma", "no-cache")
+        self.setResponseHeader("Cache-Control", "no-cache")
+        self.setResponseHeader("Expires", "-1")
         if send_body:
             self.output.seek(0, 0)
             body = self.output.getvalue()
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Sat Oct  8 20:28:24 2005
@@ -1,4 +1,5 @@
 # Copyright (C) 2005 Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 
 # This file is subject to the terms and conditions of the GNU General
 # Public License.  See the file "COPYING" in the main directory of
@@ -7,15 +8,14 @@
 import os
 import re
 import select
+import string
 import sxp
-from string import join
 from struct import pack, unpack, calcsize
 
 from xen.util.xpopen import xPopen3
 
 import xen.lowlevel.xc
 
-import XendDomainInfo
 from xen.xend.xenstore.xsutil import IntroduceDomain
 
 from XendError import XendError
@@ -42,57 +42,55 @@
         raise XendError(errmsg)
     return buf
 
-def save(xd, fd, dominfo, live):
+def save(fd, dominfo, live):
     write_exact(fd, SIGNATURE, "could not write guest state file: signature")
 
     config = sxp.to_string(dominfo.sxpr())
-    write_exact(fd, pack("!i", len(config)),
-                "could not write guest state file: config len")
-    write_exact(fd, config, "could not write guest state file: config")
-
-    # xc_save takes three customization parameters: maxit, max_f, and flags
-    # the last controls whether or not save is 'live', while the first two
-    # further customize behaviour when 'live' save is enabled. Passing "0"
-    # simply uses the defaults compiled into libxenguest; see the comments 
-    # and/or code in xc_linux_save() for more information. 
-    cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
-           str(dominfo.domid), "0", "0", str(int(live)) ]
-    log.info("[xc_save] " + join(cmd))
-    child = xPopen3(cmd, True, -1, [fd, xc.handle()])
-    
-    lasterr = ""
-    p = select.poll()
-    p.register(child.fromchild.fileno())
-    p.register(child.childerr.fileno())
-    while True: 
-        r = p.poll()
-        for (fd, event) in r:
-            if not event & select.POLLIN:
-                continue
-            if fd == child.childerr.fileno():
-                l = child.childerr.readline()
-                log.error(l.rstrip())
-                lasterr = l.rstrip()
-            if fd == child.fromchild.fileno():
-                l = child.fromchild.readline()
-                if l.rstrip() == "suspend":
-                    log.info("suspending %d" % dominfo.domid)
-                    xd.domain_shutdown(dominfo.domid, reason='suspend')
-                    dominfo.state_wait(XendDomainInfo.STATE_VM_SUSPENDED)
-                    log.info("suspend %d done" % dominfo.domid)
-                    child.tochild.write("done\n")
-                    child.tochild.flush()
-        if filter(lambda (fd, event): event & select.POLLHUP, r):
-            break
-
-    if child.wait() >> 8 == 127:
-        lasterr = "popen %s failed" % PATH_XC_SAVE
-    if child.wait() != 0:
-        raise XendError("xc_save failed: %s" % lasterr)
-
-    dominfo.closeStoreChannel()
-    xd.domain_destroy(dominfo.domid)
-    return None
+
+    domain_name = dominfo.getName()
+    # Rename the domain temporarily, so that we don't get a name clash if this
+    # domain is migrating (live or non-live) to the local host.  Doing such a
+    # thing is useful for debugging.
+    dominfo.setName('migrating-' + domain_name)
+
+    try:
+        write_exact(fd, pack("!i", len(config)),
+                    "could not write guest state file: config len")
+        write_exact(fd, config, "could not write guest state file: config")
+
+        # xc_save takes three customization parameters: maxit, max_f, and
+        # flags the last controls whether or not save is 'live', while the
+        # first two further customize behaviour when 'live' save is
+        # enabled. Passing "0" simply uses the defaults compiled into
+        # libxenguest; see the comments and/or code in xc_linux_save() for
+        # more information.
+        cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
+               str(dominfo.getDomid()), "0", "0", str(int(live)) ]
+        log.debug("[xc_save]: %s", string.join(cmd))
+
+        def saveInputHandler(line, tochild):
+            log.debug("In saveInputHandler %s", line)
+            if line == "suspend":
+                log.debug("Suspending %d ...", dominfo.getDomid())
+                dominfo.shutdown('suspend')
+                dominfo.waitForShutdown()
+                log.info("Domain %d suspended.", dominfo.getDomid())
+                tochild.write("done\n")
+                tochild.flush()
+
+        forkHelper(cmd, fd, saveInputHandler, False)
+
+        dominfo.destroyDomain()
+
+    except Exception, exn:
+        log.exception("Save failed on domain %s (%d).", domain_name,
+                      dominfo.getDomid())
+        try:
+            dominfo.setName(domain_name)
+        except:
+            log.exception("Failed to reset the migrating domain's name")
+        raise Exception, exn
+
 
 def restore(xd, fd):
     signature = read_exact(fd, len(SIGNATURE),
@@ -113,71 +111,98 @@
         raise XendError("not a valid guest state file: config parse")
 
     vmconfig = p.get_val()
-    dominfo = xd.domain_configure(vmconfig)
-
-    l = read_exact(fd, sizeof_unsigned_long,
-                   "not a valid guest state file: pfn count read")
-    nr_pfns = unpack("=L", l)[0]   # XXX endianess
-    if nr_pfns > 1024*1024:     # XXX
-        raise XendError(
-            "not a valid guest state file: pfn count out of range")
-
-    if dominfo.store_channel:
-        store_evtchn = dominfo.store_channel.port2
-    else:
-        store_evtchn = 0
-
-    if dominfo.console_channel:
-        console_evtchn = dominfo.console_channel.port2
-    else:
-        console_evtchn = 0
-
-    cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
-           str(dominfo.domid), str(nr_pfns),
-           str(store_evtchn), str(console_evtchn)]
-    log.info("[xc_restore] " + join(cmd))
+
+    dominfo = xd.restore_(vmconfig)
+
+    assert dominfo.store_channel
+    assert dominfo.console_channel
+    assert dominfo.getDomainPath()
+
+    try:
+        l = read_exact(fd, sizeof_unsigned_long,
+                       "not a valid guest state file: pfn count read")
+        nr_pfns = unpack("=L", l)[0]   # XXX endianess
+        if nr_pfns > 1024*1024:     # XXX
+            raise XendError(
+                "not a valid guest state file: pfn count out of range")
+
+        store_evtchn = dominfo.store_channel
+        console_evtchn = dominfo.console_channel
+
+        cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
+               str(dominfo.getDomid()), str(nr_pfns),
+               str(store_evtchn), str(console_evtchn)]
+        log.debug("[xc_restore]: %s", string.join(cmd))
+
+        def restoreInputHandler(line, _):
+            m = re.match(r"^(store-mfn) (\d+)$", line)
+            if m:
+                store_mfn = int(m.group(2))
+                dominfo.setStoreRef(store_mfn)
+                log.debug("IntroduceDomain %d %d %d %s",
+                          dominfo.getDomid(),
+                          store_mfn,
+                          dominfo.store_channel,
+                          dominfo.getDomainPath())
+                IntroduceDomain(dominfo.getDomid(),
+                                store_mfn,
+                                dominfo.store_channel,
+                                dominfo.getDomainPath())
+            else:
+                m = re.match(r"^(console-mfn) (\d+)$", line)
+                if m:
+                    dominfo.setConsoleRef(int(m.group(2)))
+
+        forkHelper(cmd, fd, restoreInputHandler, True)
+
+        return dominfo
+    except:
+        dominfo.destroy()
+        raise
+
+
+def forkHelper(cmd, fd, inputHandler, closeToChild):
     child = xPopen3(cmd, True, -1, [fd, xc.handle()])
-    child.tochild.close()
-
-    lasterr = ""
-    p = select.poll()
-    p.register(child.fromchild.fileno())
-    p.register(child.childerr.fileno())
-    while True:
-        r = p.poll()
-        for (fd, event) in r:
-            if not event & select.POLLIN:
-                continue
-            if fd == child.childerr.fileno():
-                l = child.childerr.readline()
-                log.error(l.rstrip())
-                lasterr = l.rstrip()
-            if fd == child.fromchild.fileno():
-                l = child.fromchild.readline()
-                while l:
-                    log.info(l.rstrip())
-                    m = re.match(r"^(store-mfn) (\d+)\n$", l)
-                    if m:
-                        if dominfo.store_channel:
-                            dominfo.setStoreRef(int(m.group(2)))
-                            if dominfo.store_mfn >= 0:
-                                IntroduceDomain(dominfo.domid,
-                                                dominfo.store_mfn,
-                                                dominfo.store_channel.port1,
-                                                dominfo.path)
-                    m = re.match(r"^(console-mfn) (\d+)\n$", l)
-                    if m:
-                        dominfo.setConsoleRef(int(m.group(2)))
-                    try:
-                        l = child.fromchild.readline()
-                    except:
-                        l = None
-        if filter(lambda (fd, event): event & select.POLLHUP, r):
-            break
+
+    if closeToChild:
+        child.tochild.close()
+
+    try:
+        fds = [child.fromchild.fileno(),
+               child.childerr.fileno()]
+        p = select.poll()
+        map(p.register, fds)
+        while len(fds) > 0:
+            r = p.poll()
+            for (fd, event) in r:
+                if event & select.POLLIN:
+                    if fd == child.childerr.fileno():
+                        lasterr = child.childerr.readline().rstrip()
+                        log.error('%s', lasterr)
+                    else:
+                        l = child.fromchild.readline().rstrip()
+                        while l:
+                            log.debug('%s', l)
+                            inputHandler(l, child.tochild)
+                            try:
+                                l = child.fromchild.readline().rstrip()
+                            except:
+                                l = None
+
+                if event & select.POLLERR:
+                    raise XendError('Error reading from child process for %s',
+                                    cmd)
+
+                if event & select.POLLHUP:
+                    fds.remove(fd)
+                    p.unregister(fd)
+    finally:
+        child.fromchild.close()
+        child.childerr.close()
+        if not closeToChild:
+            child.tochild.close()
 
     if child.wait() >> 8 == 127:
-        lasterr = "popen %s failed" % PATH_XC_RESTORE
+        lasterr = "popen failed"
     if child.wait() != 0:
-        raise XendError("xc_restore failed: %s" % lasterr)
-
-    return dominfo
+        raise XendError("%s failed: %s" % (string.join(cmd), lasterr))
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/XendClient.py       Sat Oct  8 20:28:24 2005
@@ -232,10 +232,9 @@
                              {'op'      : 'sysrq',
                               'key'     : key})
 
-    def xend_domain_destroy(self, id, reason):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'destroy',
-                              'reason'  : reason })
+    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),
@@ -307,22 +306,22 @@
                              {'op'      : 'device_create',
                               'config'  : fileof(config) })
 
-    def xend_domain_device_refresh(self, id, type, idx):
+    def xend_domain_device_refresh(self, id, type, dev):
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'device_refresh',
                               'type'    : type,
-                              'idx'     : idx })
-
-    def xend_domain_device_destroy(self, id, type, idx):
+                              'dev'     : dev })
+
+    def xend_domain_device_destroy(self, id, type, dev):
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'device_destroy',
                               'type'    : type,
-                              'idx'     : idx })
-
-    def xend_domain_device_configure(self, id, config, idx):
+                              'dev'     : dev })
+
+    def xend_domain_device_configure(self, id, config, dev):
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'device_configure',
-                              'idx'     : idx,
+                              'dev'     : dev,
                               'config'  : fileof(config) })
 
     def xend_vnets(self):
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/XendDomain.py       Sat Oct  8 20:28:24 2005
@@ -22,14 +22,15 @@
  Needs to be persistent for one uptime.
 """
 import os
+import logging
+import threading
 
 import xen.lowlevel.xc
 
-from xen.xend import sxp
+import XendDomainInfo
+
 from xen.xend import XendRoot
 from xen.xend import XendCheckpoint
-from xen.xend.XendDomainInfo import XendDomainInfo
-from xen.xend import EventServer
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
 from xen.xend.server import relocate
@@ -37,26 +38,17 @@
 
 xc = xen.lowlevel.xc.new()
 xroot = XendRoot.instance()
-eserver = EventServer.instance()
 
 
 __all__ = [ "XendDomain" ]
 
 PRIV_DOMAIN = 0
-
-class XendDomainDict(dict):
-    def get_by_name(self, name):
-        try:
-            return filter(lambda d: d.getName() == name, self.values())[0]
-        except IndexError, err:
-            return None
 
 class XendDomain:
     """Index of all domains. Singleton.
     """
 
-    """Dict of domain info indexed by domain id."""
-    domains = None
+    ## public:
     
     def __init__(self):
         # Hack alert. Python does not support mutual imports, but 
XendDomainInfo
@@ -64,18 +56,30 @@
         # to import XendDomain from XendDomainInfo causes unbounded recursion.
         # So we stuff the XendDomain instance (self) into xroot's components.
         xroot.add_component("xen.xend.XendDomain", self)
-        self.domains = XendDomainDict()
+        self.domains = {}
+        self.domains_lock = threading.Condition()
         self.watchReleaseDomain()
-        self.refresh()
-        self.dom0_setup()
+
+        self.domains_lock.acquire()
+        try:
+            self.refresh(True)
+            self.dom0_setup()
+        finally:
+            self.domains_lock.release()
+
 
     def list(self):
         """Get list of domain objects.
 
         @return: domain objects
         """
-        self.refresh()
-        return self.domains.values()
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domains.values()
+        finally:
+            self.domains_lock.release()
+
 
     def list_sorted(self):
         """Get list of domain objects, sorted by name.
@@ -94,15 +98,25 @@
         doms = self.list_sorted()
         return map(lambda x: x.getName(), doms)
 
+
+    ## private:
+
     def onReleaseDomain(self):
-        self.refresh()
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+        finally:
+            self.domains_lock.release()
+            
 
     def watchReleaseDomain(self):
         from xen.xend.xenstore.xswatch import xswatch
         self.releaseDomain = xswatch("@releaseDomain", self.onReleaseDomain)
 
+
     def xen_domains(self):
-        """Get table of domains indexed by id from xc.
+        """Get table of domains indexed by id from xc.  Expects to be
+        protected by the domains_lock.
         """
         domlist = xc.domain_getinfo()
         doms = {}
@@ -111,68 +125,37 @@
             doms[domid] = d
         return doms
 
-    def xen_domain(self, dom):
-        """Get info about a single domain from xc.
-        Returns None if not found.
-
-        @param dom domain id (int)
-        """
-        dominfo = xc.domain_getinfo(dom, 1)
-        if dominfo == [] or dominfo[0]['dom'] != dom:
-            dominfo = None
-        else:
-            dominfo = dominfo[0]
-        return dominfo
-
-
-    def recreate_domain(self, xeninfo):
-        """Refresh initial domain info from db."""
-
-        dominfo = XendDomainInfo.recreate(xeninfo)
-        self._add_domain(dominfo)
-        return dominfo
-
 
     def dom0_setup(self):
-        dom0 = self.domain_lookup(PRIV_DOMAIN)
-        if not dom0:
-            dom0 = self.recreate_domain(self.xen_domain(PRIV_DOMAIN))
-        dom0.dom0_init_store()
+        """Expects to be protected by the domains_lock."""
+        dom0 = self.domains[PRIV_DOMAIN]
         dom0.dom0_enforce_vcpus()
 
 
-    def _add_domain(self, info, notify=True):
-        """Add a domain entry to the tables.
-
-        @param info:   domain info object
-        @param notify: send a domain created event if true
-        """
-        if info.getDomid() in self.domains:
-            notify = False
+    def _add_domain(self, info):
+        """Add the given domain entry to this instance's internal cache.
+        Expects to be protected by the domains_lock.
+        """
         self.domains[info.getDomid()] = info
-        info.exportToDB()
-        if notify:
-            eserver.inject('xend.domain.create', [info.getName(),
-                                                  info.getDomid()])
-
-    def _delete_domain(self, domid, notify=True):
-        """Remove a domain from the tables.
-
-        @param id:     domain id
-        @param notify: send a domain died event if true
+
+
+    def _delete_domain(self, domid):
+        """Remove the given domain from this instance's internal cache.
+        Expects to be protected by the domains_lock.
         """
         info = self.domains.get(domid)
         if info:
             del self.domains[domid]
-            info.cleanup()
-            info.delete()
-            if notify:
-                eserver.inject('xend.domain.died', [info.getName(),
-                                                    info.getDomid()])
-
-
-    def refresh(self):
-        """Refresh domain list from Xen.
+            info.cleanupDomain()
+
+
+    def refresh(self, initialising = False):
+        """Refresh domain list from Xen.  Expects to be protected by the
+        domains_lock.
+
+        @param initialising True if this is the first refresh after starting
+        Xend.  This does not change this method's behaviour, except for
+        logging.
         """
         doms = self.xen_domains()
         for d in self.domains.values():
@@ -183,30 +166,33 @@
                 self._delete_domain(d.getDomid())
         for d in doms:
             if d not in self.domains:
-                try:
-                    self.recreate_domain(doms[d])
-                except:
-                    log.exception(
-                        "Failed to recreate information for domain %d.  "
-                        "Destroying it in the hope of recovery.", d)
+                if doms[d]['dying']:
+                    log.log(initialising and logging.ERROR or logging.DEBUG,
+                            'Cannot recreate information for dying domain %d.'
+                            '  Xend will ignore this domain from now on.',
+                            doms[d]['dom'])
+                else:
                     try:
-                        xc.domain_destroy(dom = d)
+                        dominfo = XendDomainInfo.recreate(doms[d])
+                        self._add_domain(dominfo)
                     except:
-                        log.exception('Destruction of %d failed.', d)
-
-
-    def update_domain(self, id):
-        """Update information for a single domain.
-
-        @param id: domain id
-        """
-        dominfo = self.xen_domain(id)
-        if dominfo:
-            d = self.domains.get(id)
-            if d:
-                d.update(dominfo)
-        else:
-            self._delete_domain(id)
+                        if d == PRIV_DOMAIN:
+                            log.exception(
+                                "Failed to recreate information for domain "
+                                "%d.  Doing nothing except crossing my "
+                                "fingers.", d)
+                        else:
+                            log.exception(
+                                "Failed to recreate information for domain "
+                                "%d.  Destroying it in the hope of "
+                                "recovery.", d)
+                            try:
+                                xc.domain_destroy(dom = d)
+                            except:
+                                log.exception('Destruction of %d failed.', d)
+
+
+    ## public:
 
     def domain_create(self, config):
         """Create a domain from a configuration.
@@ -214,24 +200,22 @@
         @param config: configuration
         @return: domain
         """
-        dominfo = XendDomainInfo.create(config)
-        self._add_domain(dominfo)
-        return dominfo
+        self.domains_lock.acquire()
+        try:
+            dominfo = XendDomainInfo.create(config)
+            self._add_domain(dominfo)
+            return dominfo
+        finally:
+            self.domains_lock.release()
+
 
     def domain_configure(self, config):
-        """Configure an existing domain. This is intended for internal
-        use by domain restore and migrate.
+        """Configure an existing domain.
 
         @param vmconfig: vm configuration
         """
-        # We accept our configuration specified as ['config' [...]], which
-        # some tools or configuration files may be using.  For save-restore,
-        # we use the value of XendDomainInfo.sxpr() directly, which has no
-        # such item.
-        nested = sxp.child_value(config, 'config')
-        if nested:
-            config = nested
-        return XendDomainInfo.restore(config)
+        # !!!
+        raise XendError("Unsupported")
 
     def domain_restore(self, src):
         """Restore a domain from file.
@@ -241,89 +225,156 @@
 
         try:
             fd = os.open(src, os.O_RDONLY)
-            dominfo = XendCheckpoint.restore(self, fd)
-            self._add_domain(dominfo)
-            return dominfo
+            try:
+                return self.domain_restore_fd(fd)
+            finally:
+                os.close(fd)
         except OSError, ex:
             raise XendError("can't read guest state file %s: %s" %
                             (src, ex[1]))
 
-    def domain_get(self, id):
-        """Get up-to-date info about a domain.
-
-        @param id: domain id
-        @return: domain object (or None)
-        """
-        self.update_domain(id)
-        return self.domains.get(id)
-
-
-    def domain_lookup(self, id):
-        return self.domains.get(id)
-
-    def domain_lookup_by_name(self, name):
-        dominfo = self.domains.get_by_name(name)
-        if not dominfo:
-            try:
-                id = int(name)
-                dominfo = self.domain_lookup(id)
-            except ValueError:
-                pass
-        return dominfo
-
-    def domain_unpause(self, id):
-        """Unpause domain execution.
-
-        @param id: domain id
-        """
-        dominfo = self.domain_lookup(id)
-        eserver.inject('xend.domain.unpause', [dominfo.getName(),
-                                               dominfo.getDomid()])
-        try:
+    def domain_restore_fd(self, fd):
+        """Restore a domain from the given file descriptor."""
+
+        try:
+            return XendCheckpoint.restore(self, fd)
+        except:
+            # I don't really want to log this exception here, but the error
+            # handling in the relocation-socket handling code (relocate.py) is
+            # poor, so we need to log this for debugging.
+            log.exception("Restore failed")
+            raise
+
+
+    def restore_(self, config):
+        """Create a domain as part of the restore process.  This is called
+        only from {@link XendCheckpoint}.
+
+        A restore request comes into XendDomain through {@link
+        #domain_restore} or {@link #domain_restore_fd}.  That request is
+        forwarded immediately to XendCheckpoint which, when it is ready, will
+        call this method.  It is necessary to come through here rather than go
+        directly to {@link XendDomainInfo.restore} because we need to
+        serialise the domain creation process, but cannot lock
+        domain_restore_fd as a whole, otherwise we will deadlock waiting for
+        the old domain to die.
+        """
+        self.domains_lock.acquire()
+        try:
+            dominfo = XendDomainInfo.restore(config)
+            self._add_domain(dominfo)
+            return dominfo
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup(self, domid):
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domains.get(domid)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_nr(self, domid):
+        self.domains_lock.acquire()
+        try:
+            return self.domains.get(domid)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_or_id(self, name):
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domain_lookup_by_name_or_id_nr(name)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_or_id_nr(self, name):
+        self.domains_lock.acquire()
+        try:
+            dominfo = self.domain_lookup_by_name_nr(name)
+
+            if dominfo:
+                return dominfo
+            else:
+                try:
+                    return self.domains.get(int(name))
+                except ValueError:
+                    return None
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_nr(self, name):
+        self.domains_lock.acquire()
+        try:
+            matching = filter(lambda d: d.getName() == name,
+                              self.domains.values())
+            n = len(matching)
+            if n == 1:
+                return matching[0]
+            elif n > 1:
+                log.error('Name uniqueness has been violated for name %s!  '
+                          'Recovering by renaming:', name)
+                for d in matching:
+                    d.renameUniquely()
+
+            return None
+        finally:
+            self.domains_lock.release()
+
+
+    def privilegedDomain(self):
+        self.domains_lock.acquire()
+        try:
+            return self.domains[PRIV_DOMAIN]
+        finally:
+            self.domains_lock.release()
+
+ 
+    def domain_unpause(self, domid):
+        """Unpause domain execution."""
+        try:
+            dominfo = self.domain_lookup(domid)
+            log.info("Domain %s (%d) unpaused.", dominfo.getName(),
+                     dominfo.getDomid())
             return xc.domain_unpause(dom=dominfo.getDomid())
         except Exception, ex:
             raise XendError(str(ex))
-    
-    def domain_pause(self, id):
-        """Pause domain execution.
-
-        @param id: domain id
-        """
-        dominfo = self.domain_lookup(id)
-        eserver.inject('xend.domain.pause', [dominfo.getName(),
-                                             dominfo.getDomid()])
-        try:
+
+
+    def domain_pause(self, domid):
+        """Pause domain execution."""
+        try:
+            dominfo = self.domain_lookup(domid)
+            log.info("Domain %s (%d) paused.", dominfo.getName(),
+                     dominfo.getDomid())
             return xc.domain_pause(dom=dominfo.getDomid())
         except Exception, ex:
             raise XendError(str(ex))
 
 
-    def domain_shutdown(self, domid, reason='poweroff'):
+    def domain_shutdown(self, domid, reason = 'poweroff'):
         """Shutdown domain (nicely).
-         - poweroff: restart according to exit code and restart mode
-         - reboot:   restart on exit
-         - halt:     do not restart
-
-         Returns immediately.
-
-        @param id:     domain id
-        @param reason: shutdown type: poweroff, reboot, suspend, halt
-        """
-        self.callInfo(domid, XendDomainInfo.shutdown, reason)
+
+        @param reason: shutdown reason: poweroff, reboot, suspend, halt
+        """
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason)
 
 
     def domain_sysrq(self, domid, key):
         """Send a SysRq to the specified domain."""
-        return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
-
-
-    def domain_destroy(self, domid, reason='halt'):
-        """Terminate domain immediately.
-        - halt:   cancel any restart for the domain
-        - reboot  schedule a restart for the domain
-
-        @param domid: domain id
-        """
+        return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq,
+                             key)
+
+
+    def domain_destroy(self, domid):
+        """Terminate domain immediately."""
 
         if domid == PRIV_DOMAIN:
             raise XendError("Cannot destroy privileged domain %i" % domid)
@@ -338,68 +389,52 @@
                 raise XendError(str(ex))
         return val       
 
-    def domain_migrate(self, id, dst, live=False, resource=0):
-        """Start domain migration.
-
-        @param id: domain id
-        """
-        # Need a cancel too?
-        # Don't forget to cancel restart for it.
-        dominfo = self.domain_lookup(id)
+    def domain_migrate(self, domid, dst, live=False, resource=0):
+        """Start domain migration."""
+
+        dominfo = self.domain_lookup(domid)
 
         port = xroot.get_xend_relocation_port()
         sock = relocate.setupRelocation(dst, port)
 
-        # temporarily rename domain for localhost migration
-        if dst == "localhost":
-            dominfo.setName("tmp-" + dominfo.getName())
-
-        try:
-            XendCheckpoint.save(self, sock.fileno(), dominfo, live)
-        except:
-            if dst == "localhost":
-                dominfo.setName(
-                    string.replace(dominfo.getName(), "tmp-", "", 1))
-            raise
+        XendCheckpoint.save(sock.fileno(), dominfo, live)
         
-        return None
-
-    def domain_save(self, id, dst):
+
+    def domain_save(self, domid, dst):
         """Start saving a domain to file.
 
-        @param id:       domain id
         @param dst:      destination file
         """
 
         try:
-            dominfo = self.domain_lookup(id)
+            dominfo = self.domain_lookup(domid)
 
             fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
-
-            # For now we don't support 'live checkpoint' 
-            return XendCheckpoint.save(self, fd, dominfo, False)
-
+            try:
+                # For now we don't support 'live checkpoint' 
+                return XendCheckpoint.save(fd, dominfo, False)
+            finally:
+                os.close(fd)
         except OSError, ex:
             raise XendError("can't write guest state file %s: %s" %
                             (dst, ex[1]))
 
-    def domain_pincpu(self, id, vcpu, cpumap):
+    def domain_pincpu(self, domid, vcpu, cpumap):
         """Set which cpus vcpu can use
 
-        @param id:   domain
-        @param vcpu: vcpu number
-        @param cpumap:  bitmap of usbale cpus
-        """
-        dominfo = self.domain_lookup(id)
+        @param cpumap:  bitmap of usable cpus
+        """
+        dominfo = self.domain_lookup(domid)
         try:
             return xc.domain_pincpu(dominfo.getDomid(), vcpu, cpumap)
         except Exception, ex:
             raise XendError(str(ex))
 
-    def domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, 
warpu):
+    def domain_cpu_bvt_set(self, domid, mcuadv, warpback, warpvalue, warpl,
+                           warpu):
         """Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(id)
+        dominfo = self.domain_lookup(domid)
         try:
             return xc.bvtsched_domain_set(dom=dominfo.getDomid(),
                                           mcuadv=mcuadv,
@@ -409,30 +444,31 @@
         except Exception, ex:
             raise XendError(str(ex))
 
-    def domain_cpu_bvt_get(self, id):
+    def domain_cpu_bvt_get(self, domid):
         """Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(id)
+        dominfo = self.domain_lookup(domid)
         try:
             return xc.bvtsched_domain_get(dominfo.getDomid())
         except Exception, ex:
             raise XendError(str(ex))
     
     
-    def domain_cpu_sedf_set(self, id, period, slice, latency, extratime, 
weight):
+    def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
+                            weight):
         """Set Simple EDF scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(id)
-        try:
-            return xc.sedf_domain_set(dominfo.getDomid(), period, slice,
+        dominfo = self.domain_lookup(domid)
+        try:
+            return xc.sedf_domain_set(dominfo.getDomid(), period, slice_,
                                       latency, extratime, weight)
         except Exception, ex:
             raise XendError(str(ex))
 
-    def domain_cpu_sedf_get(self, id):
+    def domain_cpu_sedf_get(self, domid):
         """Get Simple EDF scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(id)
+        dominfo = self.domain_lookup(domid)
         try:
             return xc.sedf_domain_get(dominfo.getDomid())
         except Exception, ex:
@@ -442,63 +478,58 @@
     def domain_device_create(self, domid, devconfig):
         """Create a new device for the specified domain.
         """
-        return self.callInfo(domid, XendDomainInfo.device_create, devconfig)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_create,
+                             devconfig)
 
 
     def domain_device_configure(self, domid, devconfig, devid):
         """Configure an existing device in the specified domain.
         @return: updated device configuration
         """
-        return self.callInfo(domid, XendDomainInfo.device_configure,
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_configure,
                              devconfig, devid)
 
     
-    def domain_device_refresh(self, domid, devtype, devid):
-        """Refresh a device."""
-        return self.callInfo(domid, XendDomainInfo.device_refresh, devtype,
-                             devid)
-
-
     def domain_device_destroy(self, domid, devtype, devid):
         """Destroy a device."""
-        return self.callInfo(domid, XendDomainInfo.destroyDevice, devtype,
-                             devid)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.destroyDevice,
+                             devtype, devid)
 
 
     def domain_devtype_ls(self, domid, devtype):
         """Get list of device sxprs for the specified domain."""
-        return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
-
-
-    def domain_vif_limit_set(self, id, vif, credit, period):
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.getDeviceSxprs,
+                             devtype)
+
+
+    def domain_vif_limit_set(self, domid, vif, credit, period):
         """Limit the vif's transmission rate
         """
-        dominfo = self.domain_lookup(id)
+        dominfo = self.domain_lookup(domid)
         dev = dominfo.getDevice('vif', vif)
         if not dev:
             raise XendError("invalid vif")
         return dev.setCreditLimit(credit, period)
         
-    def domain_shadow_control(self, id, op):
-        """Shadow page control.
-
-        @param id: domain
-        @param op:  operation
-        """
-        dominfo = self.domain_lookup(id)
+    def domain_shadow_control(self, domid, op):
+        """Shadow page control."""
+        dominfo = self.domain_lookup(domid)
         try:
             return xc.shadow_control(dominfo.getDomid(), op)
         except Exception, ex:
             raise XendError(str(ex))
 
-    def domain_maxmem_set(self, id, mem):
+    def domain_maxmem_set(self, domid, mem):
         """Set the memory limit for a domain.
 
-        @param id: domain
         @param mem: memory limit (in MiB)
         @return: 0 on success, -1 on error
         """
-        dominfo = self.domain_lookup(id)
+        dominfo = self.domain_lookup(domid)
         maxmem = int(mem) * 1024
         try:
             return xc.domain_setmaxmem(dominfo.getDomid(),
@@ -511,7 +542,8 @@
 
         @param mem: memory target (in MiB)
         """
-        self.callInfo(domid, XendDomainInfo.setMemoryTarget, mem << 10)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget,
+                      mem << 10)
 
 
     def domain_vcpu_hotplug(self, domid, vcpu, state):
@@ -520,12 +552,13 @@
         @param vcpu: target VCPU in domain
         @param state: which state VCPU will become
         """
-        self.callInfo(domid, XendDomainInfo.vcpu_hotplug, vcpu, state)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu,
+                      state)
 
 
     def domain_dumpcore(self, domid):
         """Save a core dump for a crashed domain."""
-        self.callInfo(domid, XendDomainInfo.dumpCore)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore)
 
 
     ## private:
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Sat Oct  8 20:28:24 2005
@@ -32,8 +32,6 @@
 import xen.lowlevel.xc
 from xen.util.blkif import blkdev_uname_to_file
 
-from xen.xend.server.channel import EventChannel
-
 from xen.xend import image
 from xen.xend import scheduler
 from xen.xend import sxp
@@ -59,27 +57,27 @@
 """Shutdown code for crash."""
 DOMAIN_CRASH    = 3
 
+"""Shutdown code for halt."""
+DOMAIN_HALT     = 4
+
 """Map shutdown codes to strings."""
 shutdown_reasons = {
     DOMAIN_POWEROFF: "poweroff",
     DOMAIN_REBOOT  : "reboot",
     DOMAIN_SUSPEND : "suspend",
     DOMAIN_CRASH   : "crash",
+    DOMAIN_HALT    : "halt"
     }
 
-RESTART_ALWAYS   = 'always'
-RESTART_ONREBOOT = 'onreboot'
-RESTART_NEVER    = 'never'
-
 restart_modes = [
-    RESTART_ALWAYS,
-    RESTART_ONREBOOT,
-    RESTART_NEVER,
+    "restart",
+    "destroy",
+    "preserve",
+    "rename-restart"
     ]
 
 STATE_VM_OK         = "ok"
 STATE_VM_TERMINATED = "terminated"
-STATE_VM_SUSPENDED  = "suspended"
 
 """Flag for a block device backend domain."""
 SIF_BLK_BE_DOMAIN = (1<<4)
@@ -94,9 +92,10 @@
 SHUTDOWN_TIMEOUT = 30
 
 
-DOMROOT = '/domain'
-VMROOT  = '/domain'
-
+DOMROOT = '/local/domain/'
+VMROOT  = '/vm/'
+
+ZOMBIE_PREFIX = 'Zombie-'
 
 xc = xen.lowlevel.xc.new()
 xroot = XendRoot.instance()
@@ -111,15 +110,219 @@
 ROUNDTRIPPING_CONFIG_ENTRIES = [
         ('name',         str),
         ('ssidref',      int),
+        ('vcpus',        int),
+        ('vcpu_avail',   int),
         ('cpu_weight',   float),
-        ('bootloader',   str)
+        ('bootloader',   str),
+        ('on_poweroff',  str),
+        ('on_reboot',    str),
+        ('on_crash',     str)
     ]
 
 
-def domain_exists(name):
+#
+# There are a number of CPU-related fields:
+#
+#   vcpus:       the number of virtual CPUs this domain is configured to use.
+#   vcpu_avail:  a bitmap telling the guest domain whether it may use each of
+#                its VCPUs.  This is translated to
+#                <dompath>/cpu/<id>/availability = {online,offline} for use
+#                by the guest domain.
+#   vcpu_to_cpu: the current mapping between virtual CPUs and the physical
+#                CPU it is using.
+#   cpumap:      a list of bitmaps, one for each VCPU, giving the physical
+#                CPUs that that VCPU may use.
+#   cpu:         a configuration setting requesting that VCPU 0 is pinned to
+#                the specified physical CPU.
+#
+# vcpus and vcpu_avail settings persist with the VM (i.e. they are persistent
+# across save, restore, migrate, and restart).  The other settings are only
+# specific to the domain, so are lost when the VM moves.
+#
+
+
+def create(config):
+    """Create a VM from a configuration.
+
+    @param config    configuration
+    @raise: VmError for invalid configuration
+    """
+
+    log.debug("XendDomainInfo.create(%s)", config)
+
+    vm = XendDomainInfo(getUuid(), parseConfig(config))
+    try:
+        vm.construct()
+        vm.initDomain()
+        vm.construct_image()
+        vm.configure()
+        vm.storeVmDetails()
+        vm.storeDomDetails()
+        vm.refreshShutdown()
+        return vm
+    except:
+        log.exception('Domain construction failed')
+        vm.destroy()
+        raise
+
+
+def recreate(xeninfo):
+    """Create the VM object for an existing domain.  The domain must not
+    be dying, as the paths in the store should already have been removed,
+    and asking us to recreate them causes problems."""
+
+    log.debug("XendDomainInfo.recreate(%s)", xeninfo)
+
+    assert not xeninfo['dying']
+
+    domid = xeninfo['dom']
+    try:
+        dompath = GetDomainPath(domid)
+        if not dompath:
+            raise XendError(
+                'No domain path in store for existing domain %d' % domid)
+        vmpath = xstransact.Read(dompath, "vm")
+        if not vmpath:
+            raise XendError(
+                'No vm path in store for existing domain %d' % domid)
+        uuid = xstransact.Read(vmpath, "uuid")
+        if not uuid:
+            raise XendError(
+                'No vm/uuid path in store for existing domain %d' % domid)
+
+        log.info("Recreating domain %d, UUID %s.", domid, uuid)
+
+        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+
+    except Exception, exn:
+        log.warn(str(exn))
+
+        uuid = getUuid()
+
+        log.info("Recreating domain %d with new UUID %s.", domid, uuid)
+
+        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+        vm.removeDom()
+        vm.storeVmDetails()
+        vm.storeDomDetails()
+
+    vm.create_channel()
+    if domid == 0:
+        vm.initStoreConnection()
+
+    vm.refreshShutdown(xeninfo)
+    return vm
+
+
+def restore(config):
+    """Create a domain and a VM object to do a restore.
+
+    @param config:    domain configuration
+    """
+
+    log.debug("XendDomainInfo.restore(%s)", config)
+
+    try:
+        uuid    =     sxp.child_value(config, 'uuid')
+        ssidref = int(sxp.child_value(config, 'ssidref'))
+    except TypeError, exn:
+        raise VmError('Invalid ssidref in config: %s' % exn)
+
+    vm = XendDomainInfo(uuid, parseConfig(config))
+    try:
+        vm.construct()
+        vm.configure()
+        vm.create_channel()
+        vm.storeVmDetails()
+        vm.storeDomDetails()
+        vm.refreshShutdown()
+        return vm
+    except:
+        vm.destroy()
+        raise
+
+
+def parseConfig(config):
+    def get_cfg(name, conv = None):
+        val = sxp.child_value(config, name)
+
+        if conv and not val is None:
+            try:
+                return conv(val)
+            except TypeError, exn:
+                raise VmError(
+                    'Invalid setting %s = %s in configuration: %s' %
+                    (name, val, str(exn)))
+        else:
+            return val
+
+
+    log.debug("parseConfig: config is %s" % str(config))
+
+    result = {}
+
+    for e in ROUNDTRIPPING_CONFIG_ENTRIES:
+        result[e[0]] = get_cfg(e[0], e[1])
+
+    result['memory']    = get_cfg('memory',    int)
+    result['mem_kb']    = get_cfg('mem_kb',    int)
+    result['maxmem']    = get_cfg('maxmem',    int)
+    result['maxmem_kb'] = get_cfg('maxmem_kb', int)
+    result['cpu']       = get_cfg('cpu',       int)
+    result['image']     = get_cfg('image')
+
+    try:
+        if result['image']:
+            result['vcpus'] = int(sxp.child_value(result['image'],
+                                                  'vcpus', 1))
+        else:
+            result['vcpus'] = 1
+    except TypeError, exn:
+        raise VmError(
+            'Invalid configuration setting: vcpus = %s: %s' %
+            (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
+
+    result['backend'] = []
+    for c in sxp.children(config, 'backend'):
+        result['backend'].append(sxp.name(sxp.child0(c)))
+
+    result['device'] = []
+    for d in sxp.children(config, 'device'):
+        c = sxp.child0(d)
+        result['device'].append((sxp.name(c), c))
+
+    # Configuration option "restart" is deprecated.  Parse it, but
+    # let on_xyz override it if they are present.
+    restart = get_cfg('restart')
+    if restart:
+        def handle_restart(event, val):
+            if not event in result:
+                result[event] = val
+
+        if restart == "onreboot":
+            handle_restart('on_poweroff', 'destroy')
+            handle_restart('on_reboot',   'restart')
+            handle_restart('on_crash',    'destroy')
+        elif restart == "always":
+            handle_restart('on_poweroff', 'restart')
+            handle_restart('on_reboot',   'restart')
+            handle_restart('on_crash',    'restart')
+        elif restart == "never":
+            handle_restart('on_poweroff', 'destroy')
+            handle_restart('on_reboot',   'destroy')
+            handle_restart('on_crash',    'destroy')
+        else:
+            log.warn("Ignoring malformed and deprecated config option "
+                     "restart = %s", restart)
+
+    log.debug("parseConfig: result is %s" % str(result))
+    return result
+
+
+def domain_by_name(name):
     # See comment in XendDomain constructor.
     xd = get_component('xen.xend.XendDomain')
-    return xd.domain_lookup_by_name(name)
+    return xd.domain_lookup_by_name_nr(name)
 
 def shutdown_reason(code):
     """Get a shutdown reason from a code.
@@ -143,7 +346,7 @@
             return domlist[0]
     except Exception, err:
         # ignore missing domain
-        log.exception("domain_getinfo(%d) failed, ignoring", dom)
+        log.debug("domain_getinfo(%d) failed, ignoring: %s", dom, str(err))
     return None
 
 class XendDomainInfo:
@@ -154,155 +357,24 @@
     MINIMUM_RESTART_TIME = 20
 
 
-    def create(cls, config):
-        """Create a VM from a configuration.
-
-        @param config    configuration
-        @raise: VmError for invalid configuration
-        """
-
-        log.debug("XendDomainInfo.create(...)")
-        
-        vm = cls(getUuid(), cls.parseConfig(config))
-        vm.construct()
-        vm.refreshShutdown()
-        return vm
-
-    create = classmethod(create)
-
-
-    def recreate(cls, xeninfo):
-        """Create the VM object for an existing domain."""
-
-        log.debug("XendDomainInfo.recreate(%s)", xeninfo)
-
-        domid = xeninfo['dom']
-        try:
-            dompath = GetDomainPath(domid)
-            if not dompath:
-                raise XendError(
-                    'No domain path in store for existing domain %d' % domid)
-            vmpath = xstransact.Read(dompath, "vm")
-            if not vmpath:
-                raise XendError(
-                    'No vm path in store for existing domain %d' % domid)
-            uuid = xstransact.Read(vmpath, "uuid")
-            if not uuid:
-                raise XendError(
-                    'No vm/uuid path in store for existing domain %d' % domid)
-
-        except Exception, exn:
-            log.warn(str(exn))
-            uuid = getUuid()
-
-        log.info("Recreating domain %d, uuid %s", domid, uuid)
-
-        vm = cls(uuid, xeninfo, domid, True)
-        vm.refreshShutdown(xeninfo)
-        return vm
-
-    recreate = classmethod(recreate)
-
-
-    def restore(cls, config, uuid = None):
-        """Create a domain and a VM object to do a restore.
-
-        @param config:    domain configuration
-        @param uuid:      uuid to use
-        """
-        
-        log.debug("XendDomainInfo.restore(%s, %s)", config, uuid)
-
-        if not uuid:
-            uuid = getUuid()
-
-        try:
-            ssidref = int(sxp.child_value(config, 'ssidref'))
-        except TypeError, exn:
-            raise VmError('Invalid ssidref in config: %s' % exn)
-
-        vm = cls(uuid, cls.parseConfig(config),
-                 xc.domain_create(ssidref = ssidref))
-        vm.create_channel()
-        vm.configure()
-        vm.exportToDB()
-        vm.refreshShutdown()
-        return vm
-
-    restore = classmethod(restore)
-
-
-    def parseConfig(cls, config):
-        def get_cfg(name, conv = None):
-            val = sxp.child_value(config, name)
-
-            if conv and not val is None:
-                try:
-                    return conv(val)
-                except TypeError, exn:
-                    raise VmError(
-                        'Invalid setting %s = %s in configuration: %s' %
-                        (name, val, str(exn)))
-            else:
-                return val
-
-
-        log.debug("parseConfig: config is %s" % str(config))
-
-        result = {}
-
-        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
-            result[e[0]] = get_cfg(e[0], e[1])
-
-        result['memory']       = get_cfg('memory',     int)
-        result['mem_kb']       = get_cfg('mem_kb',     int)
-        result['maxmem']       = get_cfg('maxmem',     int)
-        result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
-        result['cpu']          = get_cfg('cpu',        int)
-        result['restart_mode'] = get_cfg('restart')
-        result['image']        = get_cfg('image')
-
-        try:
-            if result['image']:
-                result['vcpus'] = int(sxp.child_value(result['image'],
-                                                      'vcpus', 1))
-            else:
-                result['vcpus'] = 1
-        except TypeError, exn:
-            raise VmError(
-                'Invalid configuration setting: vcpus = %s: %s' %
-                (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
-
-        result['backend'] = []
-        for c in sxp.children(config, 'backend'):
-            result['backend'].append(sxp.name(sxp.child0(c)))
-
-        result['device'] = []
-        for d in sxp.children(config, 'device'):
-            c = sxp.child0(d)
-            result['device'].append((sxp.name(c), c))
-
-        log.debug("parseConfig: result is %s" % str(result))
-        return result
-
-
-    parseConfig = classmethod(parseConfig)
-
-    
     def __init__(self, uuid, info, domid = None, augment = False):
 
         self.uuid = uuid
         self.info = info
 
-        self.path = DOMROOT + "/" + uuid
-
-        if domid:
+        if domid is not None:
             self.domid = domid
         elif 'dom' in info:
             self.domid = int(info['dom'])
         else:
             self.domid = None
 
+        self.vmpath  = VMROOT + uuid
+        if self.domid is None:
+            self.dompath = None
+        else:
+            self.dompath = DOMROOT + str(self.domid)
+
         if augment:
             self.augmentInfo()
 
@@ -317,9 +389,7 @@
 
         self.state = STATE_VM_OK
         self.state_updated = threading.Condition()
-
-        self.writeVm("uuid", self.uuid)
-        self.storeDom("vm", self.path)
+        self.refresh_shutdown_lock = threading.Condition()
 
 
     def augmentInfo(self):
@@ -332,18 +402,30 @@
                 self.info[name] = val
 
         params = (("name", str),
-                  ("restart-mode", str),
+                  ("on_poweroff",  str),
+                  ("on_reboot",    str),
+                  ("on_crash",     str),
                   ("image",        str),
-                  ("start-time", float))
+                  ("vcpus",        int),
+                  ("vcpu_avail",   int),
+                  ("start_time", float))
 
         from_store = self.gatherVm(*params)
 
         map(lambda x, y: useIfNeeded(x[0], y), params, from_store)
+
+        device = []
+        for c in controllerClasses:
+            devconfig = self.getDeviceConfigurations(c)
+            if devconfig:
+                device.extend(map(lambda x: (c, x), devconfig))
+        useIfNeeded('device', device)
 
 
     def validateInfo(self):
         """Validate and normalise the info block.  This has either been parsed
-        by parseConfig, or received from xc through recreate.
+        by parseConfig, or received from xc through recreate and augmented by
+        the current store contents.
         """
         def defaultInfo(name, val):
             if not self.infoIsSet(name):
@@ -352,9 +434,13 @@
         try:
             defaultInfo('name',         lambda: "Domain-%d" % self.domid)
             defaultInfo('ssidref',      lambda: 0)
-            defaultInfo('restart_mode', lambda: RESTART_ONREBOOT)
+            defaultInfo('on_poweroff',  lambda: "destroy")
+            defaultInfo('on_reboot',    lambda: "restart")
+            defaultInfo('on_crash',     lambda: "restart")
             defaultInfo('cpu',          lambda: None)
             defaultInfo('cpu_weight',   lambda: 1.0)
+            defaultInfo('vcpus',        lambda: 1)
+            defaultInfo('vcpu_avail',   lambda: (1 << self.info['vcpus']) - 1)
             defaultInfo('bootloader',   lambda: None)
             defaultInfo('backend',      lambda: [])
             defaultInfo('device',       lambda: [])
@@ -377,7 +463,7 @@
             # mem_kb.
 
             def discard_negatives(name):
-                if self.infoIsSet(name) and self.info[name] <= 0:
+                if self.infoIsSet(name) and self.info[name] < 0:
                     del self.info[name]
 
             def valid_KiB_(mb_name, kb_name):
@@ -403,7 +489,7 @@
 
             def valid_KiB(mb_name, kb_name):
                 result = valid_KiB_(mb_name, kb_name)
-                if result <= 0:
+                if result is None or result < 0:
                     raise VmError('Invalid %s / %s: %s' %
                                   (mb_name, kb_name, result))
                 else:
@@ -436,15 +522,10 @@
                     raise VmError('invalid device (%s, %s)' %
                                   (str(n), str(c)))
 
-            if self.info['restart_mode'] not in restart_modes:
-                raise VmError('invalid restart mode: ' +
-                              str(self.info['restart_mode']))
-
-            if 'cpumap' not in self.info:
-                if [self.info['vcpus'] == 1]:
-                    self.info['cpumap'] = [1];
-                else:
-                    raise VmError('Cannot create CPU map')
+            for event in ['on_poweroff', 'on_reboot', 'on_crash']:
+                if self.info[event] not in restart_modes:
+                    raise VmError('invalid restart event: %s = %s' %
+                                  (event, str(self.info[event])))
 
         except KeyError, exn:
             log.exception(exn)
@@ -452,42 +533,61 @@
 
 
     def readVm(self, *args):
-        return xstransact.Read(self.path, *args)
+        return xstransact.Read(self.vmpath, *args)
 
     def writeVm(self, *args):
-        return xstransact.Write(self.path, *args)
+        return xstransact.Write(self.vmpath, *args)
 
     def removeVm(self, *args):
-        return xstransact.Remove(self.path, *args)
+        return xstransact.Remove(self.vmpath, *args)
 
     def gatherVm(self, *args):
-        return xstransact.Gather(self.path, *args)
+        return xstransact.Gather(self.vmpath, *args)
 
     def storeVm(self, *args):
-        return xstransact.Store(self.path, *args)
+        return xstransact.Store(self.vmpath, *args)
 
     def readDom(self, *args):
-        return xstransact.Read(self.path, *args)
+        return xstransact.Read(self.dompath, *args)
 
     def writeDom(self, *args):
-        return xstransact.Write(self.path, *args)
+        return xstransact.Write(self.dompath, *args)
 
     def removeDom(self, *args):
-        return xstransact.Remove(self.path, *args)
+        return xstransact.Remove(self.dompath, *args)
 
     def gatherDom(self, *args):
-        return xstransact.Gather(self.path, *args)
+        return xstransact.Gather(self.dompath, *args)
 
     def storeDom(self, *args):
-        return xstransact.Store(self.path, *args)
-
-
-    def exportToDB(self):
+        return xstransact.Store(self.dompath, *args)
+
+
+    def storeVmDetails(self):
+        to_store = {
+            'uuid':               self.uuid,
+
+            # XXX
+            'memory/target':      str(self.info['memory_KiB'])
+            }
+
+        if self.infoIsSet('image'):
+            to_store['image'] = sxp.to_string(self.info['image'])
+
+        for k in ['name', 'ssidref', 'on_poweroff', 'on_reboot', 'on_crash',
+                  'vcpus', 'vcpu_avail']:
+            if self.infoIsSet(k):
+                to_store[k] = str(self.info[k])
+
+        log.debug("Storing VM details: %s" % str(to_store))
+
+        self.writeVm(to_store)
+
+
+    def storeDomDetails(self):
         to_store = {
             'domid':              str(self.domid),
-            'uuid':               self.uuid,
-
-            'xend/restart_mode':  str(self.info['restart_mode']),
+            'vm':                 self.vmpath,
 
             'memory/target':      str(self.info['memory_KiB'])
             }
@@ -496,11 +596,18 @@
             if v:
                 to_store[k] = str(v)
 
-        to_store['image'] = sxp.to_string(self.info['image'])
-
-        log.debug("Storing %s" % str(to_store))
-
-        self.writeVm(to_store)
+        def availability(n):
+            if self.info['vcpu_avail'] & (1 << n):
+                return 'online'
+            else:
+                return 'offline'
+
+        for v in range(0, self.info['vcpus']):
+            to_store["cpu/%d/availability" % v] = availability(v)
+
+        log.debug("Storing domain details: %s" % str(to_store))
+
+        self.writeDom(to_store)
 
 
     def setDomid(self, domid):
@@ -522,8 +629,8 @@
     def getName(self):
         return self.info['name']
 
-    def getPath(self):
-        return self.path
+    def getDomainPath(self):
+        return self.dompath
 
     def getUuid(self):
         return self.uuid
@@ -549,85 +656,119 @@
 
 
     def refreshShutdown(self, xeninfo = None):
-        if xeninfo is None:
-            xeninfo = dom_get(self.domid)
+        # If set at the end of this method, a restart is required, with the
+        # given reason.  This restart has to be done out of the scope of
+        # refresh_shutdown_lock.
+        restart_reason = None
+        
+        self.refresh_shutdown_lock.acquire()
+        try:
             if xeninfo is None:
-                # The domain no longer exists.  This will occur if we have
-                # scheduled a timer to check for shutdown timeouts and the
-                # shutdown succeeded.
+                xeninfo = dom_get(self.domid)
+                if xeninfo is None:
+                    # The domain no longer exists.  This will occur if we have
+                    # scheduled a timer to check for shutdown timeouts and the
+                    # shutdown succeeded.  It will also occur if someone
+                    # destroys a domain beneath us.  We clean up the domain,
+                    # just in case, but we can't clean up the VM, because that
+                    # VM may have migrated to a different domain on this
+                    # machine.
+                    self.cleanupDomain()
+                    return
+
+            if xeninfo['dying']:
+                # Dying means that a domain has been destroyed, but has not
+                # yet been cleaned up by Xen.  This state could persist
+                # indefinitely if, for example, another domain has some of its
+                # pages mapped.  We might like to diagnose this problem in the
+                # future, but for now all we do is make sure that it's not us
+                # holding the pages, by calling cleanupDomain.  We can't
+                # clean up the VM, as above.
+                self.cleanupDomain()
                 return
 
-        if xeninfo['dying']:
-            # Dying means that a domain has been destroyed, but has not yet
-            # been cleaned up by Xen.  This could persist indefinitely if,
-            # for example, another domain has some of its pages mapped.
-            # We might like to diagnose this problem in the future, but for
-            # now all we can sensibly do is ignore it.
-            pass
-
-        elif xeninfo['crashed']:
-            log.warn('Domain has crashed: name=%s id=%d.',
-                     self.info['name'], self.domid)
-
-            if xroot.get_enable_dump():
-                self.dumpCore()
-
-            self.maybeRestart('crashed')
-
-        elif xeninfo['shutdown']:
-            reason = shutdown_reason(xeninfo['shutdown_reason'])
-
-            log.info('Domain has shutdown: name=%s id=%d reason=%s.',
-                     self.info['name'], self.domid, reason)
-
-            self.clearRestart()
-
-            if reason == 'suspend':
-                self.state_set(STATE_VM_SUSPENDED)
-                # Don't destroy the domain.  XendCheckpoint will do this once
-                # it has finished.
-            elif reason in ['poweroff', 'reboot']:
-                self.maybeRestart(reason)
+            elif xeninfo['crashed']:
+                log.warn('Domain has crashed: name=%s id=%d.',
+                         self.info['name'], self.domid)
+
+                if xroot.get_enable_dump():
+                    self.dumpCore()
+
+                restart_reason = 'crash'
+
+            elif xeninfo['shutdown']:
+                if self.readDom('xend/shutdown_completed'):
+                    # We've seen this shutdown already, but we are preserving
+                    # the domain for debugging.  Leave it alone.
+                    return
+
+                else:
+                    reason = shutdown_reason(xeninfo['shutdown_reason'])
+
+                    log.info('Domain has shutdown: name=%s id=%d reason=%s.',
+                             self.info['name'], self.domid, reason)
+
+                    self.clearRestart()
+
+                    if reason == 'suspend':
+                        self.state_set(STATE_VM_TERMINATED)
+                        # Don't destroy the domain.  XendCheckpoint will do
+                        # this once it has finished.
+                    elif reason in ['poweroff', 'reboot']:
+                        restart_reason = reason
+                    else:
+                        self.destroy()
+
             else:
-                self.destroy()
-
-        else:
-            # Domain is alive.  If we are shutting it down, then check
-            # the timeout on that, and destroy it if necessary.
-
-            sst = self.readVm('xend/shutdown_start_time')
-            if sst:
-                sst = float(sst)
-                timeout = SHUTDOWN_TIMEOUT - time.time() + sst
-                if timeout < 0:
-                    log.info(
-                        "Domain shutdown timeout expired: name=%s id=%s",
-                        self.info['name'], self.domid)
-                    self.destroy()
-                else:
-                    log.debug(
-                        "Scheduling refreshShutdown on domain %d in %ds.",
-                        self.domid, timeout)
-                    scheduler.later(timeout, self.refreshShutdown)
+                # Domain is alive.  If we are shutting it down, then check
+                # the timeout on that, and destroy it if necessary.
+
+                sst = self.readDom('xend/shutdown_start_time')
+                if sst:
+                    sst = float(sst)
+                    timeout = SHUTDOWN_TIMEOUT - time.time() + sst
+                    if timeout < 0:
+                        log.info(
+                            "Domain shutdown timeout expired: name=%s id=%s",
+                            self.info['name'], self.domid)
+                        self.destroy()
+                    else:
+                        log.debug(
+                            "Scheduling refreshShutdown on domain %d in %ds.",
+                            self.domid, timeout)
+                        scheduler.later(timeout, self.refreshShutdown)
+        finally:
+            self.refresh_shutdown_lock.release()
+
+        if restart_reason:
+            self.maybeRestart(restart_reason)
 
 
     def shutdown(self, reason):
         if not reason in shutdown_reasons.values():
             raise XendError('invalid reason:' + reason)
-        self.storeVm("control/shutdown", reason)
-        if not reason == 'suspend':
-            self.storeVm('xend/shutdown_start_time', time.time())
-
+        self.storeDom("control/shutdown", reason)
+        if reason != 'suspend':
+            self.storeDom('xend/shutdown_start_time', time.time())
+
+
+    ## private:
 
     def clearRestart(self):
-        self.removeVm("xend/shutdown_start_time")
+        self.removeDom("xend/shutdown_start_time")
 
 
     def maybeRestart(self, reason):
-        if self.restart_needed(reason):
-            self.restart()
-        else:
-            self.destroy()
+        # Dispatch to the correct method based upon the configured on_{reason}
+        # behaviour.
+        {"destroy"        : self.destroy,
+         "restart"        : self.restart,
+         "preserve"       : self.preserve,
+         "rename-restart" : self.renameRestart}[self.info['on_' + reason]]()
+
+
+    def renameRestart(self):
+        self.restart(True)
 
 
     def dumpCore(self):
@@ -638,38 +779,12 @@
                                                      self.domid)
             xc.domain_dumpcore(dom = self.domid, corefile = corefile)
 
-        except Exception, exn:
-            log.error("XendDomainInfo.dumpCore failed: id = %s name = %s: %s",
-                      self.domid, self.info['name'], str(exn))
-
-
-    def closeChannel(self, channel, entry):
-        """Close the given channel, if set, and remove the given entry in the
-        store.  Nothrow guarantee."""
-        
-        try:
-            try:
-                if channel:
-                    channel.close()
-            finally:
-                self.removeDom(entry)
-        except Exception, exn:
-            log.exception(exn)
-        
-
-    def closeStoreChannel(self):
-        """Close the store channel, if any.  Nothrow guarantee."""
-
-        self.closeChannel(self.store_channel, "store/port")
-        self.store_channel = None
-
-
-    def closeConsoleChannel(self):
-        """Close the console channel, if any.  Nothrow guarantee."""
-
-        self.closeChannel(self.console_channel, "console/port")
-        self.console_channel = None
-
+        except:
+            log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
+                          self.domid, self.info['name'])
+
+
+    ## public:
 
     def setConsoleRef(self, ref):
         self.console_mfn = ref
@@ -715,9 +830,9 @@
 
     ## public:
 
-    def state_wait(self, state):
+    def waitForShutdown(self):
         self.state_updated.acquire()
-        while self.state != state:
+        while self.state == STATE_VM_OK:
             self.state_updated.wait()
         self.state_updated.release()
 
@@ -734,24 +849,32 @@
     __repr__ = __str__
 
 
+    ## private:
+
     def createDevice(self, deviceClass, devconfig):
         return self.getDeviceController(deviceClass).createDevice(devconfig)
 
 
-    def configureDevice(self, deviceClass, devid, devconfig):
-        return self.getDeviceController(deviceClass).configureDevice(
+    def reconfigureDevice(self, deviceClass, devid, devconfig):
+        return self.getDeviceController(deviceClass).reconfigureDevice(
             devid, devconfig)
 
+
+    ## public:
 
     def destroyDevice(self, deviceClass, devid):
         return self.getDeviceController(deviceClass).destroyDevice(devid)
 
 
+    ## private:
+
     def getDeviceSxprs(self, deviceClass):
         return self.getDeviceController(deviceClass).sxprs()
 
 
-    ## private:
+    def getDeviceConfigurations(self, deviceClass):
+        return self.getDeviceController(deviceClass).configurations()
+
 
     def getDeviceController(self, name):
         if name not in controllerClasses:
@@ -803,7 +926,8 @@
         if self.infoIsSet('cpu_time'):
             sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
         sxpr.append(['vcpus', self.info['vcpus']])
-        sxpr.append(['cpumap', self.info['cpumap']])
+        if self.infoIsSet('cpumap'):
+            sxpr.append(['cpumap', self.info['cpumap']])
         if self.infoIsSet('vcpu_to_cpu'):
             sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
             sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()])
@@ -813,12 +937,8 @@
             sxpr.append(['up_time', str(up_time) ])
             sxpr.append(['start_time', str(self.info['start_time']) ])
 
-        if self.store_channel:
-            sxpr.append(self.store_channel.sxpr())
         if self.store_mfn:
             sxpr.append(['store_mfn', self.store_mfn])
-        if self.console_channel:
-            sxpr.append(['console_channel', self.console_channel.sxpr()])
         if self.console_mfn:
             sxpr.append(['console_mfn', self.console_mfn])
 
@@ -847,13 +967,9 @@
             if c in '_-.:/+': continue
             if c in string.ascii_letters: continue
             raise VmError('invalid vm name')
-        dominfo = domain_exists(name)
-        # When creating or rebooting, a domain with my name should not exist.
-        # When restoring, a domain with my name will exist, but it should have
-        # my domain id.
+
+        dominfo = domain_by_name(name)
         if not dominfo:
-            return
-        if dominfo.is_terminated():
             return
         if self.domid is None:
             raise VmError("VM name '%s' already in use by domain %d" %
@@ -864,9 +980,8 @@
 
 
     def construct(self):
-        """Construct the vm instance from its configuration.
-
-        @param config: configuration
+        """Construct the domain.
+
         @raise: VmError on error
         """
 
@@ -876,22 +991,15 @@
 
         self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
 
-        if self.domid <= 0:
+        if self.domid < 0:
             raise VmError('Creating domain failed: name=%s' %
                           self.info['name'])
 
-        try:
-            self.initDomain()
-            self.construct_image()
-            self.configure()
-            self.exportToDB()
-        except Exception, ex:
-            # Catch errors, cleanup and re-raise.
-            print 'Domain construction error:', ex
-            import traceback
-            traceback.print_exc()
-            self.destroy()
-            raise
+        self.dompath = DOMROOT + str(self.domid)
+
+        # Ensure that the domain entry is clean.  This prevents a stale
+        # shutdown_start_time from killing the domain, for example.
+        self.removeDom()
 
 
     def initDomain(self):
@@ -926,43 +1034,22 @@
                   self.domid, self.info['name'], self.info['memory_KiB'])
 
 
-    def configure_vcpus(self, vcpus):
-        d = {}
-        for v in range(0, vcpus):
-            d["cpu/%d/availability" % v] = "online"
-        self.writeVm(d)
-
     def construct_image(self):
         """Construct the boot image for the domain.
         """
         self.create_channel()
         self.image.createImage()
-        self.exportToDB()
-        if self.store_channel and self.store_mfn >= 0:
-            IntroduceDomain(self.domid, self.store_mfn,
-                            self.store_channel.port1, self.path)
-        # get the configured value of vcpus and update store
-        self.configure_vcpus(self.info['vcpus'])
+        IntroduceDomain(self.domid, self.store_mfn,
+                        self.store_channel, self.dompath)
 
 
     ## public:
 
-    def delete(self):
-        """Delete the vm's db.
-        """
-        try:
-            xstransact.Remove(self.path, 'domid')
-        except Exception, ex:
-            log.warning("error in domain db delete: %s", ex)
-
-
-    def cleanup(self):
-        """Cleanup vm resources: release devices.  Nothrow guarantee."""
-
-        self.state_set(STATE_VM_TERMINATED)
+    def cleanupDomain(self):
+        """Cleanup domain resources; release devices.  Idempotent.  Nothrow
+        guarantee."""
+
         self.release_devices()
-        self.closeStoreChannel()
-        self.closeConsoleChannel()
 
         if self.image:
             try:
@@ -972,46 +1059,62 @@
                     "XendDomainInfo.cleanup: image.destroy() failed.")
             self.image = None
 
-
-    def destroy(self):
-        """Cleanup vm and destroy domain.  Nothrow guarantee."""
-
-        log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
-
-        self.cleanup()
+        try:
+            self.removeDom()
+        except:
+            log.exception("Removing domain path failed.")
+
+        try:
+            if not self.info['name'].startswith(ZOMBIE_PREFIX):
+                self.info['name'] = self.generateZombieName()
+        except:
+            log.exception("Renaming Zombie failed.")
+
+        self.state_set(STATE_VM_TERMINATED)
+
+
+    def cleanupVm(self):
+        """Cleanup VM resources.  Idempotent.  Nothrow guarantee."""
 
         try:
             self.removeVm()
-        except Exception:
+        except:
             log.exception("Removing VM path failed.")
 
-        try:
-            self.removeDom()
-        except Exception:
-            log.exception("Removing domain path failed.")
+
+    def destroy(self):
+        """Cleanup VM and destroy domain.  Nothrow guarantee."""
+
+        log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
+
+        self.cleanupVm()
+        self.destroyDomain()
+
+
+    def destroyDomain(self):
+        log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
 
         try:
             if self.domid is not None:
                 xc.domain_destroy(dom=self.domid)
-        except Exception:
+        except:
             log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
 
-
-    def is_terminated(self):
-        """Check if a domain has been terminated.
-        """
-        return self.state == STATE_VM_TERMINATED
+        self.cleanupDomain()
+
+
+    ## private:
 
     def release_devices(self):
-        """Release all vm devices.  Nothrow guarantee."""
+        """Release all domain's devices.  Nothrow guarantee."""
 
         while True:
-            t = xstransact("%s/device" % self.path)
+            t = xstransact("%s/device" % self.dompath)
             for n in controllerClasses.keys():
                 for d in t.list(n):
                     try:
                         t.remove(d)
-                    except ex:
+                    except:
                         # Log and swallow any exceptions in removal --
                         # there's nothing more we can do.
                         log.exception(
@@ -1020,22 +1123,29 @@
             if t.commit():
                 break
 
+
     def eventChannel(self, path=None):
         """Create an event channel to the domain.
         
         @param path under which port is stored in db
         """
-        port = 0
         if path:
             try:
-                port = int(self.readDom(path))
+                return int(self.readDom(path))
             except:
-                # if anything goes wrong, assume the port was not yet set
+                # The port is not yet set, i.e. the channel has not yet been
+                # created.
                 pass
-        ret = EventChannel.interdomain(0, self.domid, port1=port, port2=0)
-        self.storeDom(path, ret.port1)
-        return ret
-        
+
+        try:
+            port = xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0)
+        except:
+            log.exception("Exception in alloc_unbound(%d)", self.domid)
+            raise
+
+        self.storeDom(path, port)
+        return port
+
     def create_channel(self):
         """Create the channels to the domain.
         """
@@ -1055,6 +1165,9 @@
         self.create_configured_devices()
         if self.image:
             self.image.createDeviceModel()
+
+
+    ## public:
 
     def device_create(self, dev_config):
         """Create a new device.
@@ -1073,24 +1186,10 @@
         @param devid:      device id
         """
         deviceClass = sxp.name(dev_config)
-        self.configureDevice(deviceClass, devid, dev_config)
-
-
-    def restart_needed(self, reason):
-        """Determine if the vm needs to be restarted when shutdown
-        for the given reason.
-
-        @param reason: shutdown reason
-        @return True if needs restart, False otherwise
-        """
-        if self.info['restart_mode'] == RESTART_NEVER:
-            return False
-        if self.info['restart_mode'] == RESTART_ALWAYS:
-            return True
-        if self.info['restart_mode'] == RESTART_ONREBOOT:
-            return reason == 'reboot'
-        return False
-
+        self.reconfigureDevice(deviceClass, devid, dev_config)
+
+
+    ## private:
 
     def restart_check(self):
         """Check if domain restart is OK.
@@ -1109,11 +1208,14 @@
         self.restart_count += 1
 
 
-    def restart(self):
-        """Restart the domain after it has exited. """
+    def restart(self, rename = False):
+        """Restart the domain after it has exited.
+
+        @param rename True if the old domain is to be renamed and preserved,
+        False if it is to be destroyed.
+        """
 
         #            self.restart_check()
-        self.cleanup()
 
         config = self.sxpr()
 
@@ -1127,17 +1229,91 @@
         self.writeVm('xend/restart_in_progress', 'True')
 
         try:
-            self.destroy()
+            if rename:
+                self.preserveForRestart()
+            else:
+                self.destroy()
+                
             try:
                 xd = get_component('xen.xend.XendDomain')
-                xd.domain_unpause(xd.domain_create(config).getDomid())
-            except Exception, exn:
+                new_dom = xd.domain_create(config)
+                try:
+                    xc.domain_unpause(new_dom.getDomid())
+                except:
+                    new_dom.destroy()
+                    raise
+            except:
                 log.exception('Failed to restart domain %d.', self.domid)
         finally:
             self.removeVm('xend/restart_in_progress')
             
         # self.configure_bootloader()
         #        self.exportToDB()
+
+
+    def preserveForRestart(self):
+        """Preserve a domain that has been shut down, by giving it a new UUID,
+        cloning the VM details, and giving it a new name.  This allows us to
+        keep this domain for debugging, but restart a new one in its place
+        preserving the restart semantics (name and UUID preserved).
+        """
+        
+        new_name = self.generateUniqueName()
+        new_uuid = getUuid()
+        log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
+                 self.info['name'], self.domid, self.uuid, new_name, new_uuid)
+        self.release_devices()
+        self.info['name'] = new_name
+        self.uuid = new_uuid
+        self.vmpath = VMROOT + new_uuid
+        self.storeVmDetails()
+        self.preserve()
+
+
+    def preserve(self):
+        log.info("Preserving dead domain %s (%d).", self.info['name'],
+                 self.domid)
+        self.storeDom('xend/shutdown_completed', 'True')
+        self.state_set(STATE_VM_TERMINATED)
+
+
+    ## public:
+
+    def renameUniquely(self):
+        """Rename this domain so that it has a unique name.  This is used by
+        XendDomain to recover from non-uniqueness errors; we should never have
+        allowed the system to reach this state in the first place."""
+        new_name = self.generateUniqueName()
+        
+        log.error('Renaming %s (%d, %s) to %s', self.info['name'], self.domid,
+                  self.uuid, new_name)
+
+        self.setName(new_name)
+
+
+    # private:
+
+    def generateUniqueName(self):
+        n = 1
+        while True:
+            name = "%s-%d" % (self.info['name'], n)
+            try:
+                self.check_name(name)
+                return name
+            except VmError:
+                n += 1
+
+
+    def generateZombieName(self):
+        n = 0
+        name = ZOMBIE_PREFIX + self.info['name']
+        while True:
+            try:
+                self.check_name(name)
+                return name
+            except VmError:
+                n += 1
+                name = "%s%d-%s" % (ZOMBIE_PREFIX, n, self.info['name'])
 
 
     def configure_bootloader(self):
@@ -1182,32 +1358,31 @@
             log.error("Invalid VCPU %d" % vcpu)
             return
         if int(state) == 0:
+            self.info['vcpu_avail'] &= ~(1 << vcpu)
             availability = "offline"
         else:
+            self.info['vcpu_avail'] &= (1 << vcpu)
             availability = "online"
-        self.storeVm("cpu/%d/availability" % vcpu, availability)
+        self.storeVm('vcpu_avail', self.info['vcpu_avail'])
+        self.storeDom("cpu/%d/availability" % vcpu, availability)
 
     def send_sysrq(self, key=0):
-        self.storeVm("control/sysrq", '%c' % key)
-
-    def dom0_init_store(self):
-        if not self.store_channel:
-            self.store_channel = self.eventChannel("store/port")
-            if not self.store_channel:
-                return
-        ref = xc.init_store(self.store_channel.port2)
+        self.storeDom("control/sysrq", '%c' % key)
+
+
+    def initStoreConnection(self):
+        ref = xc.init_store(self.store_channel)
         if ref and ref >= 0:
             self.setStoreRef(ref)
             try:
-                IntroduceDomain(self.domid, ref, self.store_channel.port1,
-                                self.path)
+                IntroduceDomain(self.domid, ref, self.store_channel,
+                                self.dompath)
             except RuntimeError, ex:
                 if ex.args[0] == errno.EISCONN:
                     pass
                 else:
                     raise
-            # get run-time value of vcpus and update store
-            self.configure_vcpus(dom_get(self.domid)['vcpus'])
+
 
     def dom0_enforce_vcpus(self):
         dom = 0
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/XendRoot.py Sat Oct  8 20:28:24 2005
@@ -26,16 +26,14 @@
 
 import os
 import os.path
+import string
 import sys
 
-import EventServer
 from XendLogging import XendLogging
 from XendError import XendError
 
-# Initial create of the event server.
-eserver = EventServer.instance()
-
 import sxp
+
 
 class XendRoot:
     """Root of the management classes."""
@@ -96,9 +94,7 @@
         self.config = None
         self.logging = None
         self.configure()
-        eserver.subscribe('xend.*', self.event_handler)
-        #eserver.subscribe('xend.domain.created', self.event_handler)
-        #eserver.subscribe('xend.domain.died', self.event_handler)
+
 
     def add_component(self, name, val):
         """Add a xend component.
@@ -117,9 +113,6 @@
         @return: component object (or None)
         """
         return self.components.get(name)
-
-    def start(self):
-        eserver.inject('xend.start', 0)
 
     def _format(self, msg, args):
         if args:
@@ -246,10 +239,10 @@
         return sxp.child_value(self.config, name, val=val)
 
     def get_config_bool(self, name, val=None):
-        v = self.get_config_value(name, val)
-        if v in ['yes', '1', 'on', 'true', 1, True]:
+        v = string.lower(str(self.get_config_value(name, val)))
+        if v in ['yes', 'y', '1', 'on',  'true',  't']:
             return True
-        if v in ['no', '0', 'off', 'false', 0, False]:
+        if v in ['no',  'n', '0', 'off', 'false', 'f']:
             return False
         raise XendError("invalid xend config %s: expected bool: %s" % (name, 
v))
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/XendVnet.py
--- a/tools/python/xen/xend/XendVnet.py Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/XendVnet.py Sat Oct  8 20:28:24 2005
@@ -13,6 +13,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
 """Handler for vnet operations.
@@ -22,7 +23,8 @@
 from xen.xend import sxp
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
-from xen.xend.xenstore import XenNode, DBMap, DBVar
+from xen.xend.xenstore.xstransact import xstransact
+
 
 def vnet_cmd(cmd):
     out = None
@@ -39,39 +41,40 @@
     
     vifctl_ops = {'up': 'vif.add', 'down': 'vif.del'}
 
-    __exports__ = [
-        DBVar('id',     ty='str'),
-        DBVar('dbid',   ty='str'),
-        DBVar('config', ty='sxpr'),
-       ]
-    
-    def __init__(self, db, config=None):
+    def __init__(self, dbpath, config=None):
         if config:
-            self.id = sxp.child_value(config, 'id')
-            self.id = str(self.id)
+            self.id = str(sxp.child_value(config, 'id'))
             self.dbid = self.id.replace(':', '-')
-            self.db = db.addChild(self.dbid)
+            self.dbpath = dbpath + '/' + self.dbid
             self.config = config
         else:
-            self.db = db
+            self.dbpath = dbpath
             self.importFromDB()
-            config = self.config
             
-        self.bridge = sxp.child_value(config, 'bridge')
+        self.bridge = sxp.child_value(self.config, 'bridge')
         if not self.bridge:
             self.bridge = "vnet%s" % self.id
-        self.vnetif = sxp.child_value(config, 'vnetif')
+        self.vnetif = sxp.child_value(self.config, 'vnetif')
         if not self.vnetif:
             self.vnetif = "vnif%s" % self.id
 
-    def saveToDB(self, save=False, sync=False):
-        self.db.saveDB(save=save, sync=sync)
 
     def exportToDB(self, save=False, sync=False):
-        self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
+        to_store = {
+            'id' : self.id,
+            'dbid' : self.dbid,
+            'config' : sxp.to_string
+            }
+        xstransact.Write(self.dbpath, to_store)
+
 
     def importFromDB(self):
-        self.db.importFromDB(self, fields=self.__exports__)
+        (self.id, self.dbid, c) = xstransact.Gather(self.dbpath,
+                                                    ('id', str),
+                                                    ('dbid', str),
+                                                    ('config', str))
+        self.config = sxp.from_string(c)
+
 
     def sxpr(self):
         return self.config
@@ -88,7 +91,7 @@
         Brctl.vif_bridge_rem({'bridge': self.bridge, 'vif': self.vnetif})
         Brctl.bridge_del(self.bridge)
         val = vnet_cmd(['vnet.del', self.id])
-        self.db.delete()
+        xstransact.Remove(self.dbpath)
         return val
 
     def vifctl(self, op, vif, vmac):
@@ -107,18 +110,17 @@
     def __init__(self):
         # Table of vnet info indexed by vnet id.
         self.vnet = {}
-        self.db = DBMap(db=XenNode(self.dbpath))
-        self.db.readDB()
-        for vnetdb in self.db.values():
+        listing = xstransact.List(self.dbpath)
+        for entry in listing:
             try:
-                info = XendVnetInfo(vnetdb)
+                info = XendVnetInfo(self.dbpath + '/' + entry)
                 self.vnet[info.id] = info
                 info.configure()
             except XendError, ex:
                 log.warning("Failed to configure vnet %s: %s", str(info.id), 
str(ex))
             except Exception, ex:
                 log.exception("Vnet error")
-                vnetdb.delete()
+                xstransact.Remove(self.dbpath + '/' + entry)
 
     def vnet_of_bridge(self, bridge):
         """Get the vnet for a bridge (if any).
@@ -155,9 +157,9 @@
 
         @param config: config
         """
-        info = XendVnetInfo(self.db, config=config)
+        info = XendVnetInfo(self.dbpath, config=config)
         self.vnet[info.id] = info
-        info.saveToDB()
+        info.exportToDB()
         info.configure()
 
     def vnet_delete(self, id):
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/image.py    Sat Oct  8 20:28:24 2005
@@ -25,8 +25,6 @@
 from xen.xend.XendError import VmError
 from xen.xend.XendLogging import log
 
-from xen.xend.server import channel
-
 
 xc = xen.lowlevel.xc.new()
 
@@ -168,11 +166,11 @@
 
     def buildDomain(self):
         if self.vm.store_channel:
-            store_evtchn = self.vm.store_channel.port2
+            store_evtchn = self.vm.store_channel
         else:
             store_evtchn = 0
         if self.vm.console_channel:
-            console_evtchn = self.vm.console_channel.port2
+            console_evtchn = self.vm.console_channel
         else:
             console_evtchn = 0
 
@@ -228,16 +226,17 @@
 
     def buildDomain(self):
         # Create an event channel
-        self.device_channel = channel.eventChannel(0, self.vm.getDomid())
-        log.info("VMX device model port: %d", self.device_channel.port2)
+        self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
+                                                      remote_dom=0)
+        log.info("VMX device model port: %d", self.device_channel)
         if self.vm.store_channel:
-            store_evtchn = self.vm.store_channel.port2
+            store_evtchn = self.vm.store_channel
         else:
             store_evtchn = 0
 
         log.debug("dom            = %d", self.vm.getDomid())
         log.debug("image          = %s", self.kernel)
-        log.debug("control_evtchn = %d", self.device_channel.port2)
+        log.debug("control_evtchn = %d", self.device_channel)
         log.debug("store_evtchn   = %d", store_evtchn)
         log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
         log.debug("flags          = %d", self.flags)
@@ -245,7 +244,7 @@
 
         ret = xc.vmx_build(dom            = self.vm.getDomid(),
                            image          = self.kernel,
-                           control_evtchn = self.device_channel.port2,
+                           control_evtchn = self.device_channel,
                            store_evtchn   = store_evtchn,
                            memsize        = self.vm.getMemoryTarget() / 1024,
                            flags          = self.flags,
@@ -334,7 +333,7 @@
         if len(vnc):
             args = args + vnc
         args = args + ([ "-d",  "%d" % self.vm.getDomid(),
-                  "-p", "%d" % self.device_channel.port1,
+                  "-p", "%d" % self.device_channel,
                   "-m", "%s" % (self.vm.getMemoryTarget() / 1024)])
         args = args + self.dmargs
         env = dict(os.environ)
@@ -358,7 +357,6 @@
         return vncconnect
 
     def destroy(self):
-        channel.eventChannelClose(self.device_channel)
         import signal
         if not self.pid:
             return
diff -r 0ba10f7fef51 -r 4e0c94871be2 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/DevController.py     Sat Oct  8 20:28:24 2005
@@ -75,10 +75,29 @@
         """
 
         frontpath = self.frontendPath(devid)
-        backpath = xstransact.Read("%s/backend" % frontpath)
+        backpath = xstransact.Read(frontpath, "backend")
 
         xstransact.Remove(frontpath)
-        xstransact.Remove(backpath)
+
+        if backpath:
+            xstransact.Remove(backpath)
+        else:
+            raise VmError("Device not connected")
+           
+
+    def configurations(self):
+        return map(self.configuration, self.deviceIDs())
+
+
+    def configuration(self, devid):
+        """@return an s-expression giving the current configuration of the
+        specified device.  This would be suitable for giving to {@link
+        #createDevice} in order to recreate that device."""
+
+        backdomid = int(xstransact.Read(self.frontendPath(devid),
+                                        "backend-id"))
+
+        return [self.deviceClass, ['backend', backdomid]]
 
 
     def sxprs(self):
@@ -150,7 +169,20 @@
                 raise
 
 
-    ## private:
+    def readBackend(self, devid, *args):
+        frontpath = self.frontendPath(devid)
+        backpath = xstransact.Read(frontpath, "backend")
+        return xstransact.Read(backpath, *args)
+
+
+    def deviceIDs(self):
+        """@return The IDs of each of the devices currently configured for
+        this instance's deviceClass.
+        """
+        return map(int, xstransact.List(self.frontendRoot()))
+
+
+## private:
 
     def writeDetails(self, config, devid, backDetails, frontDetails):
         """Write the details in the store to trigger creation of a device.
@@ -167,8 +199,17 @@
         """
 
         import xen.xend.XendDomain
-        backdom = xen.xend.XendDomain.instance().domain_lookup_by_name(
-            sxp.child_value(config, 'backend', '0'))
+        xd = xen.xend.XendDomain.instance()
+
+        backdom_name = sxp.child_value(config, 'backend')
+        if backdom_name:
+            backdom = xd.domain_lookup_by_name_or_id_nr(backdom_name)
+        else:
+            backdom = xd.privilegedDomain()
+
+        if not backdom:
+            raise VmError("Cannot configure device for unknown backend %s" %
+                          backdom_name)
 
         frontpath = self.frontendPath(devid)
         backpath  = self.backendPath(backdom, devid)
@@ -197,9 +238,9 @@
     def backendPath(self, backdom, devid):
         """@param backdom [XendDomainInfo] The backend domain info."""
 
-        return "%s/backend/%s/%s/%d" % (backdom.getPath(),
+        return "%s/backend/%s/%s/%d" % (backdom.getDomainPath(),
                                         self.deviceClass,
-                                        self.vm.getUuid(), devid)
+                                        self.vm.getDomid(), devid)
 
 
     def frontendPath(self, devid):
@@ -207,8 +248,9 @@
 
 
     def frontendRoot(self):
-        return "%s/device/%s" % (self.vm.getPath(), self.deviceClass)
+        return "%s/device/%s" % (self.vm.getDomainPath(), self.deviceClass)
 
 
     def frontendMiscPath(self):
-        return "%s/device-misc/%s" % (self.vm.getPath(), self.deviceClass)
+        return "%s/device-misc/%s" % (self.vm.getDomainPath(),
+                                      self.deviceClass)
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/SrvDaemon.py Sat Oct  8 20:28:24 2005
@@ -2,6 +2,7 @@
 ## Xen controller daemon
 ## Copyright (c) 2004, K A Fraser (University of Cambridge)
 ## Copyright (C) 2004, Mike Wray <mike.wray@xxxxxx>
+## Copyright (C) 2005, XenSource Ltd
 ###########################################################
 
 import os
@@ -13,18 +14,12 @@
 import re
 import traceback
 
-from xen.xend import EventServer
 from xen.xend.server import SrvServer
 from xen.xend.XendLogging import log
-from xen.xend import XendRoot
 
 import event
 import relocate
 from params import *
-
-
-eserver = EventServer.instance()
-xroot = XendRoot.instance()
 
 
 class Daemon:
@@ -71,14 +66,17 @@
         @param pidfile: file to read
         @return pid or 0
         """
-        pid = 0
         if os.path.isfile(pidfile) and os.path.getsize(pidfile):
             try:
-                pid = open(pidfile, 'r').read()
-                pid = int(pid)
+                f = open(pidfile, 'r')
+                try:
+                    return int(f.read())
+                finally:
+                    f.close()
             except:
-                pid = 0
-        return pid
+                return 0
+        else:
+            return 0
 
     def find_process(self, pid, name):
         """Search for a process.
@@ -146,8 +144,10 @@
         if self.child:
             # Parent
             pidfile = open(pidfile, 'w')
-            pidfile.write(str(self.child))
-            pidfile.close()
+            try:
+                pidfile.write(str(self.child))
+            finally:
+                pidfile.close()
 
         return self.child
 
@@ -200,8 +200,10 @@
         if self.fork_pid(XEND_PID_FILE):
             os.close(w)
             r = os.fdopen(r, 'r')
-            s = r.read()
-            r.close()
+            try:
+                s = r.read()
+            finally:
+                r.close()
             if not len(s):
                 ret = 1
             else:
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/SrvDomain.py Sat Oct  8 20:28:24 2005
@@ -71,8 +71,7 @@
 
     def op_destroy(self, op, req):
         fn = FormFn(self.xd.domain_destroy,
-                    [['dom',    'int'],
-                     ['reason', 'str']])
+                    [['dom',    'int']])
         val = fn(req.args, {'dom': self.dom.domid})
         req.setHeader("Location", "%s/.." % req.prePathURL())
         return val
@@ -157,19 +156,11 @@
         val = fn(req.args, {'dom': self.dom.domid})
         return val
 
-    def op_device_refresh(self, op, req):
-        fn = FormFn(self.xd.domain_device_refresh,
-                    [['dom',  'int'],
-                     ['type', 'str'],
-                     ['idx',  'int']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
-
     def op_device_destroy(self, op, req):
         fn = FormFn(self.xd.domain_device_destroy,
                     [['dom',  'int'],
                      ['type', 'str'],
-                     ['idx',  'int']])
+                     ['dev',  'str']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
                 
@@ -177,7 +168,7 @@
         fn = FormFn(self.xd.domain_device_configure,
                     [['dom',    'int'],
                      ['config', 'sxpr'],
-                     ['idx',    'int']])
+                     ['dev',    'str']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
 
@@ -232,8 +223,6 @@
 
         req.write('<form method="post" action="%s">' % url)
         req.write('<input type="submit" name="op" value="destroy">')
-        req.write('<input type="radio" name="reason" value="halt" 
checked>Halt')
-        req.write('<input type="radio" name="reason" value="reboot">Reboot')
         req.write('</form>')
 
         req.write('<form method="post" action="%s">' % url)
diff -r 0ba10f7fef51 -r 4e0c94871be2 
tools/python/xen/xend/server/SrvDomainDir.py
--- a/tools/python/xen/xend/server/SrvDomainDir.py      Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/SrvDomainDir.py      Sat Oct  8 20:28:24 2005
@@ -38,7 +38,7 @@
         self.xd = XendDomain.instance()
 
     def domain(self, x):
-        dom = self.xd.domain_lookup_by_name(x)
+        dom = self.xd.domain_lookup_by_name_or_id(x)
         if not dom:
             raise XendError('No such domain ' + str(x))
         return SrvDomain(dom)
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/SrvRoot.py
--- a/tools/python/xen/xend/server/SrvRoot.py   Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/SrvRoot.py   Sat Oct  8 20:28:24 2005
@@ -13,10 +13,9 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
-from xen.xend import XendRoot
-xroot = XendRoot.instance()
 from xen.web.SrvDir import SrvDir
 
 class SrvRoot(SrvDir):
@@ -39,8 +38,6 @@
             self.add(name, klass)
         for (name, klass) in self.subdirs:
             self.get(name)
-        xroot.start()
         
     def __repr__(self):
         return "<SrvRoot %x %s>" %(id(self), self.table.keys())
-
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/blkif.py     Sat Oct  8 20:28:24 2005
@@ -23,7 +23,7 @@
 from xen.util import blkif
 from xen.xend import sxp
 
-from xen.xend.server.DevController import DevController
+from DevController import DevController
 
 
 class BlkifController(DevController):
@@ -40,14 +40,15 @@
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
         
-        typedev = sxp.child_value(config, 'dev')
-        if re.match('^ioemu:', typedev):
+        dev = sxp.child_value(config, 'dev')
+        if re.match('^ioemu:', dev):
             return (0,{},{})
 
-        devid = blkif.blkdev_name_to_number(sxp.child_value(config, 'dev'))
+        devid = blkif.blkdev_name_to_number(dev)
 
         (typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1)
-        back = { 'type' : typ,
+        back = { 'dev' : dev,
+                 'type' : typ,
                  'params' : params
                  }
 
@@ -57,3 +58,44 @@
         front = { 'virtual-device' : "%i" % devid }
 
         return (devid, back, front)
+
+
+    def configuration(self, devid):
+        """@see DevController.configuration"""
+
+        result = DevController.configuration(self, devid)
+
+        (dev, typ, params, ro) = self.readBackend(devid,
+                                                  'dev', 'type', 'params',
+                                                  'read-only')
+
+        if dev:
+            result.append(['dev', dev])
+        if typ and params:
+            result.append(['uname', typ + ":" + params])
+        if ro:
+            result.append(['mode', 'r'])
+        else:
+            result.append(['mode', 'w'])
+
+        return result
+
+
+    def destroyDevice(self, devid):
+        """@see DevController.destroyDevice"""
+
+        # If we are given a device name, then look up the device ID from it,
+        # and destroy that ID instead.  If what we are given is an integer,
+        # then assume it's a device ID and pass it straight through to our
+        # superclass's method.
+
+        try:
+            DevController.destroyDevice(self, int(devid))
+        except ValueError:
+            for i in self.deviceIDs():
+                if self.readBackend(i, 'dev') == devid:
+                    DevController.destroyDevice(self, i)
+                    return
+            # Try this, but it's almost certainly going to throw VmError,
+            # since we can't find the device.
+            DevController.destroyDevice(self, int(devid))
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/event.py
--- a/tools/python/xen/xend/server/event.py     Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/event.py     Sat Oct  8 20:28:24 2005
@@ -13,19 +13,23 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
 import sys
 import StringIO
 
-from xen.web import reactor, protocol
+from xen.web import protocol, tcp, unix
 
 from xen.xend import scheduler
 from xen.xend import sxp
 from xen.xend import PrettyPrint
-from xen.xend import EventServer; eserver = EventServer.instance()
 from xen.xend.XendError import XendError
-from xen.xend import XendRoot; xroot = XendRoot.instance()
+from xen.xend import XendRoot
+
+
+xroot = XendRoot.instance()
+
 
 DEBUG = 0
 
@@ -38,13 +42,7 @@
         self.daemon = daemon
         # Event queue.
         self.queue = []
-        # Subscribed events.
-        self.events = []
         self.parser = sxp.Parser()
-        self.pretty = 0
-
-        # For debugging subscribe to everything and make output pretty.
-        #self.subscribe(['*'])
         self.pretty = 1
 
     def dataReceived(self, data):
@@ -68,7 +66,7 @@
             scheduler.now(self.connectionLost)
 
     def connectionLost(self, reason=None):
-        self.unsubscribe()
+        pass
 
     def send_reply(self, sxpr):
         io = StringIO.StringIO()
@@ -99,16 +97,6 @@
     def send_event(self, val):
         return self.send_reply(['event', val[0], val[1]])
 
-    def unsubscribe(self):
-        for event in self.events:
-            eserver.unsubscribe(event, self.queue_event)
-
-    def subscribe(self, events):
-        self.unsubscribe()
-        for event in events:
-            eserver.subscribe(event, self.queue_event)
-        self.events = events
-
     def queue_event(self, name, v):
         # Despite the name we don't queue the event here.
         # We send it because the transport will queue it.
@@ -126,7 +114,7 @@
         op_method = getattr(self, op_method_name, self.operror)
         return op_method(op_name, req)
 
-    def op_help(self, name, req):
+    def op_help(self, _1, _2):
         def nameop(x):
             if x.startswith('op_'):
                 return x[3:].replace('_', '.')
@@ -136,37 +124,27 @@
         l = [ nameop(k) for k in dir(self) if k.startswith('op_') ]
         return l
 
-    def op_quit(self, name, req):
+    def op_quit(self, _1, _2):
         self.loseConnection()
 
-    def op_exit(self, name, req):
+    def op_exit(self, _1, _2):
         sys.exit(0)
 
-    def op_pretty(self, name, req):
+    def op_pretty(self, _1, _2):
         self.pretty = 1
 
-    def op_info(self, name, req):
+    def op_info(self, _1, _2):
         val = ['info']
         #val += self.daemon.blkifs()
         #val += self.daemon.netifs()
         #val += self.daemon.usbifs()
         return val
 
-    def op_sys_subscribe(self, name, v):
-        # (sys.subscribe event*)
-        # Subscribe to the events:
-        self.subscribe(v[1:])
-
-    def op_sys_inject(self, name, v):
-        # (sys.inject event)
-        event = v[1]
-        eserver.inject(sxp.name(event), event)
-
-    def op_trace(self, name, v):
+    def op_trace(self, _, v):
         mode = (v[1] == 'on')
         self.daemon.tracing(mode)
 
-    def op_log_stderr(self, name, v):
+    def op_log_stderr(self, _, v):
         mode = v[1]
         logging = xroot.get_logging()
         if mode == 'on':
@@ -174,11 +152,11 @@
         else:
             logging.removeLogStderr()
 
-    def op_domain_ls(self, name, v):
+    def op_domain_ls(self, _1, _2):
         xd = xroot.get_component("xen.xend.XendDomain")
         return xd.list_names()
 
-    def op_domain_configure(self, name, v):
+    def op_domain_configure(self, _, v):
         domid = sxp.child_value(v, "dom")
         config = sxp.child_value(v, "config")
         if domid is None:
@@ -188,7 +166,7 @@
         xd = xroot.get_component("xen.xend.XendDomain")
         xd.domain_configure(domid, config)
 
-    def op_domain_unpause(self, name, v):
+    def op_domain_unpause(self, _, v):
         domid = sxp.child_value(v, "dom")
         if domid is None:
             raise XendError("missing domain id")
@@ -200,18 +178,18 @@
     """
 
     def __init__(self, daemon):
-        #protocol.ServerFactory.__init__(self)
+        protocol.ServerFactory.__init__(self)
         self.daemon = daemon
 
-    def buildProtocol(self, addr):
+    def buildProtocol(self, _):
         return EventProtocol(self.daemon)
 
 def listenEvent(daemon):
     factory = EventFactory(daemon)
     if xroot.get_xend_unix_server():
         path = '/var/lib/xend/event-socket'
-        reactor.listenUNIX(path, factory)
+        unix.listenUNIX(path, factory)
     if xroot.get_xend_http_server():
         port = xroot.get_xend_event_port()
         interface = xroot.get_xend_address()
-        reactor.listenTCP(port, factory, interface=interface)
+        tcp.listenTCP(port, factory, interface=interface)
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/netif.py     Sat Oct  8 20:28:24 2005
@@ -23,8 +23,12 @@
 import os
 
 from xen.xend import sxp
+from xen.xend import XendRoot
 
 from xen.xend.server.DevController import DevController
+
+
+xroot = XendRoot.instance()
 
 
 class NetifController(DevController):
@@ -37,9 +41,6 @@
 
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
-
-        from xen.xend import XendRoot
-        xroot = XendRoot.instance()
 
         def _get_config_ipaddr(config):
             val = []
@@ -68,3 +69,26 @@
                   'mac' : mac }
 
         return (devid, back, front)
+
+
+    def configuration(self, devid):
+        """@see DevController.configuration"""
+
+        result = DevController.configuration(self, devid)
+
+        (script, ip, bridge, mac) = self.readBackend(devid,
+                                                     'script', 'ip', 'bridge',
+                                                     'mac')
+
+        if script:
+            result.append(['script',
+                           script.replace(xroot.network_script_dir + os.sep,
+                                          "")])
+        if ip:
+            result.append(['ip', ip.split(" ")])
+        if bridge:
+            result.append(['bridge', bridge])
+        if mac:
+            result.append(['mac', mac])
+
+        return result
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/relocate.py
--- a/tools/python/xen/xend/server/relocate.py  Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/relocate.py  Sat Oct  8 20:28:24 2005
@@ -13,21 +13,24 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
 import socket
 import sys
 import StringIO
 
-from xen.web import reactor, protocol
+from xen.web import protocol, tcp, unix
 
 from xen.xend import scheduler
 from xen.xend import sxp
-from xen.xend import EventServer; eserver = EventServer.instance()
 from xen.xend.XendError import XendError
-from xen.xend import XendRoot; xroot = XendRoot.instance()
+from xen.xend import XendRoot
 from xen.xend.XendLogging import log
-from xen.xend import XendCheckpoint
+
+
+xroot = XendRoot.instance()
+
 
 DEBUG = 0
 
@@ -115,7 +118,7 @@
             self.send_reply(["ready", name])
             self.transport.sock.setblocking(1)
             xd = xroot.get_component("xen.xend.XendDomain")
-            XendCheckpoint.restore(xd, self.transport.sock.fileno())
+            xd.domain_restore_fd(self.transport.sock.fileno())
             self.transport.sock.setblocking(0)
         else:
             log.error(name + ": no transport")
@@ -136,11 +139,11 @@
     factory = RelocationFactory()
     if xroot.get_xend_unix_server():
         path = '/var/lib/xend/relocation-socket'
-        reactor.listenUNIX(path, factory)
+        unix.listenUNIX(path, factory)
     if xroot.get_xend_relocation_server():
         port = xroot.get_xend_relocation_port()
         interface = xroot.get_xend_relocation_address()
-        l = reactor.listenTCP(port, factory, interface=interface)
+        l = tcp.listenTCP(port, factory, interface=interface)
         l.setCloExec()
 
 def setupRelocation(dst, port):
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py     Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/server/tpmif.py     Sat Oct  8 20:28:24 2005
@@ -37,11 +37,24 @@
 
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
-        
+
         devid = int(sxp.child_value(config, 'instance', '0'))
-        log.debug("The domain has a TPM with instance %d." % devid)
+        log.info("The domain has a TPM with instance %d." % devid)
 
         back  = { 'instance' : "%i" % devid }
         front = { 'handle' : "%i" % devid }
 
         return (devid, back, front)
+
+    def configuration(self, devid):
+
+        result = DevController.configuration(self, devid)
+
+        (instance) = self.readBackend(devif,
+                                      'instance')
+
+        if instance:
+            result.append(['instance', instance])
+            log.info("configuration: instance=%d." % instance)
+
+        return result
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/xenstore/__init__.py
--- a/tools/python/xen/xend/xenstore/__init__.py        Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/xenstore/__init__.py        Sat Oct  8 20:28:24 2005
@@ -14,5 +14,3 @@
 #============================================================================
 # Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
 #============================================================================
-from xsnode import *
-from xsobj import *
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/xenstore/xsutil.py
--- a/tools/python/xen/xend/xenstore/xsutil.py  Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/xenstore/xsutil.py  Sat Oct  8 20:28:24 2005
@@ -7,14 +7,17 @@
 import threading
 from xen.lowlevel import xs
 
-handles = {}
+xs_lock = threading.Lock()
+xs_handle = None
 
-# XXX need to g/c handles from dead threads
 def xshandle():
-    if not handles.has_key(threading.currentThread()):
-        handles[threading.currentThread()] = xs.open()
-    return handles[threading.currentThread()]
-
+    global xs_handle, xs_lock
+    if not xs_handle:
+        xs_lock.acquire()
+        if not xs_handle:
+            xs_handle = xs.open()
+        xs_lock.release()
+    return xs_handle
 
 def IntroduceDomain(domid, page, port, path):
     return xshandle().introduce_domain(domid, page, port, path)
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/xenstore/xswatch.py
--- a/tools/python/xen/xend/xenstore/xswatch.py Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/xenstore/xswatch.py Sat Oct  8 20:28:24 2005
@@ -12,7 +12,6 @@
 class xswatch:
 
     watchThread = None
-    threadcond = threading.Condition()
     xs = None
     xslock = threading.Lock()
     
@@ -21,43 +20,31 @@
         self.args = args
         self.kwargs = kwargs
         xswatch.watchStart()
-        xswatch.xslock.acquire()
         xswatch.xs.watch(path, self)
-        xswatch.xslock.release()
 
     def watchStart(cls):
-        cls.threadcond.acquire()
+        cls.xslock.acquire()
         if cls.watchThread:
-            cls.threadcond.release()
+            cls.xslock.release()
             return
+        # XXX: When we fix xenstored to have better watch semantics,
+        # this can change to shared xshandle(). Currently that would result
+        # in duplicate watch firings, thus failed extra xs.acknowledge_watch.
+        cls.xs = xs.open()
         cls.watchThread = threading.Thread(name="Watcher",
                                            target=cls.watchMain)
         cls.watchThread.setDaemon(True)
         cls.watchThread.start()
-        while cls.xs == None:
-            cls.threadcond.wait()
-        cls.threadcond.release()
+        cls.xslock.release()
 
     watchStart = classmethod(watchStart)
 
     def watchMain(cls):
-        cls.threadcond.acquire()
-        cls.xs = xs.open()
-        cls.threadcond.notifyAll()
-        cls.threadcond.release()
         while True:
             try:
-                (fd, _1, _2) = select.select([ cls.xs ], [], [])
-                cls.xslock.acquire()
-                # reconfirm ready to read with lock
-                (fd, _1, _2) = select.select([ cls.xs ], [], [], 0.001)
-                if not cls.xs in fd:
-                    cls.xslock.release()
-                    continue
                 we = cls.xs.read_watch()
                 watch = we[1]
                 cls.xs.acknowledge_watch(watch)
-                cls.xslock.release()
             except RuntimeError, ex:
                 print ex
                 raise
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xm/create.py     Sat Oct  8 20:28:24 2005
@@ -163,10 +163,46 @@
 
 gopts.var('restart', val='onreboot|always|never',
           fn=set_value, default=None,
-          use="""Whether the domain should be restarted on exit.
+          use="""Deprecated.  Use on_poweroff, on_reboot, and on_crash
+          instead.
+
+          Whether the domain should be restarted on exit.
           - onreboot: restart on exit with shutdown code reboot
           - always:   always restart on exit, ignore exit code
           - never:    never restart on exit, ignore exit code""")
+
+gopts.var('on_poweroff', val='destroy|restart|preserve|rename-restart',
+          fn=set_value, default=None,
+          use="""Behaviour when a domain exits with reason 'poweroff'.
+          - destroy:        the domain is cleaned up as normal;
+          - restart:        a new domain is started in place of the old one;
+          - preserve:       no clean-up is done until the domain is manually
+                            destroyed (using xm destroy, for example);
+          - rename-restart: the old domain is not cleaned up, but is
+                            renamed and a new domain started in its place.
+          """)
+
+gopts.var('on_reboot', val='destroy|restart|preserve|rename-restart',
+          fn=set_value, default=None,
+          use="""Behaviour when a domain exits with reason 'reboot'.
+          - destroy:        the domain is cleaned up as normal;
+          - restart:        a new domain is started in place of the old one;
+          - preserve:       no clean-up is done until the domain is manually
+                            destroyed (using xm destroy, for example);
+          - rename-restart: the old domain is not cleaned up, but is
+                            renamed and a new domain started in its place.
+          """)
+
+gopts.var('on_crash', val='destroy|restart|preserve|rename-restart',
+          fn=set_value, default=None,
+          use="""Behaviour  when a domain exits with reason 'crash'.
+          - destroy:        the domain is cleaned up as normal;
+          - restart:        a new domain is started in place of the old one;
+          - preserve:       no clean-up is done until the domain is manually
+                            destroyed (using xm destroy, for example);
+          - rename-restart: the old domain is not cleaned up, but is
+                            renamed and a new domain started in its place.
+          """)
 
 gopts.var('blkif', val='no|yes',
           fn=set_bool, default=0,
@@ -536,6 +572,12 @@
         config.append(['backend', ['tpmif']])
     if vals.restart:
         config.append(['restart', vals.restart])
+    if vals.on_poweroff:
+        config.append(['on_poweroff', vals.on_poweroff])
+    if vals.on_reboot:
+        config.append(['on_reboot', vals.on_reboot])
+    if vals.on_crash:
+        config.append(['on_crash', vals.on_crash])
 
     if vals.bootloader:
         config.append(['bootloader', vals.bootloader])
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xm/destroy.py
--- a/tools/python/xen/xm/destroy.py    Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xm/destroy.py    Sat Oct  8 20:28:24 2005
@@ -21,18 +21,14 @@
 from xen.xend.XendClient import server
 from xen.xm.opts import *
 
-gopts = Opts(use="""[options] [DOM]
+gopts = Opts(use="""[DOM]
 
-Destroy a domain, optionally restarting it.
+Destroy a domain.
 """)
 
 gopts.opt('help', short='h',
          fn=set_true, default=0,
          use="Print this help.")
-
-gopts.opt('reboot', short='R',
-          fn=set_true, default=0,
-          use='Destroy and restart.')
 
 def main(argv):
     opts = gopts
@@ -42,10 +38,4 @@
         return
     if len(args) < 1: opts.err('Missing domain')
     dom = args[0]
-    if opts.vals.reboot:
-        mode = 'reboot'
-    else:
-        mode = 'halt'
-    server.xend_domain_destroy(dom, mode)
-    
-        
+    server.xend_domain_destroy(dom)
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xm/main.py       Sat Oct  8 20:28:24 2005
@@ -30,9 +30,15 @@
 import socket
 import warnings
 warnings.filterwarnings('ignore', category=FutureWarning)
+
+import xen.xend.XendError
+import xen.xend.XendProtocol
+
 from xen.xend import PrettyPrint
 from xen.xend import sxp
 from xen.xm.opts import *
+
+
 shorthelp = """Usage: xm <subcommand> [args]
     Control, list, and manipulate Xen guest instances
 
@@ -80,8 +86,8 @@
     shutdown [-w|-a] <DomId>  shutdown a domain
     sysrq   <DomId> <letter>  send a sysrq to a domain
     unpause <DomId>           unpause a paused domain
-    vcpu-enable <DomId> <VCPU>        disable VCPU in a domain
-    vcpu-disable <DomId> <VCPU>       enable VCPU in a domain
+    vcpu-enable <DomId> <VCPU>        enable VCPU in a domain
+    vcpu-disable <DomId> <VCPU>       disable VCPU in a domain
     vcpu-list <DomId>                 get the list of VCPUs for a domain
     vcpu-pin <DomId> <VCpu> <CPUS>    set which cpus a VCPU can use. 
 
@@ -100,9 +106,10 @@
   Virtual Device Commands:
     block-attach  <DomId> <BackDev> <FrontDev> <Mode> [BackDomId]
         Create a new virtual block device 
-    block-detach  <DomId> <DevId>  Destroy a domain's virtual block device
+    block-detach  <DomId> <DevId>  Destroy a domain's virtual block device,
+                                   where <DevId> may either be the device ID
+                                   or the device name as mounted in the guest.
     block-list    <DomId>          List virtual block devices for a domain
-    block-refresh <DomId> <DevId>  Refresh a virtual block device for a domain
     network-limit   <DomId> <Vif> <Credit> <Period>
         Limit the transmission rate of a virtual network interface
     network-list    <DomId>        List virtual network interfaces for a domain
@@ -159,6 +166,9 @@
     error = str(ex)
     if error == "Not found" and dom != None:
         err("Domain '%s' not found when running 'xm %s'" % (dom, cmd))
+        sys.exit(1)
+    elif error == "Exception: Device not connected":
+        err("Device not connected")
         sys.exit(1)
     else:
         raise ex
@@ -513,15 +523,6 @@
     from xen.xend.XendClient import server
     server.xend_domain_device_create(dom, vbd)
 
-def xm_block_refresh(args):
-    arg_check(args,2,"block-refresh")
-
-    dom = args[0]
-    dev = args[1]
-
-    from xen.xend.XendClient import server
-    server.xend_domain_device_refresh(dom, 'vbd', dev)
-
 def xm_block_detach(args):
     arg_check(args,2,"block-detach")
 
@@ -608,7 +609,6 @@
     "block-attach": xm_block_attach,
     "block-detach": xm_block_detach,
     "block-list": xm_block_list,
-    "block-refresh": xm_block_refresh,
     # network
     "network-limit": xm_network_limit,
     "network-list": xm_network_list,
@@ -637,7 +637,6 @@
     "vbd-create": "block-create",
     "vbd-destroy": "block-destroy",
     "vbd-list": "block-list",
-    "vbd-refresh": "block-refresh",
     }
 
 help = {
@@ -687,7 +686,6 @@
     args = argv[2:]
     if cmd:
         try:
-            from xen.xend.XendClient import XendError
             rc = cmd(args)
             if rc:
                 usage()
@@ -698,7 +696,15 @@
         except IOError:
             err("Most commands need root access.  Please try again as root")
             sys.exit(1)
-        except XendError, ex:
+        except xen.xend.XendError.XendError, ex:
+            if len(args) > 0:
+                handle_xend_error(argv[1], args[0], ex)
+            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[0], ex)
             else:
@@ -719,6 +725,3 @@
 
 if __name__ == "__main__":
     main()
-
-
-
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py   Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xm/shutdown.py   Sat Oct  8 20:28:24 2005
@@ -73,19 +73,15 @@
         opts.info("All domains terminated")
 
 def shutdown_mode(opts):
-    mode = 'poweroff'
-    if opts.vals.wait:
-        mode = 'halt'
-        if opts.vals.reboot:
-           opts.err("Can't specify wait and reboot") 
+    if opts.vals.halt and opts.vals.reboot:
+        opts.err("Can't specify halt and reboot")
+
+    if opts.vals.halt:
+        return 'halt'
+    elif opts.vals.reboot:
+        return 'reboot'
     else:
-        if opts.vals.halt and opts.vals.reboot:
-            opts.err("Can't specify halt and reboot")
-        if opts.vals.halt:
-            mode = 'halt'
-        elif opts.vals.reboot:
-            mode = 'reboot'
-    return mode
+        return 'poweroff'
 
 def main_all(opts, args):
     mode = shutdown_mode(opts)  
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c   Sat Oct  8 17:37:45 2005
+++ b/tools/tests/test_x86_emulator.c   Sat Oct  8 20:28:24 2005
@@ -78,7 +78,7 @@
 
 int main(int argc, char **argv)
 {
-    struct xen_regs regs;
+    struct cpu_user_regs regs;
     char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
     unsigned int res = 0x7FFFFFFF;
     u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 };
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstat/libxenstat/Makefile
--- a/tools/xenstat/libxenstat/Makefile Sat Oct  8 17:37:45 2005
+++ b/tools/xenstat/libxenstat/Makefile Sat Oct  8 20:28:24 2005
@@ -38,9 +38,7 @@
 
 WARN_FLAGS=-Wall -Werror
 
-CFLAGS+=-Isrc
-CFLAGS+=-I$(XEN_ROOT)/xen/include/public
-CFLAGS+=-I$(LINUX_ROOT)/include/asm-xen/linux-public/
+CFLAGS+=-Isrc -I$(XEN_LIBXC)
 LDFLAGS+=-Lsrc
 
 all: $(LIB)
diff -r 0ba10f7fef51 -r 4e0c94871be2 
tools/xenstat/libxenstat/src/xen-interface.c
--- a/tools/xenstat/libxenstat/src/xen-interface.c      Sat Oct  8 17:37:45 2005
+++ b/tools/xenstat/libxenstat/src/xen-interface.c      Sat Oct  8 20:28:24 2005
@@ -23,9 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include "version.h"
-#include "privcmd.h"
-#include "xen.h"
+#include <xen/linux/privcmd.h>
 
 struct xi_handle {
        int fd;
diff -r 0ba10f7fef51 -r 4e0c94871be2 
tools/xenstat/libxenstat/src/xen-interface.h
--- a/tools/xenstat/libxenstat/src/xen-interface.h      Sat Oct  8 17:37:45 2005
+++ b/tools/xenstat/libxenstat/src/xen-interface.h      Sat Oct  8 20:28:24 2005
@@ -26,8 +26,10 @@
 typedef uint32_t u32;
 typedef uint64_t u64;
 
-#include "dom0_ops.h"
-#include "version.h"
+#include <xen/xen.h>
+#include <xen/dom0_ops.h>
+#include <xen/sched.h>
+#include <xen/version.h>
 
 /* Opaque handles */
 typedef struct xi_handle xi_handle;
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c    Sat Oct  8 17:37:45 2005
+++ b/tools/xenstat/libxenstat/src/xenstat.c    Sat Oct  8 20:28:24 2005
@@ -22,7 +22,6 @@
 #include <unistd.h>
 #include <xen-interface.h>
 #include "xenstat.h"
-#include "version.h"
 
 /*
  * Types
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/Makefile   Sat Oct  8 20:28:24 2005
@@ -15,7 +15,6 @@
 BASECFLAGS+= -O3 $(PROFILE)
 #BASECFLAGS+= -I$(XEN_ROOT)/tools
 BASECFLAGS+= -I$(XEN_ROOT)/tools/libxc
-BASECFLAGS+= -I$(XEN_ROOT)/xen/include/public
 BASECFLAGS+= -I.
 
 CFLAGS  += $(BASECFLAGS)
@@ -30,12 +29,11 @@
 
 all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump
 
-testcode: xs_test xenstored_test xs_random xs_dom0_test
+testcode: xs_test xenstored_test xs_random
 
 xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
 
-$(CLIENTS): libxenstore.so
 $(CLIENTS): xenstore-%: xenstore_%.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
 
@@ -48,6 +46,7 @@
 xs_tdb_dump: xs_tdb_dump.o utils.o tdb.o talloc.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
 
+xs_test xs_random xs_stress xs_crashme: LDFLAGS+=-lpthread
 xs_test: xs_test.o xs_lib.o utils.o
 xs_random: xs_random.o xs_test_lib.o xs_lib.o talloc.o utils.o
 xs_stress: xs_stress.o xs_test_lib.o xs_lib.o talloc.o utils.o
@@ -70,12 +69,12 @@
        $(COMPILE.c) -o $@ $<
 
 libxenstore.so: xs.opic xs_lib.opic
-       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenstore.so -shared -o $@ 
$^
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenstore.so -shared -o $@ 
$^ -lpthread
 
 clean: testsuite-clean
        rm -f *.o *.opic *.so
        rm -f xenstored xs_random xs_stress xs_crashme
-       rm -f xs_test xenstored_test xs_dom0_test
+       rm -f xs_test xenstored_test
        $(RM) $(PROG_DEP)
 
 print-dir:
@@ -121,9 +120,6 @@
        rm -rf $(TESTDIR)/store $(TESTDIR)/transactions
        export $(TESTENV); PID=`./xenstored_test --output-pid 
--trace-file=/tmp/trace`; ./xs_stress 5000; ret=$$?; kill $$PID; exit $$ret
 
-xs_dom0_test: xs_dom0_test.o utils.o
-       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
-
 TAGS:
        etags `find . -name '*.[ch]'`
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/fake_libxc.c
--- a/tools/xenstore/fake_libxc.c       Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/fake_libxc.c       Sat Oct  8 20:28:24 2005
@@ -36,12 +36,11 @@
 static u16 port;
 
 /* The event channel maps to a signal, shared page to an mmapped file. */
-int xc_evtchn_send(int xc_handle __attribute__((unused)), int local_port)
+void evtchn_notify(int local_port)
 {
        assert(local_port == port);
        if (kill(xs_test_pid, SIGUSR2) != 0)
                barf_perror("fake event channel failed");
-       return 0;
 }
 
 void *xc_map_foreign_range(int xc_handle, u32 dom __attribute__((unused)),
@@ -107,15 +106,6 @@
        return 1;
 }
 
-int xc_evtchn_bind_virq(int xc_handle __attribute__((unused)),
-                       int virq __attribute__((unused)),
-                       int *port)
-{
-       if (port)
-               *port = 0;
-       return 0;
-}
-
 static void send_to_fd(int signo __attribute__((unused)))
 {
        int saved_errno = errno;
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/speedtest.c
--- a/tools/xenstore/speedtest.c        Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/speedtest.c        Sat Oct  8 20:28:24 2005
@@ -98,7 +98,7 @@
 
                if (i % print == 0)
                        write(1, ".", 1);
-               if (!xs_transaction_start(h, "/")) {
+               if (!xs_transaction_start(h)) {
                        kill_daemon(pid);
                        barf_perror("Starting transaction");
                }
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/testsuite/12readonly.test
--- a/tools/xenstore/testsuite/12readonly.test  Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/testsuite/12readonly.test  Sat Oct  8 20:28:24 2005
@@ -27,8 +27,6 @@
 setperm /test 100 NONE
 expect setperm failed: Permission denied
 setperm /test 100 NONE
-expect shutdown failed: Permission denied
-shutdown
 expect introduce failed: Permission denied
 introduce 1 100 7 /home
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/testsuite/test.sh
--- a/tools/xenstore/testsuite/test.sh  Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/testsuite/test.sh  Sat Oct  8 20:28:24 2005
@@ -23,7 +23,8 @@
            cat testsuite/tmp/xenstored_errors
            return 1
        fi
-       echo shutdown | ./xs_test
+       kill $PID
+       sleep 1
        return 0
     else
        # In case daemon is wedged.
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xenstored_core.c   Sat Oct  8 20:28:24 2005
@@ -44,13 +44,14 @@
 #include "list.h"
 #include "talloc.h"
 #include "xs_lib.h"
-#include "xenstored.h"
 #include "xenstored_core.h"
 #include "xenstored_watch.h"
 #include "xenstored_transaction.h"
 #include "xenstored_domain.h"
 #include "xenctrl.h"
 #include "tdb.h"
+
+int event_fd;
 
 static bool verbose;
 LIST_HEAD(connections);
@@ -149,7 +150,6 @@
 {
        switch (type) {
        case XS_DEBUG: return "DEBUG";
-       case XS_SHUTDOWN: return "SHUTDOWN";
        case XS_DIRECTORY: return "DIRECTORY";
        case XS_READ: return "READ";
        case XS_GET_PERMS: return "GET_PERMS";
@@ -309,8 +309,7 @@
        return 0;
 }
 
-static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock,
-                         int event_fd)
+static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock)
 {
        struct connection *i;
        int max;
@@ -1082,17 +1081,6 @@
        case XS_SET_PERMS:
                do_set_perms(conn, in);
                break;
-
-       case XS_SHUTDOWN:
-               /* FIXME: Implement gentle shutdown too. */
-               /* Only tools can do this. */
-               if (conn->id != 0 || !conn->can_write) {
-                       send_error(conn, EACCES);
-                       break;
-               }
-               send_ack(conn, XS_SHUTDOWN);
-               /* Everything hangs off auto-free context, freed at exit. */
-               exit(0);
 
        case XS_DEBUG:
                if (streq(in->buffer, "print"))
@@ -1464,7 +1452,7 @@
 
 int main(int argc, char *argv[])
 {
-       int opt, *sock, *ro_sock, event_fd, max;
+       int opt, *sock, *ro_sock, max;
        struct sockaddr_un addr;
        fd_set inset, outset;
        bool dofork = true;
@@ -1568,7 +1556,7 @@
 #endif
 
        /* Get ready to listen to the tools. */
-       max = initialize_set(&inset, &outset, *sock, *ro_sock, event_fd);
+       max = initialize_set(&inset, &outset, *sock, *ro_sock);
 
        /* Main loop. */
        /* FIXME: Rewrite so noone can starve. */
@@ -1588,7 +1576,7 @@
                        accept_connection(*ro_sock, false);
 
                if (FD_ISSET(event_fd, &inset))
-                       handle_event(event_fd);
+                       handle_event();
 
                list_for_each_entry(i, &connections, list) {
                        if (i->domain)
@@ -1624,7 +1612,6 @@
                        }
                }
 
-               max = initialize_set(&inset, &outset, *sock, *ro_sock,
-                                    event_fd);
-       }
-}
+               max = initialize_set(&inset, &outset, *sock, *ro_sock);
+       }
+}
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xenstored_core.h
--- a/tools/xenstore/xenstored_core.h   Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xenstored_core.h   Sat Oct  8 20:28:24 2005
@@ -26,7 +26,6 @@
 #include <stdint.h>
 #include <errno.h>
 #include "xs_lib.h"
-#include "xenstored.h"
 #include "list.h"
 #include "tdb.h"
 
@@ -173,4 +172,6 @@
 void trace_watch_timeout(const struct connection *conn, const char *node, 
const char *token);
 void trace(const char *fmt, ...);
 
+extern int event_fd;
+
 #endif /* _XENSTORED_CORE_H */
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xenstored_domain.c Sat Oct  8 20:28:24 2005
@@ -36,6 +36,8 @@
 #include "xenstored_watch.h"
 #include "xenstored_test.h"
 
+#include <xen/linux/evtchn.h>
+
 static int *xc_handle;
 static int eventchn_fd;
 static int virq_port;
@@ -77,8 +79,16 @@
        char buf[0];
 } __attribute__((packed));
 
-#define EVENTCHN_BIND          _IO('E', 2)
-#define EVENTCHN_UNBIND        _IO('E', 3)
+#ifndef TESTING
+static void evtchn_notify(int port)
+{
+       struct ioctl_evtchn_notify notify;
+       notify.port = port;
+       (void)ioctl(event_fd, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+#else
+extern void evtchn_notify(int port);
+#endif
 
 /* FIXME: Mark connection as broken (close it?) when this happens. */
 static bool check_buffer(const struct ringbuf_head *h)
@@ -165,9 +175,7 @@
        memcpy(dest, data, len);
        mb();
        update_output_chunk(conn->domain->output, len);
-       /* FIXME: Probably not neccessary. */
-       mb();
-       xc_evtchn_send(*xc_handle, conn->domain->port);
+       evtchn_notify(conn->domain->port);
        return len;
 }
 
@@ -200,21 +208,24 @@
 
        /* If it was full, tell them we've taken some. */
        if (was_full)
-               xc_evtchn_send(*xc_handle, conn->domain->port);
+               evtchn_notify(conn->domain->port);
        return len;
 }
 
 static int destroy_domain(void *_domain)
 {
        struct domain *domain = _domain;
+       struct ioctl_evtchn_unbind unbind;
 
        list_del(&domain->list);
 
-       if (domain->port &&
-           (ioctl(eventchn_fd, EVENTCHN_UNBIND, domain->port) != 0))
-               eprintf("> Unbinding port %i failed!\n", domain->port);
-
-       if(domain->page)
+       if (domain->port) {
+               unbind.port = domain->port;
+               if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1)
+                       eprintf("> Unbinding port %i failed!\n", domain->port);
+       }
+
+       if (domain->page)
                munmap(domain->page, getpagesize());
 
        return 0;
@@ -247,7 +258,7 @@
 }
 
 /* We scan all domains rather than use the information given here. */
-void handle_event(int event_fd)
+void handle_event(void)
 {
        u16 port;
 
@@ -278,6 +289,9 @@
                                 const char *path)
 {
        struct domain *domain;
+       struct ioctl_evtchn_bind_interdomain bind;
+       int rc;
+
        domain = talloc(context, struct domain);
        domain->port = 0;
        domain->shutdown = 0;
@@ -298,10 +312,13 @@
        domain->output = domain->page + getpagesize()/2;
 
        /* Tell kernel we're interested in this event. */
-       if (ioctl(eventchn_fd, EVENTCHN_BIND, port) != 0)
+       bind.remote_domain = domid;
+       bind.remote_port   = port;
+       rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+       if (rc == -1)
                return NULL;
 
-       domain->port = port;
+       domain->port = rc;
        domain->conn = new_connection(writechn, readchn);
        domain->conn->domain = domain;
        return domain;
@@ -445,6 +462,8 @@
 int domain_init(void)
 {
        struct stat st;
+       struct ioctl_evtchn_bind_virq bind;
+       int rc;
 
        /* The size of the ringbuffer: half a page minus head structure. */
        ringbuf_datasize = getpagesize() / 2 - sizeof(struct ringbuf_head);
@@ -482,11 +501,11 @@
        if (eventchn_fd < 0)
                barf_perror("Failed to open evtchn device");
 
-       if (xc_evtchn_bind_virq(*xc_handle, VIRQ_DOM_EXC, &virq_port))
-               barf_perror("Failed to bind to domain exception virq");
-
-       if (ioctl(eventchn_fd, EVENTCHN_BIND, virq_port) != 0)
+       bind.virq = VIRQ_DOM_EXC;
+       rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
+       if (rc == -1)
                barf_perror("Failed to bind to domain exception virq port");
+       virq_port = rc;
 
        return eventchn_fd;
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xenstored_domain.h Sat Oct  8 20:28:24 2005
@@ -20,7 +20,7 @@
 #ifndef _XENSTORED_DOMAIN_H
 #define _XENSTORED_DOMAIN_H
 
-void handle_event(int event_fd);
+void handle_event(void);
 
 /* domid, mfn, eventchn, path */
 void do_introduce(struct connection *conn, struct buffered_data *in);
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xs.c       Sat Oct  8 20:28:24 2005
@@ -32,84 +32,153 @@
 #include <stdint.h>
 #include <errno.h>
 #include <sys/ioctl.h>
+#include <pthread.h>
 #include "xs.h"
-#include "xenstored.h"
-#include "xs_lib.h"
+#include "list.h"
 #include "utils.h"
 
-struct xs_handle
-{
+struct xs_stored_msg {
+       struct list_head list;
+       struct xsd_sockmsg hdr;
+       char *body;
+};
+
+struct xs_handle {
+       /* Communications channel to xenstore daemon. */
        int fd;
+
+       /*
+         * A read thread which pulls messages off the comms channel and
+         * signals waiters.
+         */
+       pthread_t read_thr;
+
+       /*
+         * A list of fired watch messages, protected by a mutex. Users can
+         * wait on the conditional variable until a watch is pending.
+         */
+       struct list_head watch_list;
+       pthread_mutex_t watch_mutex;
+       pthread_cond_t watch_condvar;
+
+       /* Clients can select() on this pipe to wait for a watch to fire. */
+       int watch_pipe[2];
+
+       /*
+         * A list of replies. Currently only one will ever be outstanding
+         * because we serialise requests. The requester can wait on the
+         * conditional variable for its response.
+         */
+       struct list_head reply_list;
+       pthread_mutex_t reply_mutex;
+       pthread_cond_t reply_condvar;
+
+       /* One request at a time. */
+       pthread_mutex_t request_mutex;
+
+       /* One transaction at a time. */
+       pthread_mutex_t transaction_mutex;
 };
 
-/* Get the socket from the store daemon handle.
- */
+static void *read_thread(void *arg);
+
 int xs_fileno(struct xs_handle *h)
 {
-       return h->fd;
-}
-
-static struct xs_handle *get_socket(const char *connect_to)
+       char c = 0;
+
+       pthread_mutex_lock(&h->watch_mutex);
+
+       if ((h->watch_pipe[0] == -1) && (pipe(h->watch_pipe) != -1)) {
+               /* Kick things off if the watch list is already non-empty. */
+               if (!list_empty(&h->watch_list))
+                       while (write(h->watch_pipe[1], &c, 1) != 1)
+                               continue;
+       }
+
+       pthread_mutex_unlock(&h->watch_mutex);
+
+       return h->watch_pipe[0];
+}
+
+static int get_socket(const char *connect_to)
 {
        struct sockaddr_un addr;
        int sock, saved_errno;
-       struct xs_handle *h = NULL;
 
        sock = socket(PF_UNIX, SOCK_STREAM, 0);
        if (sock < 0)
-               return NULL;
+               return -1;
 
        addr.sun_family = AF_UNIX;
        strcpy(addr.sun_path, connect_to);
 
-       if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
-               h = malloc(sizeof(*h));
-               if (h) {
-                       h->fd = sock;
-                       return h;
-               }
-       }
-
+       if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
+               saved_errno = errno;
+               close(sock);
+               errno = saved_errno;
+               return -1;
+       }
+
+       return sock;
+}
+
+static int get_dev(const char *connect_to)
+{
+       return open(connect_to, O_RDWR);
+}
+
+static struct xs_handle *get_handle(const char *connect_to)
+{
+       struct stat buf;
+       struct xs_handle *h = NULL;
+       int fd = -1, saved_errno;
+
+       if (stat(connect_to, &buf) != 0)
+               goto error;
+
+       if (S_ISSOCK(buf.st_mode))
+               fd = get_socket(connect_to);
+       else
+               fd = get_dev(connect_to);
+
+       if (fd == -1)
+               goto error;
+
+       h = malloc(sizeof(*h));
+       if (h == NULL)
+               goto error;
+
+       h->fd = fd;
+
+       /* Watch pipe is allocated on demand in xs_fileno(). */
+       h->watch_pipe[0] = h->watch_pipe[1] = -1;
+
+       INIT_LIST_HEAD(&h->watch_list);
+       pthread_mutex_init(&h->watch_mutex, NULL);
+       pthread_cond_init(&h->watch_condvar, NULL);
+
+       INIT_LIST_HEAD(&h->reply_list);
+       pthread_mutex_init(&h->reply_mutex, NULL);
+       pthread_cond_init(&h->reply_condvar, NULL);
+
+       pthread_mutex_init(&h->request_mutex, NULL);
+       pthread_mutex_init(&h->transaction_mutex, NULL);
+
+       if (pthread_create(&h->read_thr, NULL, read_thread, h) != 0)
+               goto error;
+
+       return h;
+
+ error:
        saved_errno = errno;
-       close(sock);
+       if (h != NULL)
+               free(h);
+       if (fd != -1)
+               close(fd);
        errno = saved_errno;
        return NULL;
 }
 
-static struct xs_handle *get_dev(const char *connect_to)
-{
-       int fd, saved_errno;
-       struct xs_handle *h;
-
-       fd = open(connect_to, O_RDWR);
-       if (fd < 0)
-               return NULL;
-
-       h = malloc(sizeof(*h));
-       if (h) {
-               h->fd = fd;
-               return h;
-       }
-
-       saved_errno = errno;
-       close(fd);
-       errno = saved_errno;
-       return NULL;
-}
-
-static struct xs_handle *get_handle(const char *connect_to)
-{
-       struct stat buf;
-
-       if (stat(connect_to, &buf) != 0)
-               return NULL;
-
-       if (S_ISSOCK(buf.st_mode))
-               return get_socket(connect_to);
-       else
-               return get_dev(connect_to);
-}
-
 struct xs_handle *xs_daemon_open(void)
 {
        return get_handle(xs_daemon_socket());
@@ -127,8 +196,39 @@
 
 void xs_daemon_close(struct xs_handle *h)
 {
-       if (h->fd >= 0)
-               close(h->fd);
+       struct xs_stored_msg *msg, *tmsg;
+
+       pthread_mutex_lock(&h->transaction_mutex);
+       pthread_mutex_lock(&h->request_mutex);
+       pthread_mutex_lock(&h->reply_mutex);
+       pthread_mutex_lock(&h->watch_mutex);
+
+       /* XXX FIXME: May leak an unpublished message buffer. */
+       pthread_cancel(h->read_thr);
+       pthread_join(h->read_thr, NULL);
+
+       list_for_each_entry_safe(msg, tmsg, &h->reply_list, list) {
+               free(msg->body);
+               free(msg);
+       }
+
+       list_for_each_entry_safe(msg, tmsg, &h->watch_list, list) {
+               free(msg->body);
+               free(msg);
+       }
+
+       pthread_mutex_unlock(&h->transaction_mutex);
+       pthread_mutex_unlock(&h->request_mutex);
+       pthread_mutex_unlock(&h->reply_mutex);
+       pthread_mutex_unlock(&h->watch_mutex);
+
+       if (h->watch_pipe[0] != -1) {
+               close(h->watch_pipe[0]);
+               close(h->watch_pipe[1]);
+       }
+
+       close(h->fd);
+
        free(h);
 }
 
@@ -171,31 +271,28 @@
 }
 
 /* Adds extra nul terminator, because we generally (always?) hold strings. */
-static void *read_reply(int fd, enum xsd_sockmsg_type *type, unsigned int *len)
-{
-       struct xsd_sockmsg msg;
-       void *ret;
-       int saved_errno;
-
-       if (!read_all(fd, &msg, sizeof(msg)))
-               return NULL;
-
-       ret = malloc(msg.len + 1);
-       if (!ret)
-               return NULL;
-
-       if (!read_all(fd, ret, msg.len)) {
-               saved_errno = errno;
-               free(ret);
-               errno = saved_errno;
-               return NULL;
-       }
-
-       *type = msg.type;
+static void *read_reply(
+       struct xs_handle *h, enum xsd_sockmsg_type *type, unsigned int *len)
+{
+       struct xs_stored_msg *msg;
+       char *body;
+
+       pthread_mutex_lock(&h->reply_mutex);
+       while (list_empty(&h->reply_list))
+               pthread_cond_wait(&h->reply_condvar, &h->reply_mutex);
+       msg = list_top(&h->reply_list, struct xs_stored_msg, list);
+       list_del(&msg->list);
+       assert(list_empty(&h->reply_list));
+       pthread_mutex_unlock(&h->reply_mutex);
+
+       *type = msg->hdr.type;
        if (len)
-               *len = msg.len;
-       ((char *)ret)[msg.len] = '\0';
-       return ret;
+               *len = msg->hdr.len;
+       body = msg->body;
+
+       free(msg);
+
+       return body;
 }
 
 /* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
@@ -219,6 +316,8 @@
        ignorepipe.sa_flags = 0;
        sigaction(SIGPIPE, &ignorepipe, &oldact);
 
+       pthread_mutex_lock(&h->request_mutex);
+
        if (!xs_write_all(h->fd, &msg, sizeof(msg)))
                goto fail;
 
@@ -226,14 +325,11 @@
                if (!xs_write_all(h->fd, iovec[i].iov_base, iovec[i].iov_len))
                        goto fail;
 
-       /* Watches can have fired before reply comes: daemon detects
-        * and re-transmits, so we can ignore this. */
-       do {
-               free(ret);
-               ret = read_reply(h->fd, &msg.type, len);
-               if (!ret)
-                       goto fail;
-       } while (msg.type == XS_WATCH_EVENT);
+       ret = read_reply(h, &msg.type, len);
+       if (!ret)
+               goto fail;
+
+       pthread_mutex_unlock(&h->request_mutex);
 
        sigaction(SIGPIPE, &oldact, NULL);
        if (msg.type == XS_ERROR) {
@@ -254,6 +350,7 @@
 fail:
        /* We're in a bad state, so close fd. */
        saved_errno = errno;
+       pthread_mutex_unlock(&h->request_mutex);
        sigaction(SIGPIPE, &oldact, NULL);
 close_fd:
        close(h->fd);
@@ -449,25 +546,50 @@
  * Returns array of two pointers: path and token, or NULL.
  * Call free() after use.
  */
-char **xs_read_watch(struct xs_handle *h)
-{
-       struct xsd_sockmsg msg;
-       char **ret;
-
-       if (!read_all(h->fd, &msg, sizeof(msg)))
+char **xs_read_watch(struct xs_handle *h, unsigned int *num)
+{
+       struct xs_stored_msg *msg;
+       char **ret, *strings, c = 0;
+       unsigned int num_strings, i;
+
+       pthread_mutex_lock(&h->watch_mutex);
+
+       /* Wait on the condition variable for a watch to fire. */
+       while (list_empty(&h->watch_list))
+               pthread_cond_wait(&h->watch_condvar, &h->watch_mutex);
+       msg = list_top(&h->watch_list, struct xs_stored_msg, list);
+       list_del(&msg->list);
+
+       /* Clear the pipe token if there are no more pending watches. */
+       if (list_empty(&h->watch_list) && (h->watch_pipe[0] != -1))
+               while (read(h->watch_pipe[0], &c, 1) != 1)
+                       continue;
+
+       pthread_mutex_unlock(&h->watch_mutex);
+
+       assert(msg->hdr.type == XS_WATCH_EVENT);
+
+       strings     = msg->body;
+       num_strings = xs_count_strings(strings, msg->hdr.len);
+
+       ret = malloc(sizeof(char*) * num_strings + msg->hdr.len);
+       if (!ret) {
+               free_no_errno(strings);
+               free_no_errno(msg);
                return NULL;
-
-       assert(msg.type == XS_WATCH_EVENT);
-       ret = malloc(sizeof(char *)*2 + msg.len);
-       if (!ret)
-               return NULL;
-
-       ret[0] = (char *)(ret + 2);
-       if (!read_all(h->fd, ret[0], msg.len)) {
-               free_no_errno(ret);
-               return NULL;
-       }
-       ret[1] = ret[0] + strlen(ret[0]) + 1;
+       }
+
+       ret[0] = (char *)(ret + num_strings);
+       memcpy(ret[0], strings, msg->hdr.len);
+
+       free(strings);
+       free(msg);
+
+       for (i = 1; i < num_strings; i++)
+               ret[i] = ret[i - 1] + strlen(ret[i - 1]) + 1;
+
+       *num = num_strings;
+
        return ret;
 }
 
@@ -502,6 +624,7 @@
  */
 bool xs_transaction_start(struct xs_handle *h)
 {
+       pthread_mutex_lock(&h->transaction_mutex);
        return xs_bool(xs_single(h, XS_TRANSACTION_START, "", NULL));
 }
 
@@ -513,12 +636,18 @@
 bool xs_transaction_end(struct xs_handle *h, bool abort)
 {
        char abortstr[2];
+       bool rc;
 
        if (abort)
                strcpy(abortstr, "F");
        else
                strcpy(abortstr, "T");
-       return xs_bool(xs_single(h, XS_TRANSACTION_END, abortstr, NULL));
+       
+       rc = xs_bool(xs_single(h, XS_TRANSACTION_END, abortstr, NULL));
+
+       pthread_mutex_unlock(&h->transaction_mutex);
+
+       return rc;
 }
 
 /* Introduce a new domain.
@@ -567,18 +696,6 @@
        return xs_single(h, XS_GET_DOMAIN_PATH, domid_str, NULL);
 }
 
-bool xs_shutdown(struct xs_handle *h)
-{
-       bool ret = xs_bool(xs_single(h, XS_SHUTDOWN, "", NULL));
-       if (ret) {
-               char c;
-               /* Wait for it to actually shutdown. */
-               while ((read(h->fd, &c, 1) < 0) && (errno == EINTR))
-                       continue;
-       }
-       return ret;
-}
-
 /* Only useful for DEBUG versions */
 char *xs_debug_command(struct xs_handle *h, const char *cmd,
                       void *data, unsigned int len)
@@ -592,3 +709,75 @@
 
        return xs_talkv(h, XS_DEBUG, iov, ARRAY_SIZE(iov), NULL);
 }
+
+static void *read_thread(void *arg)
+{
+       struct xs_handle *h = arg;
+       struct xs_stored_msg *msg = NULL;
+       char *body = NULL;
+
+       for (;;) {
+               msg = NULL;
+               body = NULL;
+
+               /* Allocate message structure and read the message header. */
+               msg = malloc(sizeof(*msg));
+               if (msg == NULL)
+                       goto error;
+               if (!read_all(h->fd, &msg->hdr, sizeof(msg->hdr)))
+                       goto error;
+
+               /* Allocate and read the message body. */
+               body = msg->body = malloc(msg->hdr.len + 1);
+               if (body == NULL)
+                       goto error;
+               if (!read_all(h->fd, body, msg->hdr.len))
+                       goto error;
+               body[msg->hdr.len] = '\0';
+
+               if (msg->hdr.type == XS_WATCH_EVENT) {
+                       pthread_mutex_lock(&h->watch_mutex);
+
+                       /* Kick users out of their select() loop. */
+                       if (list_empty(&h->watch_list) &&
+                           (h->watch_pipe[1] != -1))
+                               while (write(h->watch_pipe[1], body, 1) != 1)
+                                       continue;
+
+                       list_add_tail(&msg->list, &h->watch_list);
+                       pthread_cond_signal(&h->watch_condvar);
+
+                       pthread_mutex_unlock(&h->watch_mutex);
+               } else {
+                       pthread_mutex_lock(&h->reply_mutex);
+
+                       /* There should only ever be one response pending! */
+                       if (!list_empty(&h->reply_list)) {
+                               pthread_mutex_unlock(&h->reply_mutex);
+                               goto error;
+                       }
+
+                       list_add_tail(&msg->list, &h->reply_list);
+                       pthread_cond_signal(&h->reply_condvar);
+
+                       pthread_mutex_unlock(&h->reply_mutex);
+               }
+       }
+
+ error:
+       if (body != NULL)
+               free(body);
+       if (msg != NULL)
+               free(msg);
+       return NULL;
+}
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xs.h       Sat Oct  8 20:28:24 2005
@@ -20,7 +20,7 @@
 #ifndef _XS_H
 #define _XS_H
 
-#include "xs_lib.h"
+#include <xs_lib.h>
 
 struct xs_handle;
 
@@ -91,10 +91,10 @@
 int xs_fileno(struct xs_handle *h);
 
 /* Find out what node change was on (will block if nothing pending).
- * Returns array of two pointers: path and token, or NULL.
- * Call free() after use.
+ * Returns array containing the path and token. Use XS_WATCH_* to access these
+ * elements. Call free() after use.
  */
-char **xs_read_watch(struct xs_handle *h);
+char **xs_read_watch(struct xs_handle *h, unsigned int *num);
 
 /* Acknowledge watch on node.  Watches must be acknowledged before
  * any other watches can be read.
@@ -141,7 +141,4 @@
 char *xs_debug_command(struct xs_handle *h, const char *cmd,
                       void *data, unsigned int len);
 
-/* Shut down the daemon. */
-bool xs_shutdown(struct xs_handle *h);
-
 #endif /* _XS_H */
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xs_crashme.c
--- a/tools/xenstore/xs_crashme.c       Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xs_crashme.c       Sat Oct  8 20:28:24 2005
@@ -24,7 +24,6 @@
 #include "xs.h"
 #include "talloc.h"
 #include <errno.h>
-#include "xenstored.h"
 
 #define XSTEST
 #define RAND_FREQ 128          /* One char in 32 is corrupted. */
@@ -231,20 +230,6 @@
        return ret;
 }
 
-static int random_flags(int *state)
-{
-       switch (get_randomness(state) % 4) {
-       case 0:
-               return 0;
-       case 1:
-               return O_CREAT;
-       case 2:
-               return O_CREAT|O_EXCL;
-       default:
-               return get_randomness(state);
-       }
-}
-
 /* Do the next operation, return the results. */
 static void do_next_op(struct xs_handle *h, bool verbose)
 {
@@ -315,7 +300,7 @@
        case 7: {
                if (verbose)
                        printf("START %s\n", name);
-               xs_transaction_start(h, name);
+               xs_transaction_start(h);
                break;
        }
        case 8: {
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xs_lib.h
--- a/tools/xenstore/xs_lib.h   Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xs_lib.h   Sat Oct  8 20:28:24 2005
@@ -23,6 +23,8 @@
 #include <stdbool.h>
 #include <limits.h>
 #include <xenctrl.h>
+#include <errno.h>
+#include <xen/io/xs_wire.h>
 
 /* Bitmask of permissions. */
 enum xs_perm_type {
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xs_random.c
--- a/tools/xenstore/xs_random.c        Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xs_random.c        Sat Oct  8 20:28:24 2005
@@ -879,20 +879,11 @@
 static void cleanup_xs_ops(void)
 {
        char *cmd;
+
        if (daemon_pid) {
-               struct xs_handle *h;
-               h = xs_daemon_open();
-               if (h) {
-                       if (xs_shutdown(h)) {
-                               waitpid(daemon_pid, NULL, 0);
-                               daemon_pid = 0;
-                       }
-                       xs_daemon_close(h);
-               }
-               if (daemon_pid) {
-                       kill(daemon_pid, SIGTERM);
-                       waitpid(daemon_pid, NULL, 0);
-               }
+               kill(daemon_pid, SIGTERM);
+               waitpid(daemon_pid, NULL, 0);
+               daemon_pid = 0;
        }
        
        cmd = talloc_asprintf(NULL, "rm -rf testsuite/tmp/*");
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c  Sat Oct  8 17:37:45 2005
+++ b/tools/xenstore/xs_test.c  Sat Oct  8 20:28:24 2005
@@ -198,7 +198,6 @@
             "  rm <path>\n"
             "  getperm <path>\n"
             "  setperm <path> <id> <flags> ...\n"
-            "  shutdown\n"
             "  watch <path> <token>\n"
             "  watchnoack <path> <token>\n"
             "  waitwatch\n"
@@ -214,8 +213,6 @@
             "  notimeout\n"
             "  readonly\n"
             "  readwrite\n"
-            "  noackwrite <path> <value>...\n"
-            "  readack\n"
             "  dump\n");
 }
 
@@ -353,37 +350,6 @@
 {
        if (!xs_write(handles[handle], path, data, strlen(data)))
                failed(handle);
-}
-
-static void do_noackwrite(unsigned int handle,
-                         char *path, char *data)
-{
-       struct xsd_sockmsg msg;
-
-       msg.len = strlen(path) + 1 + strlen(data);
-       msg.type = XS_WRITE;
-       if (!write_all_choice(handles[handle]->fd, &msg, sizeof(msg)))
-               failed(handle);
-       if (!write_all_choice(handles[handle]->fd, path, strlen(path) + 1))
-               failed(handle);
-       if (!write_all_choice(handles[handle]->fd, data, strlen(data)))
-               failed(handle);
-       /* Do not wait for ack. */
-}
-
-static void do_readack(unsigned int handle)
-{
-       enum xsd_sockmsg_type type;
-       char *ret = NULL;
-
-       /* Watches can have fired before reply comes: daemon detects
-        * and re-transmits, so we can ignore this. */
-       do {
-               free(ret);
-               ret = read_reply(handles[handle]->fd, &type, NULL);
-               if (!ret)
-                       failed(handle);
-       } while (type == XS_WATCH_EVENT);
 }
 
 static void do_setid(unsigned int handle, char *id)
@@ -475,12 +441,6 @@
                failed(handle);
 }
 
-static void do_shutdown(unsigned int handle)
-{
-       if (!xs_shutdown(handles[handle]))
-               failed(handle);
-}
-
 static void do_watch(unsigned int handle, const char *node, const char *token,
                     bool swallow_event)
 {
@@ -489,8 +449,11 @@
 
        /* Convenient for testing... */
        if (swallow_event) {
-               char **vec = xs_read_watch(handles[handle]);
-               if (!vec || !streq(vec[0], node) || !streq(vec[1], token))
+               unsigned int num;
+               char **vec = xs_read_watch(handles[handle], &num);
+               if (!vec ||
+                   !streq(vec[XS_WATCH_PATH], node) ||
+                   !streq(vec[XS_WATCH_TOKEN], token))
                        failed(handle);
                if (!xs_acknowledge_watch(handles[handle], token))
                        failed(handle);
@@ -522,6 +485,7 @@
        struct timeval tv = {.tv_sec = timeout_ms/1000,
                             .tv_usec = (timeout_ms*1000)%1000000 };
        fd_set set;
+       unsigned int num;
 
        if (xs_fileno(handles[handle]) != -2) {
                /* Manually select here so we can time out gracefully. */
@@ -537,16 +501,17 @@
                set_timeout();
        }
 
-       vec = xs_read_watch(handles[handle]);
+       vec = xs_read_watch(handles[handle], &num);
        if (!vec) {
                failed(handle);
                return;
        }
 
        if (handle)
-               output("%i:%s:%s\n", handle, vec[0], vec[1]);
+               output("%i:%s:%s\n", handle,
+                      vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]);
        else
-               output("%s:%s\n", vec[0], vec[1]);
+               output("%s:%s\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]);
        free(vec);
 }
 
@@ -775,8 +740,6 @@
                do_getperm(handle, arg(line, 1));
        else if (streq(command, "setperm"))
                do_setperm(handle, arg(line, 1), line);
-       else if (streq(command, "shutdown"))
-               do_shutdown(handle);
        else if (streq(command, "watch"))
                do_watch(handle, arg(line, 1), arg(line, 2), true);
        else if (streq(command, "watchnoack"))
@@ -818,11 +781,7 @@
                readonly = false;
                xs_daemon_close(handles[handle]);
                handles[handle] = NULL;
-       } else if (streq(command, "noackwrite"))
-               do_noackwrite(handle, arg(line,1), arg(line,2));
-       else if (streq(command, "readack"))
-               do_readack(handle);
-       else
+       } else
                barf("Unknown command %s", command);
        fflush(stdout);
        disarm_timeout();
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/Makefile
--- a/xen/Makefile      Sat Oct  8 17:37:45 2005
+++ b/xen/Makefile      Sat Oct  8 20:28:24 2005
@@ -1,7 +1,3 @@
-# Default is to install to local 'dist' directory.
-DISTDIR ?= ../dist
-DESTDIR ?= $(DISTDIR)/install
-
 INSTALL                        = install
 INSTALL_DATA           = $(INSTALL) -m0644
 INSTALL_DIR            = $(INSTALL) -d -m0755
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/Rules.mk
--- a/xen/Rules.mk      Sat Oct  8 17:37:45 2005
+++ b/xen/Rules.mk      Sat Oct  8 20:28:24 2005
@@ -10,7 +10,8 @@
 domu_debug  ?= n
 crash_debug ?= n
 
-include $(BASEDIR)/../Config.mk
+XEN_ROOT=$(BASEDIR)/..
+include $(XEN_ROOT)/Config.mk
 
 # Set ARCH/SUBARCH appropriately.
 override COMPILE_SUBARCH := $(XEN_COMPILE_ARCH)
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/dom0_ops.c   Sat Oct  8 20:28:24 2005
@@ -186,7 +186,7 @@
         pi->sockets_per_node = 
             num_online_cpus() / (pi->threads_per_core * pi->cores_per_socket);
         pi->nr_nodes         = 1;
-        pi->total_pages      = max_page;
+        pi->total_pages      = total_pages;
         pi->free_pages       = avail_domheap_pages();
         pi->cpu_khz          = cpu_khz;
         memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/domain.c     Sat Oct  8 20:28:24 2005
@@ -323,47 +323,16 @@
 #ifdef CONFIG_VMX
 static int vmx_switch_on;
 
-static int vmx_final_setup_guest(
-    struct vcpu *v, struct vcpu_guest_context *ctxt)
-{
-    int error;
-    struct cpu_user_regs *regs;
-    struct vmcs_struct *vmcs;
-
-    regs = &ctxt->user_regs;
-
-    /*
-     * Create a new VMCS
-     */
-    if (!(vmcs = alloc_vmcs())) {
-        printk("Failed to create a new VMCS\n");
-        return -ENOMEM;
-    }
-
-    memset(&v->arch.arch_vmx, 0, sizeof (struct arch_vmx_struct));
-
-    v->arch.arch_vmx.vmcs = vmcs;
-    error = construct_vmcs(
-        &v->arch.arch_vmx, regs, ctxt, VMCS_USE_HOST_ENV);
-    if ( error < 0 )
-    {
-        printk("Failed to construct a new VMCS\n");
-        goto out;
-    }
-
+static void vmx_final_setup_guest(struct vcpu *v)
+{
     v->arch.schedule_tail = arch_vmx_do_launch;
 
-#if defined (__i386__)
-    v->domain->arch.vmx_platform.real_mode_data = 
-        (unsigned long *) regs->esi;
-#endif
-
     if (v == v->domain->vcpu[0]) {
-        /* 
+        /*
          * Required to do this once per domain
          * XXX todo: add a seperate function to do these.
          */
-        memset(&v->domain->shared_info->evtchn_mask[0], 0xff, 
+        memset(&v->domain->shared_info->evtchn_mask[0], 0xff,
                sizeof(v->domain->shared_info->evtchn_mask));
 
         /* Put the domain in shadow mode even though we're going to be using
@@ -375,23 +344,6 @@
 
     if (!vmx_switch_on)
         vmx_switch_on = 1;
-
-    return 0;
-
-out:
-    free_vmcs(vmcs);
-    if(v->arch.arch_vmx.io_bitmap_a != 0) {
-        free_xenheap_pages(
-            v->arch.arch_vmx.io_bitmap_a, get_order_from_bytes(0x1000));
-        v->arch.arch_vmx.io_bitmap_a = 0;
-    }
-    if(v->arch.arch_vmx.io_bitmap_b != 0) {
-        free_xenheap_pages(
-            v->arch.arch_vmx.io_bitmap_b, get_order_from_bytes(0x1000));
-        v->arch.arch_vmx.io_bitmap_b = 0;
-    }
-    v->arch.arch_vmx.vmcs = 0;
-    return error;
 }
 #endif
 
@@ -480,8 +432,7 @@
         if ( !pagetable_get_paddr(d->arch.phys_table) )
             d->arch.phys_table = v->arch.guest_table;
 
-        if ( (rc = vmx_final_setup_guest(v, c)) != 0 )
-            return rc;
+        vmx_final_setup_guest(v);
     }
 
     update_pagetables(v);
@@ -968,20 +919,7 @@
     if ( !VMX_DOMAIN(v) )
         return;
 
-    BUG_ON(v->arch.arch_vmx.vmcs == NULL);
-    free_vmcs(v->arch.arch_vmx.vmcs);
-    if(v->arch.arch_vmx.io_bitmap_a != 0) {
-        free_xenheap_pages(
-            v->arch.arch_vmx.io_bitmap_a, get_order_from_bytes(0x1000));
-        v->arch.arch_vmx.io_bitmap_a = 0;
-    }
-    if(v->arch.arch_vmx.io_bitmap_b != 0) {
-        free_xenheap_pages(
-            v->arch.arch_vmx.io_bitmap_b, get_order_from_bytes(0x1000));
-        v->arch.arch_vmx.io_bitmap_b = 0;
-    }
-    v->arch.arch_vmx.vmcs = 0;
-    
+    destroy_vmcs(&v->arch.arch_vmx);
     free_monitor_pagetable(v);
     rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer);
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/mm.c Sat Oct  8 20:28:24 2005
@@ -147,6 +147,7 @@
 /* Frame table and its size in pages. */
 struct pfn_info *frame_table;
 unsigned long max_page;
+unsigned long total_pages;
 
 void __init init_frametable(void)
 {
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/setup.c      Sat Oct  8 20:28:24 2005
@@ -418,6 +418,7 @@
     printk("System RAM: %luMB (%lukB)\n", 
            nr_pages >> (20 - PAGE_SHIFT),
            nr_pages << (PAGE_SHIFT - 10));
+    total_pages = nr_pages;
 
     init_frametable();
 
@@ -474,13 +475,14 @@
     {
         static char dom0_cmdline[MAX_GUEST_CMDLINE];
 
-        /* Skip past the image name. */
+        /* Skip past the image name and copy to a local buffer. */
         while ( *cmdline == ' ' ) cmdline++;
         if ( (cmdline = strchr(cmdline, ' ')) != NULL )
+        {
             while ( *cmdline == ' ' ) cmdline++;
-
-        /* Copy the command line to a local buffer. */
-        strcpy(dom0_cmdline, cmdline);
+            strcpy(dom0_cmdline, cmdline);
+        }
+
         cmdline = dom0_cmdline;
 
         /* Append any extra parameters. */
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/traps.c      Sat Oct  8 20:28:24 2005
@@ -895,6 +895,14 @@
             *reg = pagetable_get_paddr(v->arch.guest_table);
             break;
 
+        case 4: /* Read CR4 */
+            /*
+             * Guests can read CR4 to see what features Xen has enabled. We
+             * therefore lie about PGE & PSE as they are unavailable to guests.
+             */
+            *reg = read_cr4() & ~(X86_CR4_PGE|X86_CR4_PSE);
+            break;
+
         default:
             goto fail;
         }
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/vmx.c        Sat Oct  8 20:28:24 2005
@@ -41,14 +41,12 @@
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/shadow_64.h>
 #endif
-
+#include <public/sched.h>
 #include <public/io/ioreq.h>
 
 int hvm_enabled;
 
 #ifdef CONFIG_VMX
-
-int vmcs_size;
 unsigned int opt_vmx_debug_level = 0;
 integer_param("vmx_debug", opt_vmx_debug_level);
 
@@ -71,7 +69,7 @@
 /*
  * To avoid MSR save/restore at every VM exit/entry time, we restore
  * the x86_64 specific MSRs at domain switch time. Since those MSRs are
- * are not modified once set for generic domains, we don't save them, 
+ * are not modified once set for generic domains, we don't save them,
  * but simply reset them to the values set at percpu_traps_init().
  */
 void vmx_load_msrs(struct vcpu *n)
@@ -162,13 +160,13 @@
 
 static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
-    u64     msr_content = regs->eax | ((u64)regs->edx << 32); 
+    u64     msr_content = regs->eax | ((u64)regs->edx << 32);
     struct vcpu *vc = current;
     struct msr_state * msr = &vc->arch.arch_vmx.msr_content;
-    struct msr_state * host_state = 
+    struct msr_state * host_state =
         &percpu_msr[smp_processor_id()];
 
-    VMX_DBG_LOG(DBG_LEVEL_1, " mode_do_msr_write msr %lx msr_content %lx\n", 
+    VMX_DBG_LOG(DBG_LEVEL_1, " mode_do_msr_write msr %lx msr_content %lx\n",
                 regs->ecx, msr_content);
 
     switch (regs->ecx){
@@ -191,11 +189,11 @@
             msr_content;
         if (msr_content & ~(EFER_LME | EFER_LMA)){
             msr->msr_items[VMX_INDEX_MSR_EFER] = msr_content;
-            if (!test_bit(VMX_INDEX_MSR_EFER, &msr->flags)){ 
+            if (!test_bit(VMX_INDEX_MSR_EFER, &msr->flags)){
                 rdmsrl(MSR_EFER,
                        host_state->msr_items[VMX_INDEX_MSR_EFER]);
                 set_bit(VMX_INDEX_MSR_EFER, &host_state->flags);
-                set_bit(VMX_INDEX_MSR_EFER, &msr->flags);  
+                set_bit(VMX_INDEX_MSR_EFER, &msr->flags);
                 wrmsrl(MSR_EFER, msr_content);
             }
         }
@@ -211,7 +209,7 @@
         }
         if (regs->ecx == MSR_FS_BASE)
             __vmwrite(GUEST_FS_BASE, msr_content);
-        else 
+        else
             __vmwrite(GUEST_GS_BASE, msr_content);
         break;
 
@@ -233,14 +231,14 @@
 }
 
 void
-vmx_restore_msrs(struct vcpu *d)
+vmx_restore_msrs(struct vcpu *v)
 {
     int i = 0;
     struct msr_state *guest_state;
     struct msr_state *host_state;
     unsigned long guest_flags ;
 
-    guest_state = &d->arch.arch_vmx.msr_content;;
+    guest_state = &v->arch.arch_vmx.msr_content;;
     host_state = &percpu_msr[smp_processor_id()];
 
     wrmsrl(MSR_SHADOW_GS_BASE, guest_state->shadow_gs);
@@ -276,13 +274,13 @@
 void do_nmi(struct cpu_user_regs *, unsigned long);
 
 static int check_vmx_controls(ctrls, msr)
-{   
-    u32 vmx_msr_low, vmx_msr_high; 
+{
+    u32 vmx_msr_low, vmx_msr_high;
 
     rdmsr(msr, vmx_msr_low, vmx_msr_high);
     if (ctrls < vmx_msr_low || ctrls > vmx_msr_high) {
         printk("Insufficient VMX capability 0x%x, "
-               "msr=0x%x,low=0x%8x,high=0x%x\n", 
+               "msr=0x%x,low=0x%8x,high=0x%x\n",
                ctrls, msr, vmx_msr_low, vmx_msr_high);
         return 0;
     }
@@ -304,7 +302,7 @@
 
     if (!(test_bit(X86_FEATURE_VMXE, &boot_cpu_data.x86_capability)))
         return 0;
- 
+
     rdmsr(IA32_FEATURE_CONTROL_MSR, eax, edx);
 
     if (eax & IA32_FEATURE_CONTROL_MSR_LOCK) {
@@ -314,28 +312,28 @@
         }
     }
     else {
-        wrmsr(IA32_FEATURE_CONTROL_MSR, 
+        wrmsr(IA32_FEATURE_CONTROL_MSR,
               IA32_FEATURE_CONTROL_MSR_LOCK |
               IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON, 0);
     }
 
-    if (!check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS, 
+    if (!check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
                             MSR_IA32_VMX_PINBASED_CTLS_MSR))
         return 0;
-    if (!check_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS, 
+    if (!check_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
                             MSR_IA32_VMX_PROCBASED_CTLS_MSR))
         return 0;
-    if (!check_vmx_controls(MONITOR_VM_EXIT_CONTROLS, 
+    if (!check_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
                             MSR_IA32_VMX_EXIT_CTLS_MSR))
         return 0;
-    if (!check_vmx_controls(MONITOR_VM_ENTRY_CONTROLS, 
+    if (!check_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
                             MSR_IA32_VMX_ENTRY_CTLS_MSR))
         return 0;
 
     set_in_cr4(X86_CR4_VMXE);   /* Enable VMXE */
 
     if (!(vmcs = alloc_vmcs())) {
-        printk("Failed to allocate VMCS\n");    
+        printk("Failed to allocate VMCS\n");
         return 0;
     }
 
@@ -366,7 +364,7 @@
      if ((len) < 1 || (len) > 15) \
         __vmx_bug(&regs);
 
-static void inline __update_guest_eip(unsigned long inst_len) 
+static void inline __update_guest_eip(unsigned long inst_len)
 {
     unsigned long current_eip;
 
@@ -375,7 +373,7 @@
 }
 
 
-static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs) 
+static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
 {
     unsigned long gpa; /* FIXME: PAE */
     int result;
@@ -385,7 +383,7 @@
         unsigned long eip;
 
         __vmread(GUEST_RIP, &eip);
-        VMX_DBG_LOG(DBG_LEVEL_VMMU, 
+        VMX_DBG_LOG(DBG_LEVEL_VMMU,
                     "vmx_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
                     va, eip, (unsigned long)regs->error_code);
     }
@@ -427,12 +425,13 @@
 static void vmx_do_no_device_fault(void)
 {
     unsigned long cr0;
-        
+    struct vcpu *v = current;
+
     clts();
     setup_fpu(current);
-    __vmread_vcpu(CR0_READ_SHADOW, &cr0);
+    __vmread_vcpu(v, CR0_READ_SHADOW, &cr0);
     if (!(cr0 & X86_CR0_TS)) {
-        __vmread_vcpu(GUEST_CR0, &cr0);
+        __vmread_vcpu(v, GUEST_CR0, &cr0);
         cr0 &= ~X86_CR0_TS;
         __vmwrite(GUEST_CR0, cr0);
     }
@@ -440,14 +439,14 @@
 }
 
 
-static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs 
*regs) 
+static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs 
*regs)
 {
     unsigned int eax, ebx, ecx, edx;
     unsigned long eip;
 
     __vmread(GUEST_RIP, &eip);
 
-    VMX_DBG_LOG(DBG_LEVEL_1, 
+    VMX_DBG_LOG(DBG_LEVEL_1,
                 "do_cpuid: (eax) %lx, (ebx) %lx, (ecx) %lx, (edx) %lx,"
                 " (esi) %lx, (edi) %lx",
                 (unsigned long)regs->eax, (unsigned long)regs->ebx,
@@ -462,8 +461,8 @@
         clear_bit(X86_FEATURE_PAE, &edx);
         clear_bit(X86_FEATURE_PSE36, &edx);
 #else
-        struct vcpu *d = current;
-        if (d->domain->arch.ops->guest_paging_levels == PAGING_L2)
+        struct vcpu *v = current;
+        if (v->domain->arch.ops->guest_paging_levels == PAGING_L2)
         {
             clear_bit(X86_FEATURE_PSE, &edx);
             clear_bit(X86_FEATURE_PAE, &edx);
@@ -480,7 +479,7 @@
     regs->ecx = (unsigned long) ecx;
     regs->edx = (unsigned long) edx;
 
-    VMX_DBG_LOG(DBG_LEVEL_1, 
+    VMX_DBG_LOG(DBG_LEVEL_1,
                 "vmx_vmexit_do_cpuid: eip: %lx, input: %lx, out:eax=%x, 
ebx=%x, ecx=%x, edx=%x",
                 eip, input, eax, ebx, ecx, edx);
 
@@ -500,7 +499,7 @@
 
     reg = exit_qualification & DEBUG_REG_ACCESS_NUM;
 
-    VMX_DBG_LOG(DBG_LEVEL_1, 
+    VMX_DBG_LOG(DBG_LEVEL_1,
                 "vmx_dr_access : eip=%lx, reg=%d, exit_qualification = %lx",
                 eip, reg, exit_qualification);
 
@@ -513,16 +512,16 @@
         CASE_GET_REG_P(ESI, esi);
         CASE_GET_REG_P(EDI, edi);
     case REG_ESP:
-        break;  
+        break;
     default:
         __vmx_bug(regs);
     }
-        
+
     switch (exit_qualification & DEBUG_REG_ACCESS_TYPE) {
-    case TYPE_MOV_TO_DR: 
+    case TYPE_MOV_TO_DR:
         /* don't need to check the range */
         if (reg != REG_ESP)
-            v->arch.guest_context.debugreg[reg] = *reg_p; 
+            v->arch.guest_context.debugreg[reg] = *reg_p;
         else {
             unsigned long value;
             __vmread(GUEST_RSP, &value);
@@ -543,7 +542,7 @@
  * Invalidate the TLB for va. Invalidate the shadow page corresponding
  * the address va.
  */
-static void vmx_vmexit_do_invlpg(unsigned long va) 
+static void vmx_vmexit_do_invlpg(unsigned long va)
 {
     unsigned long eip;
     struct vcpu *v = current;
@@ -658,24 +657,24 @@
     vmx_wait_io();
 }
 
-static void vmx_io_instruction(struct cpu_user_regs *regs, 
-                               unsigned long exit_qualification, unsigned long 
inst_len) 
-{
-    struct mi_per_cpu_info *mpcip;
+static void vmx_io_instruction(struct cpu_user_regs *regs,
+                               unsigned long exit_qualification, unsigned long 
inst_len)
+{
+    struct mmio_op *mmio_opp;
     unsigned long eip, cs, eflags;
     unsigned long port, size, dir;
     int vm86;
 
-    mpcip = &current->domain->arch.vmx_platform.mpci;
-    mpcip->instr = INSTR_PIO;
-    mpcip->flags = 0;
+    mmio_opp = &current->arch.arch_vmx.mmio_op;
+    mmio_opp->instr = INSTR_PIO;
+    mmio_opp->flags = 0;
 
     __vmread(GUEST_RIP, &eip);
     __vmread(GUEST_CS_SELECTOR, &cs);
     __vmread(GUEST_RFLAGS, &eflags);
     vm86 = eflags & X86_EFLAGS_VM ? 1 : 0;
 
-    VMX_DBG_LOG(DBG_LEVEL_1, 
+    VMX_DBG_LOG(DBG_LEVEL_1,
                 "vmx_io_instruction: vm86 %d, eip=%lx:%lx, "
                 "exit_qualification = %lx",
                 vm86, cs, eip, exit_qualification);
@@ -702,7 +701,7 @@
             addr = dir == IOREQ_WRITE ? regs->esi : regs->edi;
 
         if (test_bit(5, &exit_qualification)) { /* "rep" prefix */
-            mpcip->flags |= REPZ;
+            mmio_opp->flags |= REPZ;
             count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
         }
 
@@ -713,7 +712,7 @@
         if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
             unsigned long value = 0;
 
-            mpcip->flags |= OVERLAP;
+            mmio_opp->flags |= OVERLAP;
             if (dir == IOREQ_WRITE)
                 vmx_copy(&value, addr, size, VMX_COPY_IN);
             send_pio_req(regs, port, 1, size, value, dir, 0);
@@ -772,7 +771,7 @@
 }
 
 int
-vmx_world_save(struct vcpu *d, struct vmx_assist_context *c)
+vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
 {
     unsigned long inst_len;
     int error = 0;
@@ -784,7 +783,7 @@
     error |= __vmread(GUEST_RFLAGS, &c->eflags);
 
     error |= __vmread(CR0_READ_SHADOW, &c->cr0);
-    c->cr3 = d->arch.arch_vmx.cpu_cr3;
+    c->cr3 = v->arch.arch_vmx.cpu_cr3;
     error |= __vmread(CR4_READ_SHADOW, &c->cr4);
 
     error |= __vmread(GUEST_IDTR_LIMIT, &c->idtr_limit);
@@ -837,7 +836,7 @@
 }
 
 int
-vmx_world_restore(struct vcpu *d, struct vmx_assist_context *c)
+vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
 {
     unsigned long mfn, old_cr4;
     int error = 0;
@@ -848,45 +847,45 @@
 
     error |= __vmwrite(CR0_READ_SHADOW, c->cr0);
 
-    if (!vmx_paging_enabled(d)) {
+    if (!vmx_paging_enabled(v)) {
         VMX_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table");
-        __vmwrite(GUEST_CR3, pagetable_get_paddr(d->domain->arch.phys_table));
+        __vmwrite(GUEST_CR3, pagetable_get_paddr(v->domain->arch.phys_table));
         goto skip_cr3;
     }
 
-    if (c->cr3 == d->arch.arch_vmx.cpu_cr3) {
-        /* 
-         * This is simple TLB flush, implying the guest has 
+    if (c->cr3 == v->arch.arch_vmx.cpu_cr3) {
+        /*
+         * This is simple TLB flush, implying the guest has
          * removed some translation or changed page attributes.
          * We simply invalidate the shadow.
          */
         mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT);
-        if (mfn != pagetable_get_pfn(d->arch.guest_table)) {
+        if (mfn != pagetable_get_pfn(v->arch.guest_table)) {
             printk("Invalid CR3 value=%x", c->cr3);
             domain_crash_synchronous();
             return 0;
         }
-        shadow_sync_all(d->domain);
+        shadow_sync_all(v->domain);
     } else {
         /*
          * If different, make a shadow. Check if the PDBR is valid
          * first.
          */
         VMX_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %x", c->cr3);
-        if ((c->cr3 >> PAGE_SHIFT) > d->domain->max_pages) {
+        if ((c->cr3 >> PAGE_SHIFT) > v->domain->max_pages) {
             printk("Invalid CR3 value=%x", c->cr3);
-            domain_crash_synchronous(); 
+            domain_crash_synchronous();
             return 0;
         }
         mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT);
-        d->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
-        update_pagetables(d);
-        /* 
+        v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
+        update_pagetables(v);
+        /*
          * arch.shadow_table should now hold the next CR3 for shadow
          */
-        d->arch.arch_vmx.cpu_cr3 = c->cr3;
+        v->arch.arch_vmx.cpu_cr3 = c->cr3;
         VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %x", c->cr3);
-        __vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
+        __vmwrite(GUEST_CR3, pagetable_get_paddr(v->arch.shadow_table));
     }
 
  skip_cr3:
@@ -947,7 +946,7 @@
 enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
 
 int
-vmx_assist(struct vcpu *d, int mode)
+vmx_assist(struct vcpu *v, int mode)
 {
     struct vmx_assist_context c;
     u32 magic;
@@ -971,7 +970,7 @@
         if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN))
             goto error;
         if (cp != 0) {
-            if (!vmx_world_save(d, &c))
+            if (!vmx_world_save(v, &c))
                 goto error;
             if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_OUT))
                 goto error;
@@ -983,7 +982,7 @@
         if (cp != 0) {
             if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN))
                 goto error;
-            if (!vmx_world_restore(d, &c))
+            if (!vmx_world_restore(v, &c))
                 goto error;
             return 1;
         }
@@ -1000,7 +999,7 @@
         if (cp != 0) {
             if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN))
                 goto error;
-            if (!vmx_world_restore(d, &c))
+            if (!vmx_world_restore(v, &c))
                 goto error;
             return 1;
         }
@@ -1009,21 +1008,21 @@
 
  error:
     printf("Failed to transfer to vmxassist\n");
-    domain_crash_synchronous(); 
+    domain_crash_synchronous();
     return 0;
 }
 
 static int vmx_set_cr0(unsigned long value)
 {
-    struct vcpu *d = current;
+    struct vcpu *v = current;
     unsigned long mfn;
     unsigned long eip;
     int paging_enabled;
     unsigned long vm_entry_value;
-    /* 
+    /*
      * CR0: We don't want to lose PE and PG.
      */
-    paging_enabled = vmx_paging_enabled(d);
+    paging_enabled = vmx_paging_enabled(v);
     __vmwrite(GUEST_CR0, value | X86_CR0_PE | X86_CR0_PG | X86_CR0_NE);
     __vmwrite(CR0_READ_SHADOW, value);
 
@@ -1034,33 +1033,33 @@
          * The guest CR3 must be pointing to the guest physical.
          */
         if ( !VALID_MFN(mfn = get_mfn_from_pfn(
-            d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)) ||
-             !get_page(pfn_to_page(mfn), d->domain) )
+            v->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)) ||
+             !get_page(pfn_to_page(mfn), v->domain) )
         {
-            printk("Invalid CR3 value = %lx", d->arch.arch_vmx.cpu_cr3);
+            printk("Invalid CR3 value = %lx", v->arch.arch_vmx.cpu_cr3);
             domain_crash_synchronous(); /* need to take a clean path */
         }
 
 #if defined(__x86_64__)
         if (test_bit(VMX_CPU_STATE_LME_ENABLED,
-                     &d->arch.arch_vmx.cpu_state) &&
+                     &v->arch.arch_vmx.cpu_state) &&
             !test_bit(VMX_CPU_STATE_PAE_ENABLED,
-                      &d->arch.arch_vmx.cpu_state)){
+                      &v->arch.arch_vmx.cpu_state)){
             VMX_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
-            vmx_inject_exception(d, TRAP_gp_fault, 0);
+            vmx_inject_exception(v, TRAP_gp_fault, 0);
         }
         if (test_bit(VMX_CPU_STATE_LME_ENABLED,
-                     &d->arch.arch_vmx.cpu_state)){
+                     &v->arch.arch_vmx.cpu_state)){
             /* Here the PAE is should to be opened */
             VMX_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode\n");
             set_bit(VMX_CPU_STATE_LMA_ENABLED,
-                    &d->arch.arch_vmx.cpu_state);
+                    &v->arch.arch_vmx.cpu_state);
             __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
             vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE;
             __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
 
-#if CONFIG_PAGING_LEVELS >= 4 
-            if(!shadow_set_guest_paging_levels(d->domain, 4)) {
+#if CONFIG_PAGING_LEVELS >= 4
+            if(!shadow_set_guest_paging_levels(v->domain, 4)) {
                 printk("Unsupported guest paging levels\n");
                 domain_crash_synchronous(); /* need to take a clean path */
             }
@@ -1069,7 +1068,7 @@
         else
         {
 #if CONFIG_PAGING_LEVELS >= 4
-            if(!shadow_set_guest_paging_levels(d->domain, 2)) {
+            if(!shadow_set_guest_paging_levels(v->domain, 2)) {
                 printk("Unsupported guest paging levels\n");
                 domain_crash_synchronous(); /* need to take a clean path */
             }
@@ -1081,7 +1080,7 @@
         __vmread(GUEST_CR4, &crn);
         if ( (!(crn & X86_CR4_PAE)) &&
              test_bit(VMX_CPU_STATE_PAE_ENABLED,
-                      &d->arch.arch_vmx.cpu_state)){
+                      &v->arch.arch_vmx.cpu_state)){
             VMX_DBG_LOG(DBG_LEVEL_1, "enable PAE on cr4\n");
             __vmwrite(GUEST_CR4, crn | X86_CR4_PAE);
         }
@@ -1089,24 +1088,24 @@
         /*
          * Now arch.guest_table points to machine physical.
          */
-        d->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
-        update_pagetables(d);
-
-        VMX_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
+        v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
+        update_pagetables(v);
+
+        VMX_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                     (unsigned long) (mfn << PAGE_SHIFT));
 
-        __vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
-        /* 
+        __vmwrite(GUEST_CR3, pagetable_get_paddr(v->arch.shadow_table));
+        /*
          * arch->shadow_table should hold the next CR3 for shadow
          */
-        VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx", 
-                    d->arch.arch_vmx.cpu_cr3, mfn);
+        VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx",
+                    v->arch.arch_vmx.cpu_cr3, mfn);
     }
 
     if(!((value & X86_CR0_PE) && (value & X86_CR0_PG)) && paging_enabled)
-        if(d->arch.arch_vmx.cpu_cr3)
+        if(v->arch.arch_vmx.cpu_cr3)
             put_page(pfn_to_page(get_mfn_from_pfn(
-                      d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)));
+                      v->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)));
 
     /*
      * VMX does not implement real-mode virtualization. We emulate
@@ -1116,38 +1115,38 @@
     if ((value & X86_CR0_PE) == 0) {
         if ( value & X86_CR0_PG ) {
             /* inject GP here */
-            vmx_inject_exception(d, TRAP_gp_fault, 0);
+            vmx_inject_exception(v, TRAP_gp_fault, 0);
             return 0;
         } else {
-            /* 
+            /*
              * Disable paging here.
              * Same to PE == 1 && PG == 0
              */
             if (test_bit(VMX_CPU_STATE_LMA_ENABLED,
-                         &d->arch.arch_vmx.cpu_state)){
+                         &v->arch.arch_vmx.cpu_state)){
                 clear_bit(VMX_CPU_STATE_LMA_ENABLED,
-                          &d->arch.arch_vmx.cpu_state);
+                          &v->arch.arch_vmx.cpu_state);
                 __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
                 vm_entry_value &= ~VM_ENTRY_CONTROLS_IA32E_MODE;
                 __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
             }
         }
 
-        if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
-            set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &d->arch.arch_vmx.cpu_state);
+        if (vmx_assist(v, VMX_ASSIST_INVOKE)) {
+            set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &v->arch.arch_vmx.cpu_state);
             __vmread(GUEST_RIP, &eip);
             VMX_DBG_LOG(DBG_LEVEL_1,
                         "Transfering control to vmxassist %%eip 0x%lx\n", eip);
             return 0; /* do not update eip! */
         }
     } else if (test_bit(VMX_CPU_STATE_ASSIST_ENABLED,
-                        &d->arch.arch_vmx.cpu_state)) {
+                        &v->arch.arch_vmx.cpu_state)) {
         __vmread(GUEST_RIP, &eip);
         VMX_DBG_LOG(DBG_LEVEL_1,
                     "Enabling CR0.PE at %%eip 0x%lx\n", eip);
-        if (vmx_assist(d, VMX_ASSIST_RESTORE)) {
+        if (vmx_assist(v, VMX_ASSIST_RESTORE)) {
             clear_bit(VMX_CPU_STATE_ASSIST_ENABLED,
-                      &d->arch.arch_vmx.cpu_state);
+                      &v->arch.arch_vmx.cpu_state);
             __vmread(GUEST_RIP, &eip);
             VMX_DBG_LOG(DBG_LEVEL_1,
                         "Restoring to %%eip 0x%lx\n", eip);
@@ -1188,7 +1187,7 @@
 {
     unsigned long value;
     unsigned long old_cr;
-    struct vcpu *d = current;
+    struct vcpu *v = current;
 
     switch (gp) {
         CASE_GET_REG(EAX, eax);
@@ -1206,82 +1205,82 @@
         printk("invalid gp: %d\n", gp);
         __vmx_bug(regs);
     }
-    
+
     VMX_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
     VMX_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current);
 
     switch(cr) {
-    case 0: 
+    case 0:
     {
         return vmx_set_cr0(value);
     }
-    case 3: 
+    case 3:
     {
         unsigned long old_base_mfn, mfn;
 
         /*
          * If paging is not enabled yet, simply copy the value to CR3.
          */
-        if (!vmx_paging_enabled(d)) {
-            d->arch.arch_vmx.cpu_cr3 = value;
+        if (!vmx_paging_enabled(v)) {
+            v->arch.arch_vmx.cpu_cr3 = value;
             break;
         }
-        
+
         /*
          * We make a new one if the shadow does not exist.
          */
-        if (value == d->arch.arch_vmx.cpu_cr3) {
-            /* 
-             * This is simple TLB flush, implying the guest has 
+        if (value == v->arch.arch_vmx.cpu_cr3) {
+            /*
+             * This is simple TLB flush, implying the guest has
              * removed some translation or changed page attributes.
              * We simply invalidate the shadow.
              */
             mfn = get_mfn_from_pfn(value >> PAGE_SHIFT);
-            if (mfn != pagetable_get_pfn(d->arch.guest_table))
+            if (mfn != pagetable_get_pfn(v->arch.guest_table))
                 __vmx_bug(regs);
-            shadow_sync_all(d->domain);
+            shadow_sync_all(v->domain);
         } else {
             /*
              * If different, make a shadow. Check if the PDBR is valid
              * first.
              */
             VMX_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
-            if ( ((value >> PAGE_SHIFT) > d->domain->max_pages ) ||
+            if ( ((value >> PAGE_SHIFT) > v->domain->max_pages ) ||
                  !VALID_MFN(mfn = get_mfn_from_pfn(value >> PAGE_SHIFT)) ||
-                 !get_page(pfn_to_page(mfn), d->domain) )
+                 !get_page(pfn_to_page(mfn), v->domain) )
             {
                 printk("Invalid CR3 value=%lx", value);
                 domain_crash_synchronous(); /* need to take a clean path */
             }
-            old_base_mfn = pagetable_get_pfn(d->arch.guest_table);
-            d->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
+            old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
+            v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
             if (old_base_mfn)
                 put_page(pfn_to_page(old_base_mfn));
-            update_pagetables(d);
-            /* 
+            update_pagetables(v);
+            /*
              * arch.shadow_table should now hold the next CR3 for shadow
              */
-            d->arch.arch_vmx.cpu_cr3 = value;
+            v->arch.arch_vmx.cpu_cr3 = value;
             VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx",
                         value);
-            __vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
-        }
-        break;
-    }
-    case 4:         
+            __vmwrite(GUEST_CR3, pagetable_get_paddr(v->arch.shadow_table));
+        }
+        break;
+    }
+    case 4:
     {
         /* CR4 */
         unsigned long old_guest_cr;
 
         __vmread(GUEST_CR4, &old_guest_cr);
         if (value & X86_CR4_PAE){
-            set_bit(VMX_CPU_STATE_PAE_ENABLED, &d->arch.arch_vmx.cpu_state);
+            set_bit(VMX_CPU_STATE_PAE_ENABLED, &v->arch.arch_vmx.cpu_state);
         } else {
             if (test_bit(VMX_CPU_STATE_LMA_ENABLED,
-                         &d->arch.arch_vmx.cpu_state)){
-                vmx_inject_exception(d, TRAP_gp_fault, 0);
+                         &v->arch.arch_vmx.cpu_state)){
+                vmx_inject_exception(v, TRAP_gp_fault, 0);
             }
-            clear_bit(VMX_CPU_STATE_PAE_ENABLED, &d->arch.arch_vmx.cpu_state);
+            clear_bit(VMX_CPU_STATE_PAE_ENABLED, &v->arch.arch_vmx.cpu_state);
         }
 
         __vmread(CR4_READ_SHADOW, &old_cr);
@@ -1294,7 +1293,7 @@
          * all TLB entries except global entries.
          */
         if ((old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE)) {
-            shadow_sync_all(d->domain);
+            shadow_sync_all(v->domain);
         }
         break;
     }
@@ -1317,12 +1316,12 @@
 static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
 {
     unsigned long value;
-    struct vcpu *d = current;
+    struct vcpu *v = current;
 
     if (cr != 3)
         __vmx_bug(regs);
 
-    value = (unsigned long) d->arch.arch_vmx.cpu_cr3;
+    value = (unsigned long) v->arch.arch_vmx.cpu_cr3;
 
     switch (gp) {
         CASE_SET_REG(EAX, eax);
@@ -1349,6 +1348,7 @@
 {
     unsigned int gp, cr;
     unsigned long value;
+    struct vcpu *v = current;
 
     switch (exit_qualification & CONTROL_REG_ACCESS_TYPE) {
     case TYPE_MOV_TO_CR:
@@ -1371,17 +1371,17 @@
         clts();
         setup_fpu(current);
 
-        __vmread_vcpu(GUEST_CR0, &value);
+        __vmread_vcpu(v, GUEST_CR0, &value);
         value &= ~X86_CR0_TS; /* clear TS */
         __vmwrite(GUEST_CR0, value);
 
-        __vmread_vcpu(CR0_READ_SHADOW, &value);
+        __vmread_vcpu(v, CR0_READ_SHADOW, &value);
         value &= ~X86_CR0_TS; /* clear TS */
         __vmwrite(CR0_READ_SHADOW, value);
         break;
     case TYPE_LMSW:
         TRACE_VMEXIT(1,TYPE_LMSW);
-        __vmread_vcpu(CR0_READ_SHADOW, &value);
+        __vmread_vcpu(v, CR0_READ_SHADOW, &value);
         value = (value & ~0xF) |
             (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
         return vmx_set_cr0(value);
@@ -1398,7 +1398,7 @@
     u64 msr_content = 0;
 
     VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx",
-                (unsigned long)regs->ecx, (unsigned long)regs->eax, 
+                (unsigned long)regs->ecx, (unsigned long)regs->eax,
                 (unsigned long)regs->edx);
     switch (regs->ecx) {
     case MSR_IA32_SYSENTER_CS:
@@ -1431,7 +1431,7 @@
     u64 msr_content;
 
     VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write: ecx=%lx, eax=%lx, edx=%lx",
-                (unsigned long)regs->ecx, (unsigned long)regs->eax, 
+                (unsigned long)regs->ecx, (unsigned long)regs->eax,
                 (unsigned long)regs->edx);
 
     msr_content = (regs->eax & 0xFFFFFFFF) | ((u64)regs->edx << 32);
@@ -1518,7 +1518,7 @@
 char print_buf[BUF_SIZ];
 static int index;
 
-static void vmx_print_line(const char c, struct vcpu *d) 
+static void vmx_print_line(const char c, struct vcpu *v)
 {
 
     if (index == MAX_LINE || c == '\n') {
@@ -1526,7 +1526,7 @@
             print_buf[index++] = c;
         }
         print_buf[index] = '\0';
-        printk("(GUEST: %u) %s\n", d->domain->domain_id, (char *) &print_buf);
+        printk("(GUEST: %u) %s\n", v->domain->domain_id, (char *) &print_buf);
         index = 0;
     }
     else
@@ -1586,7 +1586,7 @@
 
     if ((error = __vmread(VM_EXIT_REASON, &exit_reason)))
         __vmx_bug(&regs);
-    
+
     perfc_incra(vmexits, exit_reason);
 
     __vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field);
@@ -1594,14 +1594,14 @@
         __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
 
         __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
-        if (inst_len >= 1 && inst_len <= 15) 
+        if (inst_len >= 1 && inst_len <= 15)
             __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
 
         if (idtv_info_field & 0x800) { /* valid error code */
             unsigned long error_code;
             __vmread(IDT_VECTORING_ERROR_CODE, &error_code);
             __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
-        } 
+        }
 
         VMX_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
     }
@@ -1614,7 +1614,7 @@
 
     if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
         printk("Failed vm entry\n");
-        domain_crash_synchronous();         
+        domain_crash_synchronous();
         return;
     }
 
@@ -1630,7 +1630,7 @@
     case EXIT_REASON_EXCEPTION_NMI:
     {
         /*
-         * We don't set the software-interrupt exiting (INT n). 
+         * We don't set the software-interrupt exiting (INT n).
          * (1) We can get an exception (e.g. #PG) in the guest, or
          * (2) NMI
          */
@@ -1682,22 +1682,22 @@
         case TRAP_no_device:
         {
             vmx_do_no_device_fault();
-            break;  
+            break;
         }
         case TRAP_page_fault:
         {
             __vmread(EXIT_QUALIFICATION, &va);
             __vmread(VM_EXIT_INTR_ERROR_CODE, &regs.error_code);
-            
+
             TRACE_VMEXIT(3,regs.error_code);
             TRACE_VMEXIT(4,va);
 
-            VMX_DBG_LOG(DBG_LEVEL_VMMU, 
+            VMX_DBG_LOG(DBG_LEVEL_VMMU,
                         "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
                         (unsigned long)regs.eax, (unsigned long)regs.ebx,
                         (unsigned long)regs.ecx, (unsigned long)regs.edx,
                         (unsigned long)regs.esi, (unsigned long)regs.edi);
-            v->domain->arch.vmx_platform.mpci.inst_decoder_regs = &regs;
+            v->arch.arch_vmx.mmio_op.inst_decoder_regs = &regs;
 
             if (!(error = vmx_do_page_fault(va, &regs))) {
                 /*
@@ -1718,11 +1718,11 @@
         }
         break;
     }
-    case EXIT_REASON_EXTERNAL_INTERRUPT: 
+    case EXIT_REASON_EXTERNAL_INTERRUPT:
         vmx_vmexit_do_extint(&regs);
         break;
     case EXIT_REASON_PENDING_INTERRUPT:
-        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, 
+        __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
                   MONITOR_CPU_BASED_EXEC_CONTROLS);
         break;
     case EXIT_REASON_TASK_SWITCH:
@@ -1762,7 +1762,7 @@
         __get_instruction_length(inst_len);
         __vmread(EXIT_QUALIFICATION, &exit_qualification);
 
-        VMX_DBG_LOG(DBG_LEVEL_1, "eip = %lx, inst_len =%lx, exit_qualification 
= %lx", 
+        VMX_DBG_LOG(DBG_LEVEL_1, "eip = %lx, inst_len =%lx, exit_qualification 
= %lx",
                     eip, inst_len, exit_qualification);
         if (vmx_cr_access(exit_qualification, &regs))
             __update_guest_eip(inst_len);
@@ -1771,7 +1771,7 @@
         break;
     }
     case EXIT_REASON_DR_ACCESS:
-        __vmread(EXIT_QUALIFICATION, &exit_qualification);  
+        __vmread(EXIT_QUALIFICATION, &exit_qualification);
         vmx_dr_access(exit_qualification, &regs);
         __get_instruction_length(inst_len);
         __update_guest_eip(inst_len);
@@ -1803,13 +1803,13 @@
 
 asmlinkage void load_cr2(void)
 {
-    struct vcpu *d = current;
-
-    local_irq_disable();        
+    struct vcpu *v = current;
+
+    local_irq_disable();
 #ifdef __i386__
-    asm volatile("movl %0,%%cr2": :"r" (d->arch.arch_vmx.cpu_cr2));
+    asm volatile("movl %0,%%cr2": :"r" (v->arch.arch_vmx.cpu_cr2));
 #else
-    asm volatile("movq %0,%%cr2": :"r" (d->arch.arch_vmx.cpu_cr2));
+    asm volatile("movq %0,%%cr2": :"r" (v->arch.arch_vmx.cpu_cr2));
 #endif
 }
 
@@ -1831,7 +1831,7 @@
     TRACE_3D(TRC_VMEXIT,0,0,0);
     return;
 }
-#endif 
+#endif
 #endif /* CONFIG_VMX */
 
 /*
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c     Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/vmx_io.c     Sat Oct  8 20:28:24 2005
@@ -1,5 +1,5 @@
 /*
- * vmx_io.c: handling I/O, interrupts related VMX entry/exit 
+ * vmx_io.c: handling I/O, interrupts related VMX entry/exit
  * Copyright (c) 2004, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
 #ifdef CONFIG_VMX
 #if defined (__i386__)
 void load_cpu_user_regs(struct cpu_user_regs *regs)
-{ 
+{
     /*
      * Write the guest register value into VMCS
      */
@@ -52,7 +52,7 @@
     __vmwrite(GUEST_RFLAGS, regs->eflags);
     if (regs->eflags & EF_TF)
         __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
-    else 
+    else
         __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
 
     __vmwrite(GUEST_CS_SELECTOR, regs->cs);
@@ -189,7 +189,7 @@
     __vmwrite(GUEST_RFLAGS, regs->rflags);
     if (regs->rflags & EF_TF)
         __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
-    else 
+    else
         __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
 
     __vmwrite(GUEST_CS_SELECTOR, regs->cs);
@@ -265,52 +265,52 @@
     }
 
     switch (index) {
-    case 0: 
+    case 0:
         __set_reg_value(&regs->rax, size, value);
         break;
-    case 1: 
+    case 1:
         __set_reg_value(&regs->rcx, size, value);
         break;
-    case 2: 
+    case 2:
         __set_reg_value(&regs->rdx, size, value);
         break;
-    case 3: 
+    case 3:
         __set_reg_value(&regs->rbx, size, value);
         break;
-    case 4: 
+    case 4:
         __set_reg_value(&regs->rsp, size, value);
         break;
-    case 5: 
+    case 5:
         __set_reg_value(&regs->rbp, size, value);
         break;
-    case 6: 
+    case 6:
         __set_reg_value(&regs->rsi, size, value);
         break;
-    case 7: 
+    case 7:
         __set_reg_value(&regs->rdi, size, value);
         break;
-    case 8: 
+    case 8:
         __set_reg_value(&regs->r8, size, value);
         break;
-    case 9: 
+    case 9:
         __set_reg_value(&regs->r9, size, value);
         break;
-    case 10: 
+    case 10:
         __set_reg_value(&regs->r10, size, value);
         break;
-    case 11: 
+    case 11:
         __set_reg_value(&regs->r11, size, value);
         break;
-    case 12: 
+    case 12:
         __set_reg_value(&regs->r12, size, value);
         break;
-    case 13: 
+    case 13:
         __set_reg_value(&regs->r13, size, value);
         break;
-    case 14: 
+    case 14:
         __set_reg_value(&regs->r14, size, value);
         break;
-    case 15: 
+    case 15:
         __set_reg_value(&regs->r15, size, value);
         break;
     default:
@@ -391,7 +391,7 @@
 }
 
 static void vmx_pio_assist(struct cpu_user_regs *regs, ioreq_t *p,
-                           struct mi_per_cpu_info *mpcip)
+                           struct mmio_op *mmio_opp)
 {
     unsigned long old_eax;
     int sign = p->df ? -1 : 1;
@@ -399,15 +399,15 @@
     if (p->dir == IOREQ_WRITE) {
         if (p->pdata_valid) {
             regs->esi += sign * p->count * p->size;
-            if (mpcip->flags & REPZ)
+            if (mmio_opp->flags & REPZ)
                 regs->ecx -= p->count;
         }
     } else {
-        if (mpcip->flags & OVERLAP) {
+        if (mmio_opp->flags & OVERLAP) {
             unsigned long addr;
 
             regs->edi += sign * p->count * p->size;
-            if (mpcip->flags & REPZ)
+            if (mmio_opp->flags & REPZ)
                 regs->ecx -= p->count;
 
             addr = regs->edi;
@@ -416,7 +416,7 @@
             vmx_copy(&p->u.data, addr, p->size, VMX_COPY_OUT);
         } else if (p->pdata_valid) {
             regs->edi += sign * p->count * p->size;
-            if (mpcip->flags & REPZ)
+            if (mmio_opp->flags & REPZ)
                 regs->ecx -= p->count;
         } else {
             old_eax = regs->eax;
@@ -439,18 +439,18 @@
 }
 
 static void vmx_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p,
-                            struct mi_per_cpu_info *mpcip)
+                            struct mmio_op *mmio_opp)
 {
     int sign = p->df ? -1 : 1;
     int size = -1, index = -1;
     unsigned long value = 0, diff = 0;
     unsigned long src, dst;
 
-    src = mpcip->operand[0];
-    dst = mpcip->operand[1];
+    src = mmio_opp->operand[0];
+    dst = mmio_opp->operand[1];
     size = operand_size(src);
 
-    switch (mpcip->instr) {
+    switch (mmio_opp->instr) {
     case INSTR_MOV:
         if (dst & REGISTER) {
             index = operand_index(dst);
@@ -475,7 +475,7 @@
         regs->esi += sign * p->count * p->size;
         regs->edi += sign * p->count * p->size;
 
-        if ((mpcip->flags & OVERLAP) && p->dir == IOREQ_READ) {
+        if ((mmio_opp->flags & OVERLAP) && p->dir == IOREQ_READ) {
             unsigned long addr = regs->edi;
 
             if (sign > 0)
@@ -483,14 +483,14 @@
             vmx_copy(&p->u.data, addr, p->size, VMX_COPY_OUT);
         }
 
-        if (mpcip->flags & REPZ)
+        if (mmio_opp->flags & REPZ)
             regs->ecx -= p->count;
         break;
 
     case INSTR_STOS:
         sign = p->df ? -1 : 1;
         regs->edi += sign * p->count * p->size;
-        if (mpcip->flags & REPZ)
+        if (mmio_opp->flags & REPZ)
             regs->ecx -= p->count;
         break;
 
@@ -500,7 +500,7 @@
             value = get_reg_value(size, index, 0, regs);
             diff = (unsigned long) p->u.data & value;
         } else if (src & IMMEDIATE) {
-            value = mpcip->immediate;
+            value = mmio_opp->immediate;
             diff = (unsigned long) p->u.data & value;
         } else if (src & MEMORY) {
             index = operand_index(dst);
@@ -527,7 +527,7 @@
             value = get_reg_value(size, index, 0, regs);
             diff = (unsigned long) p->u.data | value;
         } else if (src & IMMEDIATE) {
-            value = mpcip->immediate;
+            value = mmio_opp->immediate;
             diff = (unsigned long) p->u.data | value;
         } else if (src & MEMORY) {
             index = operand_index(dst);
@@ -554,7 +554,7 @@
             value = get_reg_value(size, index, 0, regs);
             diff = (unsigned long) p->u.data ^ value;
         } else if (src & IMMEDIATE) {
-            value = mpcip->immediate;
+            value = mmio_opp->immediate;
             diff = (unsigned long) p->u.data ^ value;
         } else if (src & MEMORY) {
             index = operand_index(dst);
@@ -581,7 +581,7 @@
             value = get_reg_value(size, index, 0, regs);
             diff = (unsigned long) p->u.data - value;
         } else if (src & IMMEDIATE) {
-            value = mpcip->immediate;
+            value = mmio_opp->immediate;
             diff = (unsigned long) p->u.data - value;
         } else if (src & MEMORY) {
             index = operand_index(dst);
@@ -608,7 +608,7 @@
             index = operand_index(src);
             value = get_reg_value(size, index, 0, regs);
         } else if (src & IMMEDIATE) {
-            value = mpcip->immediate;
+            value = mmio_opp->immediate;
         } else if (src & MEMORY) {
             index = operand_index(dst);
             value = get_reg_value(size, index, 0, regs);
@@ -629,21 +629,21 @@
     load_cpu_user_regs(regs);
 }
 
-void vmx_io_assist(struct vcpu *v) 
+void vmx_io_assist(struct vcpu *v)
 {
     vcpu_iodata_t *vio;
     ioreq_t *p;
     struct cpu_user_regs *regs = guest_cpu_user_regs();
-    struct mi_per_cpu_info *mpci_p;
+    struct mmio_op *mmio_opp;
     struct cpu_user_regs *inst_decoder_regs;
 
-    mpci_p = &v->domain->arch.vmx_platform.mpci;
-    inst_decoder_regs = mpci_p->inst_decoder_regs;
+    mmio_opp = &v->arch.arch_vmx.mmio_op;
+    inst_decoder_regs = mmio_opp->inst_decoder_regs;
 
     vio = get_vio(v->domain, v->vcpu_id);
 
     if (vio == 0) {
-        VMX_DBG_LOG(DBG_LEVEL_1, 
+        VMX_DBG_LOG(DBG_LEVEL_1,
                     "bad shared page: %lx", (unsigned long) vio);
         printf("bad shared page: %lx\n", (unsigned long) vio);
         domain_crash_synchronous();
@@ -660,15 +660,15 @@
             clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
 
             if (p->type == IOREQ_TYPE_PIO)
-                vmx_pio_assist(regs, p, mpci_p);
+                vmx_pio_assist(regs, p, mmio_opp);
             else
-                vmx_mmio_assist(regs, p, mpci_p);
+                vmx_mmio_assist(regs, p, mmio_opp);
         }
         /* else an interrupt send event raced us */
     }
 }
 
-int vmx_clear_pending_io_event(struct vcpu *v) 
+int vmx_clear_pending_io_event(struct vcpu *v)
 {
     struct domain *d = v->domain;
     int port = iopacket_port(d);
@@ -678,7 +678,7 @@
         clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel);
 
     /* Note: VMX domains may need upcalls as well */
-    if (!v->vcpu_info->evtchn_pending_sel) 
+    if (!v->vcpu_info->evtchn_pending_sel)
         clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
 
     /* clear the pending bit for port */
@@ -688,18 +688,18 @@
 /* Because we've cleared the pending events first, we need to guarantee that
  * all events to be handled by xen for VMX domains are taken care of here.
  *
- * interrupts are guaranteed to be checked before resuming guest. 
- * VMX upcalls have been already arranged for if necessary. 
+ * interrupts are guaranteed to be checked before resuming guest.
+ * VMX upcalls have been already arranged for if necessary.
  */
-void vmx_check_events(struct vcpu *d) 
-{
-    /* clear the event *before* checking for work. This should avoid 
+void vmx_check_events(struct vcpu *v)
+{
+    /* clear the event *before* checking for work. This should avoid
        the set-and-check races */
     if (vmx_clear_pending_io_event(current))
-        vmx_io_assist(d);
-}
-
-/* On exit from vmx_wait_io, we're guaranteed to have a I/O response from 
+        vmx_io_assist(v);
+}
+
+/* On exit from vmx_wait_io, we're guaranteed to have a I/O response from
    the device model */
 void vmx_wait_io()
 {
@@ -782,7 +782,7 @@
     return __fls(pintr[0]);
 }
 
-#define BSP_CPU(d)    (!(d->vcpu_id))
+#define BSP_CPU(v)    (!(v->vcpu_id))
 static inline void clear_extint(struct vcpu *v)
 {
     global_iodata_t *spg;
@@ -883,7 +883,7 @@
     return ((eflags & X86_EFLAGS_IF) == 0);
 }
 
-asmlinkage void vmx_intr_assist(void) 
+asmlinkage void vmx_intr_assist(void)
 {
     int intr_type = 0;
     int highest_vector;
@@ -891,7 +891,7 @@
     struct vcpu *v = current;
 
     highest_vector = find_highest_pending_irq(v, &intr_type);
-    __vmread_vcpu(CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
+    __vmread_vcpu(v, CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
 
     if (highest_vector == -1) {
         disable_irq_window(cpu_exec_control);
@@ -945,19 +945,19 @@
     return;
 }
 
-void vmx_do_resume(struct vcpu *d) 
+void vmx_do_resume(struct vcpu *v)
 {
     vmx_stts();
 
-    if (event_pending(d)) {
-        vmx_check_events(d);
-
-        if (test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags))
+    if (event_pending(v)) {
+        vmx_check_events(v);
+
+        if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
             vmx_wait_io();
     }
 
     /* We can't resume the guest if we're waiting on I/O */
-    ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags));
+    ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags));
 }
 
 #endif /* CONFIG_VMX */
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c       Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/vmx_platform.c       Sat Oct  8 20:28:24 2005
@@ -22,8 +22,8 @@
 #include <xen/mm.h>
 #include <asm/shadow.h>
 #include <xen/domain_page.h>
-#include <asm/page.h> 
-#include <xen/event.h> 
+#include <asm/page.h>
+#include <xen/event.h>
 #include <xen/trace.h>
 #include <asm/vmx.h>
 #include <asm/vmx_platform.h>
@@ -69,16 +69,16 @@
     }
 }
 
-long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs) 
+long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs)
 {
     if (size == BYTE) {
-        switch (index) { 
+        switch (index) {
         case 0: /* %al */
             return (char)(regs->rax & 0xFF);
         case 1: /* %cl */
             return (char)(regs->rcx & 0xFF);
         case 2: /* %dl */
-            return (char)(regs->rdx & 0xFF); 
+            return (char)(regs->rdx & 0xFF);
         case 3: /* %bl */
             return (char)(regs->rbx & 0xFF);
         case 4: /* %ah */
@@ -90,7 +90,7 @@
         case 7: /* %bh */
             return (char)((regs->rbx & 0xFF00) >> 8);
         default:
-            printf("Error: (get_reg_value) Invalid index value\n"); 
+            printf("Error: (get_reg_value) Invalid index value\n");
             domain_crash_synchronous();
         }
         /* NOTREACHED */
@@ -114,7 +114,7 @@
     case 14: return __get_reg_value(regs->r14, size);
     case 15: return __get_reg_value(regs->r15, size);
     default:
-        printf("Error: (get_reg_value) Invalid index value\n"); 
+        printf("Error: (get_reg_value) Invalid index value\n");
         domain_crash_synchronous();
     }
 }
@@ -131,7 +131,7 @@
 }
 
 static inline long __get_reg_value(unsigned long reg, int size)
-{                    
+{
     switch(size) {
     case WORD:
         return (short)(reg & 0xFFFF);
@@ -144,15 +144,15 @@
 }
 
 long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs)
-{                    
+{
     if (size == BYTE) {
-        switch (index) { 
+        switch (index) {
         case 0: /* %al */
             return (char)(regs->eax & 0xFF);
         case 1: /* %cl */
             return (char)(regs->ecx & 0xFF);
         case 2: /* %dl */
-            return (char)(regs->edx & 0xFF); 
+            return (char)(regs->edx & 0xFF);
         case 3: /* %bl */
             return (char)(regs->ebx & 0xFF);
         case 4: /* %ah */
@@ -164,7 +164,7 @@
         case 7: /* %bh */
             return (char)((regs->ebx & 0xFF00) >> 8);
         default:
-            printf("Error: (get_reg_value) Invalid index value\n"); 
+            printf("Error: (get_reg_value) Invalid index value\n");
             domain_crash_synchronous();
         }
     }
@@ -179,7 +179,7 @@
     case 6: return __get_reg_value(regs->esi, size);
     case 7: return __get_reg_value(regs->edi, size);
     default:
-        printf("Error: (get_reg_value) Invalid index value\n"); 
+        printf("Error: (get_reg_value) Invalid index value\n");
         domain_crash_synchronous();
     }
 }
@@ -283,9 +283,9 @@
 
     //Only one operand in the instruction is register
     if (mod == 3) {
-        return (rm + (rex_b << 3)); 
+        return (rm + (rex_b << 3));
     } else {
-        return (reg + (rex_r << 3)); 
+        return (reg + (rex_r << 3));
     }
     return 0;
 }
@@ -299,7 +299,7 @@
 
     mmio_inst->operand[0] = 0;
     mmio_inst->operand[1] = 0;
-        
+
     mmio_inst->flags = 0;
 }
 
@@ -498,12 +498,12 @@
         instr->instr = INSTR_MOVS;
         instr->op_size = BYTE;
         return DECODE_success;
-            
+
     case 0xA5: /* movsw/movsl */
         instr->instr = INSTR_MOVS;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return DECODE_success;
-    
+
     case 0xAA: /* stosb */
         instr->instr = INSTR_STOS;
         instr->op_size = BYTE;
@@ -513,7 +513,7 @@
         instr->instr = INSTR_STOS;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return DECODE_success;
-                    
+
     case 0xC6:
         if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm8, m8 */
             instr->instr = INSTR_MOV;
@@ -522,11 +522,11 @@
             instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
             instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
             instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
-            
+
             return DECODE_success;
         } else
             return DECODE_failure;
-            
+
     case 0xC7:
         if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm16/32, m16/32 */
             instr->instr = INSTR_MOV;
@@ -535,7 +535,7 @@
             instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
             instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
             instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
-            
+
             return DECODE_success;
         } else
             return DECODE_failure;
@@ -598,34 +598,34 @@
     return inst_len;
 }
 
-void send_mmio_req(unsigned char type, unsigned long gpa, 
+void send_mmio_req(unsigned char type, unsigned long gpa,
                    unsigned long count, int size, long value, int dir, int 
pvalid)
 {
-    struct vcpu *d = current;
+    struct vcpu *v = current;
     vcpu_iodata_t *vio;
     ioreq_t *p;
     int vm86;
     struct cpu_user_regs *regs;
     extern long evtchn_send(int lport);
 
-    regs = current->domain->arch.vmx_platform.mpci.inst_decoder_regs;
-
-    vio = get_vio(d->domain, d->vcpu_id);
+    regs = current->arch.arch_vmx.mmio_op.inst_decoder_regs;
+
+    vio = get_vio(v->domain, v->vcpu_id);
     if (vio == NULL) {
         printf("bad shared page\n");
-        domain_crash_synchronous(); 
+        domain_crash_synchronous();
     }
 
     p = &vio->vp_ioreq;
 
     vm86 = regs->eflags & X86_EFLAGS_VM;
 
-    if (test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags)) {
+    if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
         printf("VMX I/O has not yet completed\n");
         domain_crash_synchronous();
     }
 
-    set_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags);
+    set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
     p->dir = dir;
     p->pdata_valid = pvalid;
 
@@ -647,27 +647,27 @@
 
     if (vmx_mmio_intercept(p)){
         p->state = STATE_IORESP_READY;
-        vmx_io_assist(d);
+        vmx_io_assist(v);
         return;
     }
 
-    evtchn_send(iopacket_port(d->domain));
+    evtchn_send(iopacket_port(v->domain));
     vmx_wait_io();
 }
 
 static void mmio_operands(int type, unsigned long gpa, struct instruction 
*inst,
-                          struct mi_per_cpu_info *mpcip, struct cpu_user_regs 
*regs)
+                          struct mmio_op *mmio_opp, struct cpu_user_regs *regs)
 {
     unsigned long value = 0;
     int index, size;
-    
+
     size = operand_size(inst->operand[0]);
 
-    mpcip->flags = inst->flags;
-    mpcip->instr = inst->instr;
-    mpcip->operand[0] = inst->operand[0]; /* source */
-    mpcip->operand[1] = inst->operand[1]; /* destination */
-    mpcip->immediate = inst->immediate;
+    mmio_opp->flags = inst->flags;
+    mmio_opp->instr = inst->instr;
+    mmio_opp->operand[0] = inst->operand[0]; /* source */
+    mmio_opp->operand[1] = inst->operand[1]; /* destination */
+    mmio_opp->immediate = inst->immediate;
 
     if (inst->operand[0] & REGISTER) { /* dest is memory */
         index = operand_index(inst->operand[0]);
@@ -687,19 +687,19 @@
 
 #define GET_REPEAT_COUNT() \
      (mmio_inst.flags & REPZ ? (vm86 ? regs->ecx & 0xFFFF : regs->ecx) : 1)
- 
+
 void handle_mmio(unsigned long va, unsigned long gpa)
 {
     unsigned long eip, eflags, cs;
     unsigned long inst_len, inst_addr;
-    struct mi_per_cpu_info *mpcip;
+    struct mmio_op *mmio_opp;
     struct cpu_user_regs *regs;
     struct instruction mmio_inst;
     unsigned char inst[MAX_INST_LEN];
     int i, vm86, ret;
-     
-    mpcip = &current->domain->arch.vmx_platform.mpci;
-    regs = mpcip->inst_decoder_regs;
+
+    mmio_opp = &current->arch.arch_vmx.mmio_op;
+    regs = mmio_opp->inst_decoder_regs;
 
     __vmread(GUEST_RIP, &eip);
     __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
@@ -720,7 +720,7 @@
     }
 
     init_instruction(&mmio_inst);
-    
+
     if (vmx_decode(inst, &mmio_inst) == DECODE_failure) {
         printf("mmio opcode: va 0x%lx, gpa 0x%lx, len %ld:",
                va, gpa, inst_len);
@@ -735,7 +735,7 @@
 
     switch (mmio_inst.instr) {
     case INSTR_MOV:
-        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
         break;
 
     case INSTR_MOVS:
@@ -769,8 +769,8 @@
             }
         }
 
-        mpcip->flags = mmio_inst.flags;
-        mpcip->instr = mmio_inst.instr;
+        mmio_opp->flags = mmio_inst.flags;
+        mmio_opp->instr = mmio_inst.instr;
 
         /*
          * In case of a movs spanning multiple pages, we break the accesses
@@ -785,7 +785,7 @@
         if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
             unsigned long value = 0;
 
-            mpcip->flags |= OVERLAP;
+            mmio_opp->flags |= OVERLAP;
 
             regs->eip -= inst_len; /* do not advance %eip */
 
@@ -808,7 +808,7 @@
     }
 
     case INSTR_MOVZ:
-        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
         break;
 
     case INSTR_STOS:
@@ -816,31 +816,31 @@
          * Since the destination is always in (contiguous) mmio space we don't
          * need to break it up into pages.
          */
-        mpcip->flags = mmio_inst.flags;
-        mpcip->instr = mmio_inst.instr;
+        mmio_opp->flags = mmio_inst.flags;
+        mmio_opp->instr = mmio_inst.instr;
         send_mmio_req(IOREQ_TYPE_COPY, gpa,
                       GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax, 
IOREQ_WRITE, 0);
         break;
 
     case INSTR_OR:
-        mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mpcip, regs);
+        mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mmio_opp, regs);
         break;
 
     case INSTR_AND:
-        mmio_operands(IOREQ_TYPE_AND, gpa, &mmio_inst, mpcip, regs);
+        mmio_operands(IOREQ_TYPE_AND, gpa, &mmio_inst, mmio_opp, regs);
         break;
 
     case INSTR_XOR:
-        mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mpcip, regs);
+        mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mmio_opp, regs);
         break;
 
     case INSTR_CMP:        /* Pass through */
     case INSTR_TEST:
-        mpcip->flags = mmio_inst.flags;
-        mpcip->instr = mmio_inst.instr;
-        mpcip->operand[0] = mmio_inst.operand[0]; /* source */
-        mpcip->operand[1] = mmio_inst.operand[1]; /* destination */
-        mpcip->immediate = mmio_inst.immediate;
+        mmio_opp->flags = mmio_inst.flags;
+        mmio_opp->instr = mmio_inst.instr;
+        mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
+        mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */
+        mmio_opp->immediate = mmio_inst.immediate;
 
         /* send the request and wait for the value */
         send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0, 
IOREQ_READ, 0);
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c   Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/vmx_vmcs.c   Sat Oct  8 20:28:24 2005
@@ -37,6 +37,8 @@
 #endif
 #ifdef CONFIG_VMX
 
+int vmcs_size;
+
 struct vmcs_struct *alloc_vmcs(void)
 {
     struct vmcs_struct *vmcs;
@@ -51,13 +53,35 @@
     return vmcs;
 }
 
-void free_vmcs(struct vmcs_struct *vmcs)
+static void free_vmcs(struct vmcs_struct *vmcs)
 {
     int order;
 
     order = get_order_from_bytes(vmcs_size);
     free_xenheap_pages(vmcs, order);
 }
+
+static int load_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
+{
+    int error;
+
+    if ((error = __vmptrld(phys_ptr))) {
+        clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
+        return error;
+    }
+    set_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
+    return 0;
+}
+
+#if 0
+static int store_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
+{
+    /* take the current VMCS */
+    __vmptrst(phys_ptr);
+    clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
+    return 0;
+}
+#endif
 
 static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx)
 {
@@ -118,7 +142,7 @@
 #endif
 };
 
-static void vmx_setup_platform(struct vcpu *v, struct cpu_user_regs *regs)
+static void vmx_setup_platform(struct vcpu *v)
 {
     int i;
     unsigned char e820_map_nr;
@@ -161,9 +185,6 @@
     }
     unmap_domain_page(p);
 
-    if (v->vcpu_id)
-        return;
-
     /* Initialise shared page */
     mpfn = get_mfn_from_pfn(gpfn);
     if (mpfn == INVALID_MFN) {
@@ -184,7 +205,7 @@
               &v->domain->shared_info->evtchn_mask[0]);
 }
 
-void vmx_set_host_env(struct vcpu *v)
+static void vmx_set_host_env(struct vcpu *v)
 {
     unsigned int tr, cpu, error = 0;
     struct host_execution_env host_env;
@@ -209,14 +230,13 @@
     error |= __vmwrite(HOST_TR_BASE, host_env.tr_base);
 }
 
-void vmx_do_launch(struct vcpu *v)
+static void vmx_do_launch(struct vcpu *v)
 {
 /* Update CR3, GDT, LDT, TR */
     unsigned int  error = 0;
     unsigned long pfn = 0;
     unsigned long cr0, cr4;
     struct pfn_info *page;
-    struct cpu_user_regs *regs = guest_cpu_user_regs();
 
     __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
 
@@ -246,7 +266,7 @@
     page = (struct pfn_info *) alloc_domheap_page(NULL);
     pfn = (unsigned long) (page - frame_table);
 
-    vmx_setup_platform(v, regs);
+    vmx_setup_platform(v);
 
     vmx_set_host_env(v);
 
@@ -267,8 +287,7 @@
 /*
  * Initially set the same environement as host.
  */
-static inline int
-construct_init_vmcs_guest(struct cpu_user_regs *regs)
+static inline int construct_init_vmcs_guest(cpu_user_regs_t *regs)
 {
     int error = 0;
     union vmcs_arbytes arbytes;
@@ -374,34 +393,33 @@
     return error;
 }
 
-static inline int construct_vmcs_host(struct host_execution_env *host_env)
+static inline int construct_vmcs_host()
 {
     int error = 0;
+#ifdef __x86_64__
+    unsigned long fs_base;
+    unsigned long gs_base;
+#endif
     unsigned long crn;
 
     /* Host Selectors */
-    host_env->ds_selector = __HYPERVISOR_DS;
-    error |= __vmwrite(HOST_ES_SELECTOR, host_env->ds_selector);
-    error |= __vmwrite(HOST_SS_SELECTOR, host_env->ds_selector);
-    error |= __vmwrite(HOST_DS_SELECTOR, host_env->ds_selector);
+    error |= __vmwrite(HOST_ES_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
 #if defined (__i386__)
-    error |= __vmwrite(HOST_FS_SELECTOR, host_env->ds_selector);
-    error |= __vmwrite(HOST_GS_SELECTOR, host_env->ds_selector);
-    error |= __vmwrite(HOST_FS_BASE, host_env->ds_base);
-    error |= __vmwrite(HOST_GS_BASE, host_env->ds_base);
+    error |= __vmwrite(HOST_FS_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_GS_SELECTOR, __HYPERVISOR_DS);
+    error |= __vmwrite(HOST_FS_BASE, 0);
+    error |= __vmwrite(HOST_GS_BASE, 0);
 
 #else
-    rdmsrl(MSR_FS_BASE, host_env->fs_base);
-    rdmsrl(MSR_GS_BASE, host_env->gs_base);
-    error |= __vmwrite(HOST_FS_BASE, host_env->fs_base);
-    error |= __vmwrite(HOST_GS_BASE, host_env->gs_base);
-
-#endif
-    host_env->cs_selector = __HYPERVISOR_CS;
-    error |= __vmwrite(HOST_CS_SELECTOR, host_env->cs_selector);
-
-    host_env->ds_base = 0;
-    host_env->cs_base = 0;
+    rdmsrl(MSR_FS_BASE, fs_base);
+    rdmsrl(MSR_GS_BASE, gs_base);
+    error |= __vmwrite(HOST_FS_BASE, fs_base);
+    error |= __vmwrite(HOST_GS_BASE, gs_base);
+
+#endif
+    error |= __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS);
 
     __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (crn) : );
     error |= __vmwrite(HOST_CR0, crn); /* same CR0 */
@@ -423,55 +441,58 @@
 
 /*
  * Need to extend to support full virtualization.
- * The variable use_host_env indicates if the new VMCS needs to use
- * the same setups as the host has (xenolinux).
  */
-
-int construct_vmcs(struct arch_vmx_struct *arch_vmx,
-                   struct cpu_user_regs *regs,
-                   struct vcpu_guest_context *ctxt,
-                   int use_host_env)
+static int construct_vmcs(struct arch_vmx_struct *arch_vmx,
+                          cpu_user_regs_t *regs)
 {
     int error;
+    long rc;
     u64 vmcs_phys_ptr;
 
-    struct host_execution_env host_env;
-
-    if (use_host_env != VMCS_USE_HOST_ENV)
-        return -EINVAL;
-
-    memset(&host_env, 0, sizeof(struct host_execution_env));
-
+    memset(arch_vmx, 0, sizeof(struct arch_vmx_struct));
+    /*
+     * Create a new VMCS
+     */
+    if (!(arch_vmx->vmcs = alloc_vmcs())) {
+        printk("Failed to create a new VMCS\n");
+        rc = -ENOMEM;
+        goto err_out;
+    }
     vmcs_phys_ptr = (u64) virt_to_phys(arch_vmx->vmcs);
 
-    if ((error = __vmpclear (vmcs_phys_ptr))) {
+    if ((error = __vmpclear(vmcs_phys_ptr))) {
         printk("construct_vmcs: VMCLEAR failed\n");
-        return -EINVAL;
+        rc = -EINVAL;
+        goto err_out;
     }
     if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) {
         printk("construct_vmcs: load_vmcs failed: VMCS = %lx\n",
                (unsigned long) vmcs_phys_ptr);
-        return -EINVAL;
+        rc = -EINVAL;
+        goto err_out;
     }
     if ((error = construct_vmcs_controls(arch_vmx))) {
         printk("construct_vmcs: construct_vmcs_controls failed\n");
-        return -EINVAL;
+        rc = -EINVAL;
+        goto err_out;
     }
     /* host selectors */
-    if ((error = construct_vmcs_host(&host_env))) {
+    if ((error = construct_vmcs_host())) {
         printk("construct_vmcs: construct_vmcs_host failed\n");
-        return -EINVAL;
+        rc = -EINVAL;
+        goto err_out;
     }
     /* guest selectors */
     if ((error = construct_init_vmcs_guest(regs))) {
         printk("construct_vmcs: construct_vmcs_guest failed\n");
-        return -EINVAL;
-    }
-
+        rc = -EINVAL;
+        goto err_out;
+    }
     if ((error |= __vmwrite(EXCEPTION_BITMAP,
                             MONITOR_DEFAULT_EXCEPTION_BITMAP))) {
         printk("construct_vmcs: setting Exception bitmap failed\n");
-        return -EINVAL;
+        rc = -EINVAL;
+        goto err_out;
     }
 
     if (regs->eflags & EF_TF)
@@ -480,6 +501,27 @@
         __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
 
     return 0;
+
+err_out:
+    destroy_vmcs(arch_vmx);
+    return rc;
+}
+
+void destroy_vmcs(struct arch_vmx_struct *arch_vmx)
+{
+    if(arch_vmx->vmcs != NULL)
+        free_vmcs(arch_vmx->vmcs);
+    if(arch_vmx->io_bitmap_a != 0) {
+        free_xenheap_pages(
+            arch_vmx->io_bitmap_a, get_order_from_bytes(0x1000));
+        arch_vmx->io_bitmap_a = 0;
+    }
+    if(arch_vmx->io_bitmap_b != 0) {
+        free_xenheap_pages(
+            arch_vmx->io_bitmap_b, get_order_from_bytes(0x1000));
+        arch_vmx->io_bitmap_b = 0;
+    }
+    arch_vmx->vmcs = 0;
 }
 
 /*
@@ -506,26 +548,6 @@
     return 0;
 }
 
-int load_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
-{
-    int error;
-
-    if ((error = __vmptrld(phys_ptr))) {
-        clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
-        return error;
-    }
-    set_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
-    return 0;
-}
-
-int store_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
-{
-    /* take the current VMCS */
-    __vmptrst(phys_ptr);
-    clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
-    return 0;
-}
-
 void vm_launch_fail(unsigned long eflags)
 {
     unsigned long error;
@@ -553,9 +575,19 @@
 
 void arch_vmx_do_launch(struct vcpu *v)
 {
-    u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs);
-
-    load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr);
+    int error;
+    cpu_user_regs_t *regs = &current->arch.guest_context.user_regs;
+
+    error = construct_vmcs(&v->arch.arch_vmx, regs);
+    if ( error < 0 )
+    {
+        if (v->vcpu_id == 0) {
+            printk("Failed to construct a new VMCS for BSP.\n");
+        } else {
+            printk("Failed to construct a new VMCS for AP %d\n", v->vcpu_id);
+        }
+        domain_crash_synchronous();
+    }
     vmx_do_launch(v);
     reset_stack_and_jump(vmx_asm_do_launch);
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/x86_32/entry.S       Sat Oct  8 20:28:24 2005
@@ -808,7 +808,7 @@
         .long do_vm_assist
         .long do_update_va_mapping_otherdomain
         .long do_switch_vm86
-        .long do_boot_vcpu
+        .long do_vcpu_op
         .long do_ni_hypercall       /* 25 */
         .long do_mmuext_op
         .long do_acm_op             /* 27 */
@@ -841,7 +841,7 @@
         .byte 2 /* do_vm_assist         */
         .byte 5 /* do_update_va_mapping_otherdomain */
         .byte 0 /* do_switch_vm86       */
-        .byte 2 /* do_boot_vcpu         */
+        .byte 3 /* do_vcpu_op           */
         .byte 0 /* do_ni_hypercall      */  /* 25 */
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/x86_32/mm.c  Sat Oct  8 20:28:24 2005
@@ -156,6 +156,7 @@
      */
     if ( (offsetof(struct pfn_info, u.inuse._domain) != 
           (offsetof(struct pfn_info, count_info) + sizeof(u32))) ||
+         ((offsetof(struct pfn_info, count_info) & 7) != 0) ||
          (sizeof(struct pfn_info) != 24) )
     {
         printk("Weird pfn_info layout (%ld,%ld,%d)\n",
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/x86_64/entry.S       Sat Oct  8 20:28:24 2005
@@ -629,7 +629,7 @@
         .quad do_vm_assist
         .quad do_update_va_mapping_otherdomain
         .quad do_switch_to_user
-        .quad do_boot_vcpu
+        .quad do_vcpu_op
         .quad do_set_segment_base   /* 25 */
         .quad do_mmuext_op
         .quad do_acm_op
@@ -662,7 +662,7 @@
         .byte 2 /* do_vm_assist         */
         .byte 4 /* do_update_va_mapping_otherdomain */
         .byte 0 /* do_switch_to_user    */
-        .byte 2 /* do_boot_vcpu         */
+        .byte 3 /* do_vcpu_op           */
         .byte 2 /* do_set_segment_base  */  /* 25 */
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Sat Oct  8 17:37:45 2005
+++ b/xen/arch/x86/x86_64/mm.c  Sat Oct  8 20:28:24 2005
@@ -137,8 +137,10 @@
      * count_info and domain fields must be adjacent, as we perform atomic
      * 64-bit operations on them.
      */
-    if ( (offsetof(struct pfn_info, u.inuse._domain) != 
-          (offsetof(struct pfn_info, count_info) + sizeof(u32))) )
+    if ( ((offsetof(struct pfn_info, u.inuse._domain) != 
+           (offsetof(struct pfn_info, count_info) + sizeof(u32)))) ||
+         ((offsetof(struct pfn_info, count_info) & 7) != 0) ||
+         (sizeof(struct pfn_info) != 40) )
     {
         printk("Weird pfn_info layout (%ld,%ld,%ld)\n",
                offsetof(struct pfn_info, count_info),
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/common/domain.c
--- a/xen/common/domain.c       Sat Oct  8 17:37:45 2005
+++ b/xen/common/domain.c       Sat Oct  8 20:28:24 2005
@@ -18,6 +18,8 @@
 #include <xen/domain_page.h>
 #include <asm/debugger.h>
 #include <public/dom0_ops.h>
+#include <public/sched.h>
+#include <public/vcpu.h>
 
 /* Both these structures are protected by the domlist_lock. */
 rwlock_t domlist_lock = RW_LOCK_UNLOCKED;
@@ -366,37 +368,17 @@
     return rc;
 }
 
-/*
- * final_setup_guest is used for final setup and launching of domains other
- * than domain 0. ie. the domains that are being built by the userspace dom0
- * domain builder.
- */
-long do_boot_vcpu(unsigned long vcpu, struct vcpu_guest_context *ctxt) 
-{
-    struct domain *d = current->domain;
-    struct vcpu *v;
-    int rc = 0;
-    struct vcpu_guest_context *c;
-
-    if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] != NULL) )
-        return -EINVAL;
-
-    if ( alloc_vcpu_struct(d, vcpu) == NULL )
+int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) 
+{
+    struct vcpu *v;
+    int rc;
+
+    ASSERT(d->vcpu[vcpuid] == NULL);
+
+    if ( alloc_vcpu_struct(d, vcpuid) == NULL )
         return -ENOMEM;
 
-    if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
-    {
-        rc = -ENOMEM;
-        goto out;
-    }
-
-    if ( copy_from_user(c, ctxt, sizeof(*c)) )
-    {
-        rc = -EFAULT;
-        goto out;
-    }
-
-    v = d->vcpu[vcpu];
+    v = d->vcpu[vcpuid];
 
     atomic_set(&v->pausecnt, 0);
     v->cpumap = CPUMAP_RUNANYWHERE;
@@ -405,22 +387,73 @@
 
     arch_do_boot_vcpu(v);
 
-    if ( (rc = arch_set_info_guest(v, c)) != 0 )
+    if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
         goto out;
 
     sched_add_domain(v);
 
-    /* domain_unpause_by_systemcontroller */
-    if ( test_and_clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
-        vcpu_wake(v);
-
-    xfree(c);
+    set_bit(_VCPUF_down, &v->vcpu_flags);
+    clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
+
     return 0;
 
  out:
-    xfree(c);
-    arch_free_vcpu_struct(d->vcpu[vcpu]);
-    d->vcpu[vcpu] = NULL;
+    arch_free_vcpu_struct(d->vcpu[vcpuid]);
+    d->vcpu[vcpuid] = NULL;
+    return rc;
+}
+
+long do_vcpu_op(int cmd, int vcpuid, void *arg)
+{
+    struct domain *d = current->domain;
+    struct vcpu *v;
+    struct vcpu_guest_context *ctxt;
+    long rc = 0;
+
+    if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
+        return -EINVAL;
+
+    if ( ((v = d->vcpu[vcpuid]) == NULL) && (cmd != VCPUOP_initialise) )
+        return -ENOENT;
+
+    switch ( cmd )
+    {
+    case VCPUOP_initialise:
+        if ( (ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
+        {
+            rc = -ENOMEM;
+            break;
+        }
+
+        if ( copy_from_user(ctxt, arg, sizeof(*ctxt)) )
+        {
+            xfree(ctxt);
+            rc = -EFAULT;
+            break;
+        }
+
+        LOCK_BIGLOCK(d);
+        rc = (d->vcpu[vcpuid] == NULL) ? boot_vcpu(d, vcpuid, ctxt) : -EEXIST;
+        UNLOCK_BIGLOCK(d);
+
+        xfree(ctxt);
+        break;
+
+    case VCPUOP_up:
+        if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+            vcpu_wake(v);
+        break;
+
+    case VCPUOP_down:
+        if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+            vcpu_sleep_nosync(v);
+        break;
+
+    case VCPUOP_is_up:
+        rc = !test_bit(_VCPUF_down, &v->vcpu_flags);
+        break;
+    }
+
     return rc;
 }
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Sat Oct  8 17:37:45 2005
+++ b/xen/common/event_channel.c        Sat Oct  8 20:28:24 2005
@@ -36,7 +36,13 @@
 #define evtchn_from_port(d,p) \
     (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
 
-#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
+#define ERROR_EXIT(_errno)                                          \
+    do {                                                            \
+        DPRINTK("EVTCHNOP failure: domain %d, error %d, line %d\n", \
+                current->domain->domain_id, (_errno), __LINE__);    \
+        rc = (_errno);                                              \
+        goto out;                                                   \
+    } while ( 0 )
 
 static int get_free_port(struct domain *d)
 {
@@ -63,222 +69,133 @@
 static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 {
     struct evtchn *chn;
+    struct domain *d;
+    int            port;
+    domid_t        dom = alloc->dom;
+    long           rc = 0;
+
+    if ( dom == DOMID_SELF )
+        dom = current->domain->domain_id;
+    else if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( (d = find_domain_by_id(dom)) == NULL )
+        return -ESRCH;
+
+    spin_lock(&d->evtchn_lock);
+
+    if ( (port = get_free_port(d)) < 0 )
+        ERROR_EXIT(port);
+    chn = evtchn_from_port(d, port);
+
+    chn->state = ECS_UNBOUND;
+    chn->u.unbound.remote_domid = alloc->remote_dom;
+
+    alloc->port = port;
+
+ out:
+    spin_unlock(&d->evtchn_lock);
+
+    put_domain(d);
+
+    return rc;
+}
+
+
+static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
+{
+    struct evtchn *lchn, *rchn;
+    struct domain *ld = current->domain, *rd;
+    int            lport, rport = bind->remote_port;
+    long           rc = 0;
+
+    if ( (rd = find_domain_by_id(bind->remote_dom)) == NULL )
+        return -ESRCH;
+
+    /* Avoid deadlock by first acquiring lock of domain with smaller id. */
+    if ( ld < rd )
+    {
+        spin_lock(&ld->evtchn_lock);
+        spin_lock(&rd->evtchn_lock);
+    }
+    else
+    {
+        if ( ld != rd )
+            spin_lock(&rd->evtchn_lock);
+        spin_lock(&ld->evtchn_lock);
+    }
+
+    if ( (lport = get_free_port(ld)) < 0 )
+        ERROR_EXIT(lport);
+    lchn = evtchn_from_port(ld, lport);
+
+    if ( !port_is_valid(rd, rport) )
+        ERROR_EXIT(-EINVAL);
+    rchn = evtchn_from_port(rd, rport);
+    if ( (rchn->state != ECS_UNBOUND) ||
+         (rchn->u.unbound.remote_domid != ld->domain_id) )
+        ERROR_EXIT(-EINVAL);
+
+    lchn->u.interdomain.remote_dom  = rd;
+    lchn->u.interdomain.remote_port = (u16)rport;
+    lchn->state                     = ECS_INTERDOMAIN;
+    
+    rchn->u.interdomain.remote_dom  = ld;
+    rchn->u.interdomain.remote_port = (u16)lport;
+    rchn->state                     = ECS_INTERDOMAIN;
+
+    /*
+     * We may have lost notifications on the remote unbound port. Fix that up
+     * here by conservatively always setting a notification on the local port.
+     */
+    evtchn_set_pending(ld->vcpu[lchn->notify_vcpu_id], lport);
+
+    bind->local_port = lport;
+
+ out:
+    spin_unlock(&ld->evtchn_lock);
+    if ( ld != rd )
+        spin_unlock(&rd->evtchn_lock);
+    
+    put_domain(rd);
+
+    return rc;
+}
+
+
+static long evtchn_bind_virq(evtchn_bind_virq_t *bind)
+{
+    struct evtchn *chn;
+    struct vcpu   *v;
     struct domain *d = current->domain;
-    int            port = alloc->port;
+    int            port, virq = bind->virq, vcpu = bind->vcpu;
     long           rc = 0;
-
-    spin_lock(&d->evtchn_lock);
-
-    /* Obtain, or ensure that we already have, a valid <port>. */
-    if ( port == 0 )
-    {
-        if ( (port = get_free_port(d)) < 0 )
-            ERROR_EXIT(port);
-    }
-    else if ( !port_is_valid(d, port) )
-        ERROR_EXIT(-EINVAL);
-    chn = evtchn_from_port(d, port);
-
-    /* Validate channel's current state. */
-    switch ( chn->state )
-    {
-    case ECS_FREE:
-        chn->state = ECS_UNBOUND;
-        chn->u.unbound.remote_domid = alloc->dom;
-        break;
-
-    case ECS_UNBOUND:
-        if ( chn->u.unbound.remote_domid != alloc->dom )
-            ERROR_EXIT(-EINVAL);
-        break;
-
-    default:
-        ERROR_EXIT(-EINVAL);
-    }
-
- out:
-    spin_unlock(&d->evtchn_lock);
-
-    alloc->port = port;
-    return rc;
-}
-
-
-static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
-{
-    struct evtchn *chn1, *chn2;
-    struct domain *d1, *d2;
-    int            port1 = bind->port1, port2 = bind->port2;
-    domid_t        dom1 = bind->dom1, dom2 = bind->dom2;
-    long           rc = 0;
-
-    if ( !IS_PRIV(current->domain) && (dom1 != DOMID_SELF) )
-        return -EPERM;
-
-    if ( dom1 == DOMID_SELF )
-        dom1 = current->domain->domain_id;
-    if ( dom2 == DOMID_SELF )
-        dom2 = current->domain->domain_id;
-
-    if ( ((d1 = find_domain_by_id(dom1)) == NULL) ||
-         ((d2 = find_domain_by_id(dom2)) == NULL) )
-    {
-        if ( d1 != NULL )
-            put_domain(d1);
-        return -ESRCH;
-    }
-
-    /* Avoid deadlock by first acquiring lock of domain with smaller id. */
-    if ( d1 < d2 )
-    {
-        spin_lock(&d1->evtchn_lock);
-        spin_lock(&d2->evtchn_lock);
-    }
-    else
-    {
-        if ( d1 != d2 )
-            spin_lock(&d2->evtchn_lock);
-        spin_lock(&d1->evtchn_lock);
-    }
-
-    /* Obtain, or ensure that we already have, a valid <port1>. */
-    if ( port1 == 0 )
-    {
-        if ( (port1 = get_free_port(d1)) < 0 )
-            ERROR_EXIT(port1);
-    }
-    else if ( !port_is_valid(d1, port1) )
-        ERROR_EXIT(-EINVAL);
-    chn1 = evtchn_from_port(d1, port1);
-
-    /* Obtain, or ensure that we already have, a valid <port2>. */
-    if ( port2 == 0 )
-    {
-        /* Make port1 non-free while we allocate port2 (in case dom1==dom2). */
-        u16 state = chn1->state;
-        chn1->state = ECS_INTERDOMAIN;
-        port2 = get_free_port(d2);
-        chn1->state = state;
-        if ( port2 < 0 )
-            ERROR_EXIT(port2);
-    }
-    else if ( !port_is_valid(d2, port2) )
-        ERROR_EXIT(-EINVAL);
-    chn2 = evtchn_from_port(d2, port2);
-
-    /* Validate <dom1,port1>'s current state. */
-    switch ( chn1->state )
-    {
-    case ECS_FREE:
-        break;
-
-    case ECS_UNBOUND:
-        if ( chn1->u.unbound.remote_domid != dom2 )
-            ERROR_EXIT(-EINVAL);
-        break;
-
-    case ECS_INTERDOMAIN:
-        if ( chn1->u.interdomain.remote_dom != d2 )
-            ERROR_EXIT(-EINVAL);
-        if ( (chn1->u.interdomain.remote_port != port2) && (bind->port2 != 0) )
-            ERROR_EXIT(-EINVAL);
-        port2 = chn1->u.interdomain.remote_port;
-        goto out;
-
-    default:
-        ERROR_EXIT(-EINVAL);
-    }
-
-    /* Validate <dom2,port2>'s current state. */
-    switch ( chn2->state )
-    {
-    case ECS_FREE:
-        if ( !IS_PRIV(current->domain) && (dom2 != DOMID_SELF) )
-            ERROR_EXIT(-EPERM);
-        break;
-
-    case ECS_UNBOUND:
-        if ( chn2->u.unbound.remote_domid != dom1 )
-            ERROR_EXIT(-EINVAL);
-        break;
-
-    case ECS_INTERDOMAIN:
-        if ( chn2->u.interdomain.remote_dom != d1 )
-            ERROR_EXIT(-EINVAL);
-        if ( (chn2->u.interdomain.remote_port != port1) && (bind->port1 != 0) )
-            ERROR_EXIT(-EINVAL);
-        port1 = chn2->u.interdomain.remote_port;
-        goto out;
-
-    default:
-        ERROR_EXIT(-EINVAL);
-    }
-
-    /*
-     * Everything checked out okay -- bind <dom1,port1> to <dom2,port2>.
-     */
-
-    chn1->u.interdomain.remote_dom  = d2;
-    chn1->u.interdomain.remote_port = (u16)port2;
-    chn1->state                     = ECS_INTERDOMAIN;
-    
-    chn2->u.interdomain.remote_dom  = d1;
-    chn2->u.interdomain.remote_port = (u16)port1;
-    chn2->state                     = ECS_INTERDOMAIN;
-
- out:
-    spin_unlock(&d1->evtchn_lock);
-    if ( d1 != d2 )
-        spin_unlock(&d2->evtchn_lock);
-    
-    put_domain(d1);
-    put_domain(d2);
-
-    bind->port1 = port1;
-    bind->port2 = port2;
-
-    return rc;
-}
-
-
-static long evtchn_bind_virq(evtchn_bind_virq_t *bind)
-{
-    struct evtchn *chn;
-    struct vcpu   *v = current;
-    struct domain *d = v->domain;
-    int            port, virq = bind->virq;
 
     if ( virq >= ARRAY_SIZE(v->virq_to_evtchn) )
         return -EINVAL;
 
-    if ( d->domain_id == 0 && virq >= VIRQ_CONSOLE )
-        v = d->vcpu[0];
+    if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || ((v = d->vcpu[vcpu]) == NULL) )
+        return -ENOENT;
 
     spin_lock(&d->evtchn_lock);
 
-    /*
-     * Port 0 is the fallback port for VIRQs that haven't been explicitly
-     * bound yet.
-     */
-    if ( ((port = v->virq_to_evtchn[virq]) != 0) ||
-         ((port = get_free_port(d)) < 0) )
-        goto out;
+    if ( v->virq_to_evtchn[virq] != 0 )
+        ERROR_EXIT(-EEXIST);
+
+    if ( (port = get_free_port(d)) < 0 )
+        ERROR_EXIT(port);
 
     chn = evtchn_from_port(d, port);
     chn->state          = ECS_VIRQ;
-    chn->notify_vcpu_id = v->vcpu_id;
+    chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
 
-    v->virq_to_evtchn[virq] = port;
+    v->virq_to_evtchn[virq] = bind->port = port;
 
  out:
     spin_unlock(&d->evtchn_lock);
 
-    if ( port < 0 )
-        return port;
-
-    bind->port = port;
-    return 0;
+    return rc;
 }
 
 
@@ -286,24 +203,27 @@
 {
     struct evtchn *chn;
     struct domain *d = current->domain;
-    int            port;
+    int            port, vcpu = bind->vcpu;
+    long           rc = 0;
+
+    if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu] == NULL) )
+        return -ENOENT;
 
     spin_lock(&d->evtchn_lock);
 
-    if ( (port = get_free_port(d)) >= 0 )
-    {
-        chn = evtchn_from_port(d, port);
-        chn->state          = ECS_IPI;
-        chn->notify_vcpu_id = current->vcpu_id;
-    }
-
+    if ( (port = get_free_port(d)) < 0 )
+        ERROR_EXIT(port);
+
+    chn = evtchn_from_port(d, port);
+    chn->state          = ECS_IPI;
+    chn->notify_vcpu_id = vcpu;
+
+    bind->port = port;
+
+ out:
     spin_unlock(&d->evtchn_lock);
 
-    if ( port < 0 )
-        return port;
-
-    bind->port = port;
-    return 0;
+    return rc;
 }
 
 
@@ -311,16 +231,19 @@
 {
     struct evtchn *chn;
     struct domain *d = current->domain;
-    int            port, rc, pirq = bind->pirq;
+    int            port, pirq = bind->pirq;
+    long           rc;
 
     if ( pirq >= ARRAY_SIZE(d->pirq_to_evtchn) )
         return -EINVAL;
 
     spin_lock(&d->evtchn_lock);
 
-    if ( ((rc = port = d->pirq_to_evtchn[pirq]) != 0) ||
-         ((rc = port = get_free_port(d)) < 0) )
-        goto out;
+    if ( d->pirq_to_evtchn[pirq] != 0 )
+        ERROR_EXIT(-EEXIST);
+
+    if ( (port = get_free_port(d)) < 0 )
+        ERROR_EXIT(port);
 
     chn = evtchn_from_port(d, port);
 
@@ -336,14 +259,12 @@
     chn->state  = ECS_PIRQ;
     chn->u.pirq = pirq;
 
+    bind->port = port;
+
  out:
     spin_unlock(&d->evtchn_lock);
 
-    if ( rc < 0 )
-        return rc;
-
-    bind->port = port;
-    return 0;
+    return rc;
 }
 
 
@@ -457,22 +378,7 @@
 
 static long evtchn_close(evtchn_close_t *close)
 {
-    struct domain *d;
-    long           rc;
-    domid_t        dom = close->dom;
-
-    if ( dom == DOMID_SELF )
-        dom = current->domain->domain_id;
-    else if ( !IS_PRIV(current->domain) )
-        return -EPERM;
-
-    if ( (d = find_domain_by_id(dom)) == NULL )
-        return -ESRCH;
-
-    rc = __evtchn_close(d, close->port);
-
-    put_domain(d);
-    return rc;
+    return __evtchn_close(current->domain, close->port);
 }
 
 
@@ -502,6 +408,9 @@
     case ECS_IPI:
         evtchn_set_pending(ld->vcpu[lchn->notify_vcpu_id], lport);
         break;
+    case ECS_UNBOUND:
+        /* silently drop the notification */
+        break;
     default:
         ret = -EINVAL;
     }
@@ -590,9 +499,8 @@
     struct evtchn *chn;
     long           rc = 0;
 
-    if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) ) {
-        return -EINVAL;
-    }
+    if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu] == NULL) )
+        return -ENOENT;
 
     spin_lock(&d->evtchn_lock);
 
@@ -668,7 +576,7 @@
         break;
 
     case EVTCHNOP_send:
-        rc = evtchn_send(op.u.send.local_port);
+        rc = evtchn_send(op.u.send.port);
         break;
 
     case EVTCHNOP_status:
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Sat Oct  8 17:37:45 2005
+++ b/xen/common/sched_sedf.c   Sat Oct  8 20:28:24 2005
@@ -500,9 +500,15 @@
                   curinf->vcpu->domain->domain_id,
                   curinf->vcpu->vcpu_id);
             __del_from_queue(curinf->vcpu);
-   
+
             /*move them to their next period*/
             curinf->deadl_abs += curinf->period;
+            /*ensure that the start of the next period is in the future*/
+            if (unlikely(PERIOD_BEGIN(curinf) < now)) {
+                curinf->deadl_abs += 
+                    (DIV_UP(now - PERIOD_BEGIN(curinf),
+                           curinf->period)) * curinf->period;
+            }
             /*and put them back into the queue*/
             __add_to_waitqueue_sort(curinf->vcpu);
             continue;
@@ -645,7 +651,7 @@
                                                         s_time_t end_xt, 
struct list_head *extraq[], int cpu) {
     struct task_slice   ret;
     struct sedf_vcpu_info *runinf;
- 
+    ASSERT(end_xt > now);
     /* Enough time left to use for extratime? */
     if (end_xt - now < EXTRA_QUANTUM)
         goto return_idle;
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/common/schedule.c
--- a/xen/common/schedule.c     Sat Oct  8 17:37:45 2005
+++ b/xen/common/schedule.c     Sat Oct  8 20:28:24 2005
@@ -36,6 +36,7 @@
 #include <xen/softirq.h>
 #include <xen/trace.h>
 #include <xen/mm.h>
+#include <public/sched.h>
 #include <public/sched_ctl.h>
 
 extern void arch_getdomaininfo_ctxt(struct vcpu *,
@@ -270,74 +271,11 @@
     return 0;
 }
 
-/* Mark target vcpu as non-runnable so it is not scheduled */
-static long do_vcpu_down(int vcpu)
-{
-    struct vcpu *target;
-    
-    if ( vcpu > MAX_VIRT_CPUS )
-        return -EINVAL;
-
-    target = current->domain->vcpu[vcpu];
-    if ( target == NULL )
-        return -ESRCH;
-    set_bit(_VCPUF_down, &target->vcpu_flags);
-
-    return 0;
-}
-
-/* Mark target vcpu as runnable and wake it */
-static long do_vcpu_up(int vcpu)
-{
-    struct vcpu *target;
-   
-    if (vcpu > MAX_VIRT_CPUS)
-        return -EINVAL;
-
-    target = current->domain->vcpu[vcpu];
-    if ( target == NULL )
-        return -ESRCH;
-    clear_bit(_VCPUF_down, &target->vcpu_flags);
-    /* wake vcpu */
-    vcpu_wake(target);
-
-    return 0;
-}
-
-static long do_vcpu_pickle(int vcpu, unsigned long arg)
-{
-    struct vcpu *v;
-    vcpu_guest_context_t *c;
-    int ret = 0;
-
-    if (vcpu >= MAX_VIRT_CPUS)
-        return -EINVAL;
-    v = current->domain->vcpu[vcpu];
-    if (!v)
-        return -ESRCH;
-    /* Don't pickle vcpus which are currently running */
-    if (!test_bit(_VCPUF_down, &v->vcpu_flags)) {
-        return -EBUSY;
-    }
-    c = xmalloc(vcpu_guest_context_t);
-    if (!c)
-        return -ENOMEM;
-    arch_getdomaininfo_ctxt(v, c);
-    if (copy_to_user((vcpu_guest_context_t *)arg,
-                     (const vcpu_guest_context_t *)c, sizeof(*c)))
-        ret = -EFAULT;
-    xfree(c);
-    return ret;
-}
-
-/*
- * Demultiplex scheduler-related hypercalls.
- */
-long do_sched_op(unsigned long op, unsigned long arg)
+long do_sched_op(int cmd, unsigned long arg)
 {
     long ret = 0;
 
-    switch ( op & SCHEDOP_cmdmask ) 
+    switch ( cmd )
     {
     case SCHEDOP_yield:
     {
@@ -354,24 +292,8 @@
     case SCHEDOP_shutdown:
     {
         TRACE_3D(TRC_SCHED_SHUTDOWN,
-                 current->domain->domain_id, current->vcpu_id,
-                 (op >> SCHEDOP_reasonshift));
-        domain_shutdown((u8)(op >> SCHEDOP_reasonshift));
-        break;
-    }
-    case SCHEDOP_vcpu_down:
-    {
-        ret = do_vcpu_down((int)(op >> SCHEDOP_vcpushift));
-        break;
-    }
-    case SCHEDOP_vcpu_up:
-    {
-        ret = do_vcpu_up((int)(op >> SCHEDOP_vcpushift));
-        break;
-    }
-    case SCHEDOP_vcpu_pickle:
-    {
-        ret = do_vcpu_pickle((int)(op >> SCHEDOP_vcpushift), arg);
+                 current->domain->domain_id, current->vcpu_id, arg);
+        domain_shutdown((u8)arg);
         break;
     }
 
@@ -395,8 +317,8 @@
     return 0;
 }
 
-/** sched_id - fetch ID of current scheduler */
-int sched_id()
+/* sched_id - fetch ID of current scheduler */
+int sched_id(void)
 {
     return ops.sched_id;
 }
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Sat Oct  8 17:37:45 2005
+++ b/xen/include/asm-x86/mm.h  Sat Oct  8 20:28:24 2005
@@ -22,9 +22,6 @@
     /* Each frame can be threaded onto a doubly-linked list. */
     struct list_head list;
 
-    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
-    u32 tlbflush_timestamp;
-
     /* Reference count and various PGC_xxx flags and fields. */
     u32 count_info;
 
@@ -37,17 +34,20 @@
             u32 _domain; /* pickled format */
             /* Type reference count and various PGT_xxx flags and fields. */
             unsigned long type_info;
-        } inuse;
+        } __attribute__ ((packed)) inuse;
 
         /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
         struct {
+            /* Order-size of the free chunk this page is the head of. */
+            u32 order;
             /* Mask of possibly-tainted TLBs. */
             cpumask_t cpumask;
-            /* Order-size of the free chunk this page is the head of. */
-            u8 order;
-        } free;
+        } __attribute__ ((packed)) free;
 
     } u;
+
+    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
+    u32 tlbflush_timestamp;
 };
 
  /* The following page types are MUTUALLY EXCLUSIVE. */
@@ -156,6 +156,7 @@
 
 extern struct pfn_info *frame_table;
 extern unsigned long max_page;
+extern unsigned long total_pages;
 void init_frametable(void);
 
 int alloc_page_type(struct pfn_info *page, unsigned long type);
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/asm-x86/vmx.h
--- a/xen/include/asm-x86/vmx.h Sat Oct  8 17:37:45 2005
+++ b/xen/include/asm-x86/vmx.h Sat Oct  8 20:28:24 2005
@@ -39,7 +39,6 @@
 extern void arch_vmx_do_resume(struct vcpu *);
 extern void arch_vmx_do_relaunch(struct vcpu *);
 
-extern int vmcs_size;
 extern unsigned int cpu_rev;
 
 /*
@@ -315,10 +314,8 @@
 }
 
 
-static always_inline void __vmwrite_vcpu(unsigned long field, unsigned long 
value)
-{
-    struct vcpu *v = current;
-
+static always_inline void __vmwrite_vcpu(struct vcpu *v, unsigned long field, 
unsigned long value)
+{
     switch(field) {
     case CR0_READ_SHADOW:
        v->arch.arch_vmx.cpu_shadow_cr0 = value;
@@ -335,10 +332,8 @@
     }
 }
 
-static always_inline void __vmread_vcpu(unsigned long field, unsigned long 
*value)
-{
-    struct vcpu *v = current;
-
+static always_inline void __vmread_vcpu(struct vcpu *v, unsigned long field, 
unsigned long *value)
+{
     switch(field) {
     case CR0_READ_SHADOW:
        *value = v->arch.arch_vmx.cpu_shadow_cr0;
@@ -353,24 +348,15 @@
        printk("__vmread_cpu: invalid field %lx\n", field);
        break;
     }
-
-   /* 
-    * __vmwrite() can be used for non-current vcpu, and it's possible that
-    * the vcpu field is not initialized at that case.
-    * 
-    */
-    if (!*value) {
-       __vmread(field, value);
-       __vmwrite_vcpu(field, *value);
-    }
 }
 
 static inline int __vmwrite (unsigned long field, unsigned long value)
 {
     unsigned long eflags;
+    struct vcpu *v = current;
 
     __asm__ __volatile__ ( VMWRITE_OPCODE
-                           MODRM_EAX_ECX       
+                           MODRM_EAX_ECX
                            :
                            : "a" (field) , "c" (value)
                            : "memory");
@@ -382,7 +368,7 @@
     case CR0_READ_SHADOW:
     case GUEST_CR0:
     case CPU_BASED_VM_EXEC_CONTROL:
-       __vmwrite_vcpu(field, value);
+       __vmwrite_vcpu(v, field, value);
        break;
     }
 
@@ -438,23 +424,24 @@
 static inline void vmx_stts(void)
 {
     unsigned long cr0;
-
-    __vmread_vcpu(GUEST_CR0, &cr0);
+    struct vcpu *v = current;
+
+    __vmread_vcpu(v, GUEST_CR0, &cr0);
     if (!(cr0 & X86_CR0_TS)) {
         __vmwrite(GUEST_CR0, cr0 | X86_CR0_TS);
     }
 
-    __vmread_vcpu(CR0_READ_SHADOW, &cr0);
+    __vmread_vcpu(v, CR0_READ_SHADOW, &cr0);
     if (!(cr0 & X86_CR0_TS))
        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 }
 
-/* Works only for ed == current */
+/* Works only for vcpu == current */
 static inline int vmx_paging_enabled(struct vcpu *v)
 {
     unsigned long cr0;
 
-    __vmread_vcpu(CR0_READ_SHADOW, &cr0);
+    __vmread_vcpu(v, CR0_READ_SHADOW, &cr0);
     return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
 }
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h        Sat Oct  8 17:37:45 2005
+++ b/xen/include/asm-x86/vmx_platform.h        Sat Oct  8 20:28:24 2005
@@ -75,20 +75,11 @@
 
 #define MAX_INST_LEN      32
 
-struct mi_per_cpu_info {
-    int                    flags;
-    int      instr;  /* instruction */
-    unsigned long          operand[2];  /* operands */
-    unsigned long          immediate;  /* immediate portion */
-    struct cpu_user_regs   *inst_decoder_regs; /* current context */
-};
-
 struct virtual_platform_def {
     unsigned long          *real_mode_data; /* E820, etc. */
     unsigned long          shared_page_va;
     struct vmx_virpit_t    vmx_pit;
     struct vmx_handler_t   vmx_handler;
-    struct mi_per_cpu_info mpci;  /* MMIO */
 };
 
 extern void handle_mmio(unsigned long, unsigned long);
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h    Sat Oct  8 17:37:45 2005
+++ b/xen/include/asm-x86/vmx_vmcs.h    Sat Oct  8 20:28:24 2005
@@ -53,6 +53,8 @@
     unsigned char data [0]; /* vmcs size is read from MSR */
 };
 
+extern int vmcs_size;
+
 enum { 
     VMX_INDEX_MSR_LSTAR = 0,
     VMX_INDEX_MSR_STAR,
@@ -67,6 +69,14 @@
     unsigned long flags;
     unsigned long msr_items[VMX_MSR_COUNT];
     unsigned long shadow_gs;
+};
+
+struct mmio_op {
+    int                    flags;
+    int                    instr;       /* instruction */
+    unsigned long          operand[2];  /* operands */
+    unsigned long          immediate;   /* immediate portion */
+    struct cpu_user_regs   *inst_decoder_regs; /* current context */
 };
 
 #define PC_DEBUG_PORT   0x80 
@@ -81,7 +91,8 @@
     unsigned long           cpu_state;
     unsigned long           cpu_based_exec_control;
     struct msr_state        msr_content;
-    void                   *io_bitmap_a, *io_bitmap_b;
+    struct mmio_op          mmio_op;  /* MMIO */
+    void                    *io_bitmap_a, *io_bitmap_b;
 };
 
 #define vmx_schedule_tail(next)         \
@@ -94,18 +105,11 @@
 #define ARCH_VMX_VMCS_RESUME    2       /* Needs VMCS resume */
 #define ARCH_VMX_IO_WAIT        3       /* Waiting for I/O completion */
 
-void vmx_do_launch(struct vcpu *); 
-void vmx_do_resume(struct vcpu *); 
-void vmx_set_host_env(struct vcpu *);
-
+void vmx_do_resume(struct vcpu *);
 struct vmcs_struct *alloc_vmcs(void);
-void free_vmcs(struct vmcs_struct *);
-int  load_vmcs(struct arch_vmx_struct *, u64);
-int  store_vmcs(struct arch_vmx_struct *, u64);
-int  construct_vmcs(struct arch_vmx_struct *, struct cpu_user_regs *, 
-                    struct vcpu_guest_context *, int);
 int modify_vmcs(struct arch_vmx_struct *arch_vmx,
                 struct cpu_user_regs *regs);
+void destroy_vmcs(struct arch_vmx_struct *arch_vmx);
 
 #define VMCS_USE_HOST_ENV       1
 #define VMCS_USE_SEPARATE_ENV   0
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Sat Oct  8 17:37:45 2005
+++ b/xen/include/public/dom0_ops.h     Sat Oct  8 20:28:24 2005
@@ -19,7 +19,7 @@
  * This makes sure that old versions of dom0 tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define DOM0_INTERFACE_VERSION   0xAAAA1010
+#define DOM0_INTERFACE_VERSION   0xAAAA1011
 
 /************************************************************************/
 
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Sat Oct  8 17:37:45 2005
+++ b/xen/include/public/event_channel.h        Sat Oct  8 20:28:24 2005
@@ -10,63 +10,55 @@
 #define __XEN_PUBLIC_EVENT_CHANNEL_H__
 
 /*
- * EVTCHNOP_alloc_unbound: Prepare a local port for binding to <dom>.
- * <port> may be wildcarded by setting to zero, in which case a fresh port
- * will be allocated, and the field filled in on return.
+ * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
+ * accepting interdomain bindings from domain <remote_dom>. A fresh port
+ * is allocated in <dom> and returned as <port>.
+ * NOTES:
+ *  1. If the caller is unprivileged then <dom> must be DOMID_SELF.
  */
 #define EVTCHNOP_alloc_unbound    6
 typedef struct evtchn_alloc_unbound {
     /* IN parameters */
-    domid_t dom;
-    /* IN/OUT parameters */
+    domid_t dom, remote_dom;
+    /* OUT parameters */
     u32     port;
 } evtchn_alloc_unbound_t;
 
 /*
  * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between
- * <dom1> and <dom2>. Either <port1> or <port2> may be wildcarded by setting to
- * zero. On successful return both <port1> and <port2> are filled in and
- * <dom1,port1> is fully bound to <dom2,port2>.
- * 
- * NOTES:
- *  1. A wildcarded port is allocated from the relevant domain's free list
- *     (i.e., some port that was previously EVTCHNSTAT_closed). However, if the
- *     remote port pair is already fully bound then a port is not allocated,
- *     and instead the existing local port is returned to the caller.
- *  2. If the caller is unprivileged then <dom1> must be DOMID_SELF.
- *  3. If the caller is unprivileged and <dom2,port2> is EVTCHNSTAT_closed
- *     then <dom2> must be DOMID_SELF.
- *  4. If either port is already bound then it must be bound to the other
- *     specified domain and port (if not wildcarded).
- *  5. If either port is awaiting binding (EVTCHNSTAT_unbound) then it must
- *     be awaiting binding to the other domain, and the other port pair must
- *     be closed or unbound.
+ * the calling domain and <remote_dom>. <remote_dom,remote_port> must identify
+ * a port that is unbound and marked as accepting bindings from the calling
+ * domain. A fresh port is allocated in the calling domain and returned as
+ * <local_port>.
  */
 #define EVTCHNOP_bind_interdomain 0
 typedef struct evtchn_bind_interdomain {
     /* IN parameters. */
-    domid_t dom1, dom2;
-    /* IN/OUT parameters. */
-    u32     port1, port2;
+    domid_t remote_dom;
+    u32     remote_port;
+    /* OUT parameters. */
+    u32     local_port;
 } evtchn_bind_interdomain_t;
 
 /*
- * EVTCHNOP_bind_virq: Bind a local event channel to IRQ <irq> on calling vcpu.
+ * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
+ * vcpu.
  * NOTES:
  *  1. A virtual IRQ may be bound to at most one event channel per vcpu.
- *  2. The allocated event channel is bound to the calling vcpu. The binding
+ *  2. The allocated event channel is bound to the specified vcpu. The binding
  *     may not be changed.
  */
 #define EVTCHNOP_bind_virq        1
 typedef struct evtchn_bind_virq {
     /* IN parameters. */
     u32 virq;
+    u32 vcpu;
     /* OUT parameters. */
     u32 port;
 } evtchn_bind_virq_t;
 
 /*
- * EVTCHNOP_bind_pirq: Bind a local event channel to IRQ <irq>.
+ * EVTCHNOP_bind_pirq: Bind a local event channel to PIRQ <irq>.
  * NOTES:
  *  1. A physical IRQ may be bound to at most one event channel per domain.
  *  2. Only a sufficiently-privileged domain may bind to a physical IRQ.
@@ -84,41 +76,35 @@
 /*
  * EVTCHNOP_bind_ipi: Bind a local event channel to receive events.
  * NOTES:
- *  1. The allocated event channel is bound to the calling vcpu. The binding
+ *  1. The allocated event channel is bound to the specified vcpu. The binding
  *     may not be changed.
  */
 #define EVTCHNOP_bind_ipi         7
 typedef struct evtchn_bind_ipi {
+    u32 vcpu;
     /* OUT parameters. */
     u32 port;
 } evtchn_bind_ipi_t;
 
 /*
- * EVTCHNOP_close: Close the communication channel which has an endpoint at
- * <dom, port>. If the channel is interdomain then the remote end is placed in
- * the unbound state (EVTCHNSTAT_unbound), awaiting a new connection.
- * NOTES:
- *  1. <dom> may be specified as DOMID_SELF.
- *  2. Only a sufficiently-privileged domain may close an event channel
- *     for which <dom> is not DOMID_SELF.
+ * EVTCHNOP_close: Close a local event channel <port>. If the channel is
+ * interdomain then the remote end is placed in the unbound state
+ * (EVTCHNSTAT_unbound), awaiting a new connection.
  */
 #define EVTCHNOP_close            3
 typedef struct evtchn_close {
     /* IN parameters. */
-    domid_t dom;
-    u32     port;
-    /* No OUT parameters. */
+    u32 port;
 } evtchn_close_t;
 
 /*
  * EVTCHNOP_send: Send an event to the remote end of the channel whose local
- * endpoint is <DOMID_SELF, local_port>.
+ * endpoint is <port>.
  */
 #define EVTCHNOP_send             4
 typedef struct evtchn_send {
     /* IN parameters. */
-    u32     local_port;
-    /* No OUT parameters. */
+    u32 port;
 } evtchn_send_t;
 
 /*
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Sat Oct  8 17:37:45 2005
+++ b/xen/include/public/xen.h  Sat Oct  8 20:28:24 2005
@@ -55,7 +55,7 @@
 #define __HYPERVISOR_update_va_mapping_otherdomain 22
 #define __HYPERVISOR_switch_vm86          23 /* x86/32 only */
 #define __HYPERVISOR_switch_to_user       23 /* x86/64 only */
-#define __HYPERVISOR_boot_vcpu            24
+#define __HYPERVISOR_vcpu_op              24
 #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
 #define __HYPERVISOR_mmuext_op            26
 #define __HYPERVISOR_acm_op               27
@@ -194,29 +194,6 @@
 #define UVMF_MULTI              (0UL<<2) /* Flush subset of TLBs. */
 #define UVMF_LOCAL              (0UL<<2) /* Flush local TLB.      */
 #define UVMF_ALL                (1UL<<2) /* Flush all TLBs.       */
-
-/*
- * Commands to HYPERVISOR_sched_op().
- */
-#define SCHEDOP_yield           0   /* Give up the CPU voluntarily.       */
-#define SCHEDOP_block           1   /* Block until an event is received.  */
-#define SCHEDOP_shutdown        2   /* Stop executing this domain.        */
-#define SCHEDOP_vcpu_down       3   /* make target VCPU not-runnable.     */
-#define SCHEDOP_vcpu_up         4   /* make target VCPU runnable.         */
-#define SCHEDOP_vcpu_pickle     5   /* save a vcpu's context to memory.   */
-#define SCHEDOP_cmdmask       255   /* 8-bit command. */
-#define SCHEDOP_reasonshift     8   /* 8-bit reason code. (SCHEDOP_shutdown) */
-#define SCHEDOP_vcpushift       8   /* 8-bit VCPU target. (SCHEDOP_up|down) */
-
-/*
- * Reason codes for SCHEDOP_shutdown. These may be interpreted by control 
- * software to determine the appropriate action. For the most part, Xen does
- * not care about the shutdown code (SHUTDOWN_crash excepted).
- */
-#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
-#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
-#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
-#define SHUTDOWN_crash      3  /* Tell controller we've crashed.             */
 
 /*
  * Commands to HYPERVISOR_console_io().
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/arch/xen/i386/kernel/vsyscall-note.S
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/vsyscall-note.S Sat Oct  8 
20:28:24 2005
@@ -0,0 +1,32 @@
+/*
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ * First we get the vanilla i386 note that supplies the kernel version info.
+ */
+
+#include "../../../i386/kernel/vsyscall-note.S"
+
+/*
+ * Now we add a special note telling glibc's dynamic linker a fake hardware
+ * flavor that it will use to choose the search path for libraries in the
+ * same way it uses real hardware capabilities like "mmx".
+ * We supply "nosegneg" as the fake capability, to indicate that we
+ * do not like negative offsets in instructions using segment overrides,
+ * since we implement those inefficiently.  This makes it possible to
+ * install libraries optimized to avoid those access patterns in someplace
+ * like /lib/i686/tls/nosegneg.  Note that an /etc/ld.so.conf.d/file
+ * corresponding to the bits here is needed to make ldconfig work right.
+ * It should contain:
+ *     hwcap 0 nosegneg
+ * to match the mapping of bit to name that we give here.
+ */
+#define NOTE_KERNELCAP_BEGIN(ncaps, mask) \
+       ASM_ELF_NOTE_BEGIN(".note.kernelcap", "a", "GNU", 2) \
+       .long ncaps, mask
+#define NOTE_KERNELCAP(bit, name) \
+       .byte bit; .asciz name
+#define NOTE_KERNELCAP_END ASM_ELF_NOTE_END
+
+NOTE_KERNELCAP_BEGIN(1, 1)
+NOTE_KERNELCAP(1, "nosegneg")  /* Change 1 back to 0 when glibc is fixed! */
+NOTE_KERNELCAP_END
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Sat Oct  8 20:28:24 2005
@@ -0,0 +1,58 @@
+#
+# TPM device configuration
+#
+
+menu "TPM devices"
+
+config TCG_TPM
+       tristate "TPM Hardware Support"
+       depends on EXPERIMENTAL && PCI
+       ---help---
+         If you have a TPM security chip in your system, which
+         implements the Trusted Computing Group's specification,
+         say Yes and it will be accessible from within Linux.  For
+         more information see <http://www.trustedcomputinggroup.org>. 
+         An implementation of the Trusted Software Stack (TSS), the 
+         userspace enablement piece of the specification, can be 
+         obtained at: <http://sourceforge.net/projects/trousers>.  To 
+         compile this driver as a module, choose M here; the module 
+         will be called tpm. If unsure, say N.
+
+config TCG_TIS
+       tristate "TPM Interface Specification 1.2 Interface"
+       depends on TCG_TPM
+       ---help---
+         If you have a TPM security chip that is compliant with the
+         TCG TIS 1.2 TPM specification say Yes and it will be accessible
+         from within Linux.  To compile this driver as a module, choose
+         M here; the module will be called tpm_tis.
+
+config TCG_NSC
+       tristate "National Semiconductor TPM Interface"
+       depends on TCG_TPM
+       ---help---
+         If you have a TPM security chip from National Semicondutor 
+         say Yes and it will be accessible from within Linux.  To 
+         compile this driver as a module, choose M here; the module 
+         will be called tpm_nsc.
+
+config TCG_ATMEL
+       tristate "Atmel TPM Interface"
+       depends on TCG_TPM
+       ---help---
+         If you have a TPM security chip from Atmel say Yes and it 
+         will be accessible from within Linux.  To compile this driver 
+         as a module, choose M here; the module will be called tpm_atmel.
+
+config TCG_XEN
+       tristate "XEN TPM Interface"
+       depends on TCG_TPM && ARCH_XEN && XEN_TPMDEV_FRONTEND
+       ---help---
+         If you want to make TPM support available to a Xen
+         user domain, say Yes and it will
+          be accessible from within Linux. To compile this driver
+          as a module, choose M here; the module will be called
+          tpm_xen.
+
+endmenu
+
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.6-xen-sparse/drivers/char/tpm/tpm.c
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c       Sat Oct  8 20:28:24 2005
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org      
+ *
+ * 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, version 2 of the
+ * License.
+ * 
+ * Note, the TPM chip is not interrupt driven (only polling)
+ * and can have very long timeouts (minutes!). Hence the unusual
+ * calls to msleep.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include "tpm.h"
+
+#define TPM_CHIP_NUM_MASK      0x0000ffff
+#define TPM_CHIP_TYPE_SHIFT    16      
+
+enum tpm_const {
+       TPM_MINOR = 224,        /* officially assigned */
+       TPM_MIN_BUFSIZE = 2048,
+       TPM_MAX_BUFSIZE = 64 * 1024,
+       TPM_NUM_DEVICES = 256,
+       TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
+};
+
+static LIST_HEAD(tpm_chip_list);
+static DEFINE_SPINLOCK(driver_lock);
+static int dev_mask[TPM_NUM_MASK_ENTRIES];
+
+static void user_reader_timeout(unsigned long ptr)
+{
+       struct tpm_chip *chip = (struct tpm_chip *) ptr;
+
+       down(&chip->buffer_mutex);
+       atomic_set(&chip->data_pending, 0);
+       memset(chip->data_buffer, 0, chip->vendor->buffersize);
+       up(&chip->buffer_mutex);
+}
+
+/*
+ * Internal kernel interface to transmit TPM commands
+ */
+static ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
+                           size_t bufsiz)
+{
+       ssize_t rc;
+       u32 count;
+       unsigned long stop;
+
+       if (!chip)
+               return -ENODEV;
+
+       if ( !chip )
+               return -ENODEV;
+
+       count = be32_to_cpu(*((__be32 *) (buf + 2)));
+
+       if (count == 0)
+               return -ENODATA;
+       if (count > bufsiz) {
+               dev_err(chip->dev,
+                       "invalid count value %x %zx \n", count, bufsiz);
+               return -E2BIG;
+       }
+
+       down(&chip->tpm_mutex);
+
+       if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+               dev_err(chip->dev,
+                       "tpm_transmit: tpm_send: error %zd\n", rc);
+               goto out;
+       }
+
+       stop = jiffies + 2 * 60 * HZ;
+       do {
+               u8 status = chip->vendor->status(chip);
+               if ((status & chip->vendor->req_complete_mask) ==
+                   chip->vendor->req_complete_val) {
+                       goto out_recv;
+               }
+
+               if ((status == chip->vendor->req_canceled)) {
+                       dev_err(chip->dev, "Operation Canceled\n");
+                       rc = -ECANCELED;
+                       goto out;
+               }
+
+               msleep(TPM_TIMEOUT);    /* CHECK */
+               rmb();
+       } while (time_before(jiffies, stop));
+
+
+       chip->vendor->cancel(chip);
+       dev_err(chip->dev, "Operation Timed out\n");
+       rc = -ETIME;
+       goto out;
+
+out_recv:
+       rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+       if (rc < 0)
+               dev_err(chip->dev,
+                       "tpm_transmit: tpm_recv: error %zd\n", rc);
+out:
+       up(&chip->tpm_mutex);
+       return rc;
+}
+
+#define TPM_DIGEST_SIZE 20
+#define CAP_PCR_RESULT_SIZE 18
+static const u8 cap_pcr[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 22,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 5,
+       0, 0, 0, 4,
+       0, 0, 1, 1
+};
+
+#define READ_PCR_RESULT_SIZE 30
+static const u8 pcrread[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 14,            /* length */
+       0, 0, 0, 21,            /* TPM_ORD_PcrRead */
+       0, 0, 0, 0              /* PCR index */
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
+ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
+                     char *buf)
+#else
+ssize_t tpm_show_pcrs(struct device *dev,
+                     char *buf)
+#endif
+{
+       u8 data[READ_PCR_RESULT_SIZE];
+       ssize_t len;
+       int i, j, num_pcrs;
+       __be32 index;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, cap_pcr, sizeof(cap_pcr));
+       if ((len = tpm_transmit(chip, data, sizeof(data)))
+           < CAP_PCR_RESULT_SIZE) {
+               dev_dbg(chip->dev, "A TPM error (%d) occurred "
+                               "attempting to determine the number of PCRS\n",
+                       be32_to_cpu(*((__be32 *) (data + 6))));
+               return 0;
+       }
+
+       num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
+
+       for (i = 0; i < num_pcrs; i++) {
+               memcpy(data, pcrread, sizeof(pcrread));
+               index = cpu_to_be32(i);
+               memcpy(data + 10, &index, 4);
+               if ((len = tpm_transmit(chip, data, sizeof(data)))
+                   < READ_PCR_RESULT_SIZE){
+                       dev_dbg(chip->dev, "A TPM error (%d) occurred"
+                               " attempting to read PCR %d of %d\n",
+                               be32_to_cpu(*((__be32 *) (data + 6))), i, 
num_pcrs);
+                       goto out;
+               }
+               str += sprintf(str, "PCR-%02d: ", i);
+               for (j = 0; j < TPM_DIGEST_SIZE; j++)
+                       str += sprintf(str, "%02X ", *(data + 10 + j));
+               str += sprintf(str, "\n");
+       }
+out:
+       return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_pcrs);
+
+#define  READ_PUBEK_RESULT_SIZE 314
+static const u8 readpubek[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 30,            /* length */
+       0, 0, 0, 124,           /* TPM_ORD_ReadPubek */
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
+ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
+                      char *buf)
+#else
+ssize_t tpm_show_pubek(struct device *dev,
+                      char *buf)
+#endif
+{
+       u8 *data;
+       ssize_t len;
+       int i, rc;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       memcpy(data, readpubek, sizeof(readpubek));
+       memset(data + sizeof(readpubek), 0, 20);        /* zero nonce */
+
+       if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
+           READ_PUBEK_RESULT_SIZE) {
+               dev_dbg(chip->dev, "A TPM error (%d) occurred "
+                               "attempting to read the PUBEK\n",
+                           be32_to_cpu(*((__be32 *) (data + 6))));
+               rc = 0;
+               goto out;
+       }
+
+       /* 
+          ignore header 10 bytes
+          algorithm 32 bits (1 == RSA )
+          encscheme 16 bits
+          sigscheme 16 bits
+          parameters (RSA 12->bytes: keybit, #primes, expbit)  
+          keylenbytes 32 bits
+          256 byte modulus
+          ignore checksum 20 bytes
+        */
+
+       str +=
+           sprintf(str,
+                   "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
+                   "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
+                   " %02X %02X %02X %02X %02X %02X %02X %02X\n"
+                   "Modulus length: %d\nModulus: \n",
+                   data[10], data[11], data[12], data[13], data[14],
+                   data[15], data[16], data[17], data[22], data[23],
+                   data[24], data[25], data[26], data[27], data[28],
+                   data[29], data[30], data[31], data[32], data[33],
+                   be32_to_cpu(*((__be32 *) (data + 34))));
+
+       for (i = 0; i < 256; i++) {
+               str += sprintf(str, "%02X ", data[i + 38]);
+               if ((i + 1) % 16 == 0)
+                       str += sprintf(str, "\n");
+       }
+       rc = str - buf;
+out:
+       kfree(data);
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(tpm_show_pubek);
+
+#define CAP_VER_RESULT_SIZE 18
+static const u8 cap_version[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 18,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 6,
+       0, 0, 0, 0
+};
+
+#define CAP_MANUFACTURER_RESULT_SIZE 18
+static const u8 cap_manufacturer[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 22,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 5,
+       0, 0, 0, 4,
+       0, 0, 1, 3
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
+ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
+                     char *buf)
+#else
+ssize_t tpm_show_caps(struct device *dev,
+                     char *buf)
+#endif
+{
+       u8 data[sizeof(cap_manufacturer)];
+       ssize_t len;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <
+           CAP_MANUFACTURER_RESULT_SIZE)
+               return len;
+
+       str += sprintf(str, "Manufacturer: 0x%x\n",
+                      be32_to_cpu(*((__be32 *) (data + 14))));
+
+       memcpy(data, cap_version, sizeof(cap_version));
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <
+           CAP_VER_RESULT_SIZE)
+               return len;
+
+       str +=
+           sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
+                   (int) data[14], (int) data[15], (int) data[16],
+                   (int) data[17]);
+
+       return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_caps);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
+ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+#else
+ssize_t tpm_store_cancel(struct device *dev,
+                       const char *buf, size_t count)
+#endif
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return 0;
+
+       chip->vendor->cancel(chip);
+       return count;
+}
+EXPORT_SYMBOL_GPL(tpm_store_cancel);
+
+
+/*
+ * Device file system interface to the TPM
+ */
+int tpm_open(struct inode *inode, struct file *file)
+{
+       int rc = 0, minor = iminor(inode);
+       struct tpm_chip *chip = NULL, *pos;
+
+       spin_lock(&driver_lock);
+
+       list_for_each_entry(pos, &tpm_chip_list, list) {
+               if (pos->vendor->miscdev.minor == minor) {
+                       chip = pos;
+                       break;
+               }
+       }
+
+       if (chip == NULL) {
+               rc = -ENODEV;
+               goto err_out;
+       }
+
+       if (chip->num_opens) {
+               dev_dbg(chip->dev,
+                       "Another process owns this TPM\n");
+               rc = -EBUSY;
+               goto err_out;
+       }
+
+       chip->num_opens++;
+       get_device(chip->dev);
+
+       spin_unlock(&driver_lock);
+
+       chip->data_buffer = kmalloc(chip->vendor->buffersize * sizeof(u8), 
GFP_KERNEL);
+       if (chip->data_buffer == NULL) {
+               chip->num_opens--;
+               put_device(chip->dev);
+               return -ENOMEM;
+       }
+
+       atomic_set(&chip->data_pending, 0);
+
+       file->private_data = chip;
+       return 0;
+
+err_out:
+       spin_unlock(&driver_lock);
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(tpm_open);
+
+int tpm_release(struct inode *inode, struct file *file)
+{
+       struct tpm_chip *chip = file->private_data;
+
+       spin_lock(&driver_lock);
+       file->private_data = NULL;
+       chip->num_opens--;
+       del_singleshot_timer_sync(&chip->user_read_timer);
+       atomic_set(&chip->data_pending, 0);
+       put_device(chip->dev);
+       kfree(chip->data_buffer);
+       spin_unlock(&driver_lock);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_release);
+
+ssize_t tpm_write(struct file * file, const char __user * buf,
+                 size_t size, loff_t * off)
+{
+       struct tpm_chip *chip = file->private_data;
+       int in_size = size, out_size;
+
+       /* cannot perform a write until the read has cleared
+          either via tpm_read or a user_read_timer timeout */
+       while (atomic_read(&chip->data_pending) != 0)
+               msleep(TPM_TIMEOUT);
+
+       down(&chip->buffer_mutex);
+
+       if (in_size > chip->vendor->buffersize)
+               in_size = chip->vendor->buffersize;
+
+       if (copy_from_user
+           (chip->data_buffer, (void __user *) buf, in_size)) {
+               up(&chip->buffer_mutex);
+               return -EFAULT;
+       }
+
+       /* atomic tpm command send and result receive */
+       out_size = tpm_transmit(chip, chip->data_buffer, 
+                               chip->vendor->buffersize);
+
+       atomic_set(&chip->data_pending, out_size);
+       atomic_set(&chip->data_position, 0);
+       up(&chip->buffer_mutex);
+
+       /* Set a timeout by which the reader must come claim the result */
+       mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
+
+       return in_size;
+}
+
+EXPORT_SYMBOL_GPL(tpm_write);
+
+ssize_t tpm_read(struct file * file, char __user * buf,
+                size_t size, loff_t * off)
+{
+       struct tpm_chip *chip = file->private_data;
+       int ret_size;
+       int pos, pending = 0;
+
+       ret_size = atomic_read(&chip->data_pending);
+       if (ret_size > 0) {     /* relay data */
+               if (size < ret_size)
+                       ret_size = size;
+
+               pos = atomic_read(&chip->data_position);
+
+               down(&chip->buffer_mutex);
+               if (copy_to_user
+                   ((void __user *) buf, &chip->data_buffer[pos], ret_size)) {
+                       ret_size = -EFAULT;
+               } else {
+                       pending = atomic_read(&chip->data_pending) - ret_size;
+                       if ( pending ) {
+                               atomic_set( &chip->data_pending, pending );
+                               atomic_set( &chip->data_position, pos+ret_size 
);
+                       }
+               }
+               up(&chip->buffer_mutex);
+       }
+       
+       if ( ret_size <= 0 || pending == 0 ) {
+               atomic_set( &chip->data_pending, 0 );
+               del_singleshot_timer_sync(&chip->user_read_timer);
+       }
+
+       return ret_size;
+}
+
+EXPORT_SYMBOL_GPL(tpm_read);
+
+void tpm_remove_hardware(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+
+       if (chip == NULL) {
+               dev_err(dev, "No device data found\n");
+               return;
+       }
+
+       spin_lock(&driver_lock);
+
+       list_del(&chip->list);
+
+       spin_unlock(&driver_lock);
+
+       dev_set_drvdata(dev, NULL);
+       misc_deregister(&chip->vendor->miscdev);
+       kfree(chip->vendor->miscdev.name);
+
+       sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
+
+       dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << 
(chip->dev_num % TPM_NUM_MASK_ENTRIES));
+
+       kfree(chip);
+
+       put_device(dev);
+}
+
+EXPORT_SYMBOL_GPL(tpm_remove_hardware);
+
+static u8 savestate[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 10,            /* blob length (in bytes) */
+       0, 0, 0, 152            /* TPM_ORD_SaveState */
+};
+
+/*
+ * We are about to suspend. Save the TPM state
+ * so that it can be restored.
+ */
+int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       tpm_transmit(chip, savestate, sizeof(savestate));
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_pm_suspend);
+
+/*
+ * Resume from a power safe. The BIOS already restored
+ * the TPM state.
+ */
+int tpm_pm_resume(struct pci_dev *pci_dev)
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+
+       if (chip == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_pm_resume);
+
+/*
+ * Called from tpm_<specific>.c probe function only for devices 
+ * the driver has determined it should claim.  Prior to calling
+ * this function the specific probe function has called pci_enable_device
+ * upon errant exit from this function specific probe function should call
+ * pci_disable_device
+ */
+int tpm_register_hardware(struct device *dev,
+                         struct tpm_vendor_specific *entry)
+{
+#define DEVNAME_SIZE 7
+
+       char *devname;
+       struct tpm_chip *chip;
+       int i, j;
+
+       /* Driver specific per-device data */
+       chip = kmalloc(sizeof(*chip), GFP_KERNEL);
+       if (chip == NULL)
+               return -ENOMEM;
+
+       memset(chip, 0, sizeof(struct tpm_chip));
+
+       init_MUTEX(&chip->buffer_mutex);
+       init_MUTEX(&chip->tpm_mutex);
+       INIT_LIST_HEAD(&chip->list);
+
+       init_timer(&chip->user_read_timer);
+       chip->user_read_timer.function = user_reader_timeout;
+       chip->user_read_timer.data = (unsigned long) chip;
+
+       chip->vendor = entry;
+       
+       if (entry->buffersize < TPM_MIN_BUFSIZE) {
+               entry->buffersize = TPM_MIN_BUFSIZE;
+       } else if (entry->buffersize > TPM_MAX_BUFSIZE) {
+               entry->buffersize = TPM_MAX_BUFSIZE;
+       }
+
+       chip->dev_num = -1;
+
+       for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
+               for (j = 0; j < 8 * sizeof(int); j++)
+                       if ((dev_mask[i] & (1 << j)) == 0) {
+                               chip->dev_num =
+                                   i * TPM_NUM_MASK_ENTRIES + j;
+                               dev_mask[i] |= 1 << j;
+                               goto dev_num_search_complete;
+                       }
+
+dev_num_search_complete:
+       if (chip->dev_num < 0) {
+               dev_err(dev,
+                       "No available tpm device numbers\n");
+               kfree(chip);
+               return -ENODEV;
+       } else if (chip->dev_num == 0)
+               chip->vendor->miscdev.minor = TPM_MINOR;
+       else
+               chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
+
+       devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
+       scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
+       chip->vendor->miscdev.name = devname;
+
+       chip->vendor->miscdev.dev = dev;
+       chip->dev = get_device(dev);
+
+       if (misc_register(&chip->vendor->miscdev)) {
+               dev_err(chip->dev,
+                       "unable to misc_register %s, minor %d\n",
+                       chip->vendor->miscdev.name,
+                       chip->vendor->miscdev.minor);
+               put_device(dev);
+               kfree(chip);
+               dev_mask[i] &= !(1 << j);
+               return -ENODEV;
+       }
+
+       spin_lock(&driver_lock);
+
+       dev_set_drvdata(dev, chip);
+
+       list_add(&chip->list, &tpm_chip_list);
+
+       spin_unlock(&driver_lock);
+
+       sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_register_hardware);
+
+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.6-xen-sparse/drivers/char/tpm/tpm.h
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Sat Oct  8 20:28:24 2005
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org      
+ *
+ * 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, version 2 of the
+ * License.
+ * 
+ */
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+
+enum tpm_timeout {
+       TPM_TIMEOUT = 5,        /* msecs */
+};
+
+/* TPM addresses */
+enum tpm_addr {
+       TPM_SUPERIO_ADDR = 0x2E,
+       TPM_ADDR = 0x4E,
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
+extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
+                               const char *, size_t);
+#else
+extern ssize_t tpm_show_pubek(struct device *,
+                               char *);
+extern ssize_t tpm_show_pcrs(struct device *,
+                               char *);
+extern ssize_t tpm_show_caps(struct device *,
+                               char *);
+extern ssize_t tpm_store_cancel(struct device *,
+                               const char *, size_t);
+#endif
+
+struct tpm_chip;
+
+struct tpm_vendor_specific {
+       u8 req_complete_mask;
+       u8 req_complete_val;
+       u8 req_canceled;
+       u16 base;               /* TPM base address */
+       int drv_type;
+       u32 buffersize;
+
+       int (*recv) (struct tpm_chip *, u8 *, size_t);
+       int (*send) (struct tpm_chip *, u8 *, size_t);
+       void (*cancel) (struct tpm_chip *);
+       u8 (*status) (struct tpm_chip *);
+       struct miscdevice miscdev;
+       struct attribute_group *attr_group;
+};
+
+struct tpm_chip {
+       struct device *dev;     /* Device stuff */
+
+       int dev_num;            /* /dev/tpm# */
+       int num_opens;          /* only one allowed */
+       int time_expired;
+
+       /* Data passed to and from the tpm via the read/write calls */
+       u8 *data_buffer;
+       atomic_t data_pending;
+       atomic_t data_position;
+       struct semaphore buffer_mutex;
+
+       struct timer_list user_read_timer;      /* user needs to claim result */
+       struct semaphore tpm_mutex;     /* tpm is processing */
+
+       struct tpm_vendor_specific *vendor;
+
+       struct list_head list;
+};
+
+static inline int tpm_read_index(int base, int index)
+{
+       outb(index, base);
+       return inb(base+1) & 0xFF;
+}
+
+static inline void tpm_write_index(int base, int index, int value)
+{
+       outb(index, base);
+       outb(value & 0xFF, base+1);
+}
+
+extern int tpm_register_hardware(struct device *,
+                                struct tpm_vendor_specific *);
+extern int tpm_open(struct inode *, struct file *);
+extern int tpm_release(struct inode *, struct file *);
+extern ssize_t tpm_write(struct file *, const char __user *, size_t,
+                        loff_t *);
+extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
+extern void tpm_remove_hardware(struct device *);
+extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
+extern int tpm_pm_resume(struct pci_dev *);
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c Sat Oct  8 20:28:24 2005
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org      
+ *
+ * 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, version 2 of the
+ * License.
+ * 
+ */
+
+#include "tpm.h"
+
+/* Atmel definitions */
+enum tpm_atmel_addr {
+       TPM_ATMEL_BASE_ADDR_LO = 0x08,
+       TPM_ATMEL_BASE_ADDR_HI = 0x09
+};
+
+/* write status bits */
+enum tpm_atmel_write_status {
+       ATML_STATUS_ABORT = 0x01,
+       ATML_STATUS_LASTBYTE = 0x04
+};
+/* read status bits */
+enum tpm_atmel_read_status {
+       ATML_STATUS_BUSY = 0x01,
+       ATML_STATUS_DATA_AVAIL = 0x02,
+       ATML_STATUS_REWRITE = 0x04,
+       ATML_STATUS_READY = 0x08
+};
+
+static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       u8 status, *hdr = buf;
+       u32 size;
+       int i;
+       __be32 *native_size;
+
+       /* start reading header */
+       if (count < 6)
+               return -EIO;
+
+       for (i = 0; i < 6; i++) {
+               status = inb(chip->vendor->base + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(chip->dev,
+                               "error reading header\n");
+                       return -EIO;
+               }
+               *buf++ = inb(chip->vendor->base);
+       }
+
+       /* size of the data received */
+       native_size = (__force __be32 *) (hdr + 2);
+       size = be32_to_cpu(*native_size);
+
+       if (count < size) {
+               dev_err(chip->dev,
+                       "Recv size(%d) less than available space\n", size);
+               for (; i < size; i++) { /* clear the waiting data anyway */
+                       status = inb(chip->vendor->base + 1);
+                       if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                               dev_err(chip->dev,
+                                       "error reading data\n");
+                               return -EIO;
+                       }
+               }
+               return -EIO;
+       }
+
+       /* read all the data available */
+       for (; i < size; i++) {
+               status = inb(chip->vendor->base + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(chip->dev,
+                               "error reading data\n");
+                       return -EIO;
+               }
+               *buf++ = inb(chip->vendor->base);
+       }
+
+       /* make sure data available is gone */
+       status = inb(chip->vendor->base + 1);
+       if (status & ATML_STATUS_DATA_AVAIL) {
+               dev_err(chip->dev, "data available is stuck\n");
+               return -EIO;
+       }
+
+       return size;
+}
+
+static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       int i;
+
+       dev_dbg(chip->dev, "tpm_atml_send:\n");
+       for (i = 0; i < count; i++) {
+               dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
+               outb(buf[i], chip->vendor->base);
+       }
+
+       return count;
+}
+
+static void tpm_atml_cancel(struct tpm_chip *chip)
+{
+       outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
+}
+
+static u8 tpm_atml_status(struct tpm_chip *chip)
+{
+       return inb(chip->vendor->base + 1);
+}
+
+static struct file_operations atmel_ops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .open = tpm_open,
+       .read = tpm_read,
+       .write = tpm_write,
+       .release = tpm_release,
+};
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute* atmel_attrs[] = {
+       &dev_attr_pubek.attr,
+       &dev_attr_pcrs.attr,
+       &dev_attr_caps.attr,
+       &dev_attr_cancel.attr,
+       0,
+};
+
+static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
+
+static struct tpm_vendor_specific tpm_atmel = {
+       .recv = tpm_atml_recv,
+       .send = tpm_atml_send,
+       .cancel = tpm_atml_cancel,
+       .status = tpm_atml_status,
+       .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
+       .req_complete_val = ATML_STATUS_DATA_AVAIL,
+       .req_canceled = ATML_STATUS_READY,
+       .attr_group = &atmel_attr_grp,
+       .miscdev = { .fops = &atmel_ops, },
+};
+
+static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
+                                  const struct pci_device_id *pci_id)
+{
+       u8 version[4];
+       int rc = 0;
+       int lo, hi;
+
+       if (pci_enable_device(pci_dev))
+               return -EIO;
+
+       lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+       hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+
+       tpm_atmel.base = (hi<<8)|lo;
+       dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
+
+       /* verify that it is an Atmel part */
+       if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) 
!= 'T'
+           || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 
7) != 'L') {
+               rc = -ENODEV;
+               goto out_err;
+       }
+
+       /* query chip for its version number */
+       if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
+               version[1] = tpm_read_index(TPM_ADDR, 0x01);
+               version[2] = tpm_read_index(TPM_ADDR, 0x02);
+               version[3] = tpm_read_index(TPM_ADDR, 0x03);
+       } else {
+               dev_info(&pci_dev->dev, "version query failed\n");
+               rc = -ENODEV;
+               goto out_err;
+       }
+
+       if ((rc = tpm_register_hardware(&pci_dev->dev, &tpm_atmel)) < 0)
+               goto out_err;
+
+       dev_info(&pci_dev->dev,
+                "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
+                version[2], version[3]);
+
+       return 0;
+out_err:
+       pci_disable_device(pci_dev);
+       return rc;
+}
+
+static void __devexit tpm_atml_remove(struct pci_dev *pci_dev) 
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+
+       if ( chip )
+               tpm_remove_hardware(chip->dev);
+}
+
+static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+#ifndef PCI_DEVICE_ID_SERVERWORKS_CSB6LPC
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
+#else
+#warning Remove the define of PCI_DEVICE_ID_SERVERWORKS_CSB6LPC
+#endif
+       {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 
PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
+       {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+
+static struct pci_driver atmel_pci_driver = {
+       .name = "tpm_atmel",
+       .id_table = tpm_pci_tbl,
+       .probe = tpm_atml_init,
+       .remove = __devexit_p(tpm_atml_remove),
+       .suspend = tpm_pm_suspend,
+       .resume = tpm_pm_resume,
+};
+
+static int __init init_atmel(void)
+{
+       return pci_register_driver(&atmel_pci_driver);
+}
+
+static void __exit cleanup_atmel(void)
+{
+       pci_unregister_driver(&atmel_pci_driver);
+}
+
+fs_initcall(init_atmel);
+module_exit(cleanup_atmel);
+
+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c   Sat Oct  8 20:28:24 2005
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org      
+ *
+ * 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, version 2 of the
+ * License.
+ * 
+ */
+
+#include "tpm.h"
+
+/* National definitions */
+enum tpm_nsc_addr{
+       TPM_NSC_IRQ = 0x07,
+       TPM_NSC_BASE0_HI = 0x60,
+       TPM_NSC_BASE0_LO = 0x61,
+       TPM_NSC_BASE1_HI = 0x62,
+       TPM_NSC_BASE1_LO = 0x63
+};
+
+enum tpm_nsc_index {
+       NSC_LDN_INDEX = 0x07,
+       NSC_SID_INDEX = 0x20,
+       NSC_LDC_INDEX = 0x30,
+       NSC_DIO_INDEX = 0x60,
+       NSC_CIO_INDEX = 0x62,
+       NSC_IRQ_INDEX = 0x70,
+       NSC_ITS_INDEX = 0x71
+};
+
+enum tpm_nsc_status_loc {
+       NSC_STATUS = 0x01,
+       NSC_COMMAND = 0x01,
+       NSC_DATA = 0x00
+};
+
+/* status bits */
+enum tpm_nsc_status {
+       NSC_STATUS_OBF = 0x01,  /* output buffer full */
+       NSC_STATUS_IBF = 0x02,  /* input buffer full */
+       NSC_STATUS_F0 = 0x04,   /* F0 */
+       NSC_STATUS_A2 = 0x08,   /* A2 */
+       NSC_STATUS_RDY = 0x10,  /* ready to receive command */
+       NSC_STATUS_IBR = 0x20   /* ready to receive data */
+};
+
+/* command bits */
+enum tpm_nsc_cmd_mode {
+       NSC_COMMAND_NORMAL = 0x01,      /* normal mode */
+       NSC_COMMAND_EOC = 0x03,
+       NSC_COMMAND_CANCEL = 0x22
+};
+/*
+ * Wait for a certain status to appear
+ */
+static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
+{
+       unsigned long stop;
+
+       /* status immediately available check */
+       *data = inb(chip->vendor->base + NSC_STATUS);
+       if ((*data & mask) == val)
+               return 0;
+
+       /* wait for status */
+       stop = jiffies + 10 * HZ;
+       do {
+               msleep(TPM_TIMEOUT);
+               *data = inb(chip->vendor->base + 1);
+               if ((*data & mask) == val)
+                       return 0;
+       }
+       while (time_before(jiffies, stop));
+
+       return -EBUSY;
+}
+
+static int nsc_wait_for_ready(struct tpm_chip *chip)
+{
+       int status;
+       unsigned long stop;
+
+       /* status immediately available check */
+       status = inb(chip->vendor->base + NSC_STATUS);
+       if (status & NSC_STATUS_OBF)
+               status = inb(chip->vendor->base + NSC_DATA);
+       if (status & NSC_STATUS_RDY)
+               return 0;
+
+       /* wait for status */
+       stop = jiffies + 100;
+       do {
+               msleep(TPM_TIMEOUT);
+               status = inb(chip->vendor->base + NSC_STATUS);
+               if (status & NSC_STATUS_OBF)
+                       status = inb(chip->vendor->base + NSC_DATA);
+               if (status & NSC_STATUS_RDY)
+                       return 0;
+       }
+       while (time_before(jiffies, stop));
+
+       dev_info(chip->dev, "wait for ready failed\n");
+       return -EBUSY;
+}
+
+
+static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       u8 *buffer = buf;
+       u8 data, *p;
+       u32 size;
+       __be32 *native_size;
+
+       if (count < 6)
+               return -EIO;
+
+       if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
+               dev_err(chip->dev, "F0 timeout\n");
+               return -EIO;
+       }
+       if ((data =
+            inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
+               dev_err(chip->dev, "not in normal mode (0x%x)\n",
+                       data);
+               return -EIO;
+       }
+
+       /* read the whole packet */
+       for (p = buffer; p < &buffer[count]; p++) {
+               if (wait_for_stat
+                   (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
+                       dev_err(chip->dev,
+                               "OBF timeout (while reading data)\n");
+                       return -EIO;
+               }
+               if (data & NSC_STATUS_F0)
+                       break;
+               *p = inb(chip->vendor->base + NSC_DATA);
+       }
+
+       if ((data & NSC_STATUS_F0) == 0 &&
+       (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
+               dev_err(chip->dev, "F0 not set\n");
+               return -EIO;
+       }
+       if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
+               dev_err(chip->dev,
+                       "expected end of command(0x%x)\n", data);
+               return -EIO;
+       }
+
+       native_size = (__force __be32 *) (buf + 2);
+       size = be32_to_cpu(*native_size);
+
+       if (count < size)
+               return -EIO;
+
+       return size;
+}
+
+static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       u8 data;
+       int i;
+
+       /*
+        * If we hit the chip with back to back commands it locks up
+        * and never set IBF. Hitting it with this "hammer" seems to
+        * fix it. Not sure why this is needed, we followed the flow
+        * chart in the manual to the letter.
+        */
+       outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+
+       if (nsc_wait_for_ready(chip) != 0)
+               return -EIO;
+
+       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+               dev_err(chip->dev, "IBF timeout\n");
+               return -EIO;
+       }
+
+       outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
+       if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
+               dev_err(chip->dev, "IBR timeout\n");
+               return -EIO;
+       }
+
+       for (i = 0; i < count; i++) {
+               if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+                       dev_err(chip->dev,
+                               "IBF timeout (while writing data)\n");
+                       return -EIO;
+               }
+               outb(buf[i], chip->vendor->base + NSC_DATA);
+       }
+
+       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+               dev_err(chip->dev, "IBF timeout\n");
+               return -EIO;
+       }
+       outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
+
+       return count;
+}
+
+static void tpm_nsc_cancel(struct tpm_chip *chip)
+{
+       outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+}
+
+static u8 tpm_nsc_status(struct tpm_chip *chip)
+{
+       return inb(chip->vendor->base + NSC_STATUS);
+}
+
+static struct file_operations nsc_ops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .open = tpm_open,
+       .read = tpm_read,
+       .write = tpm_write,
+       .release = tpm_release,
+};
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute * nsc_attrs[] = {
+       &dev_attr_pubek.attr,
+       &dev_attr_pcrs.attr,
+       &dev_attr_caps.attr,
+       &dev_attr_cancel.attr,
+       0,
+};
+
+static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
+
+static struct tpm_vendor_specific tpm_nsc = {
+       .recv = tpm_nsc_recv,
+       .send = tpm_nsc_send,
+       .cancel = tpm_nsc_cancel,
+       .status = tpm_nsc_status,
+       .req_complete_mask = NSC_STATUS_OBF,
+       .req_complete_val = NSC_STATUS_OBF,
+       .req_canceled = NSC_STATUS_RDY,
+       .attr_group = &nsc_attr_grp,
+       .miscdev = { .fops = &nsc_ops, },
+};
+
+static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
+                                 const struct pci_device_id *pci_id)
+{
+       int rc = 0;
+       int lo, hi;
+       int nscAddrBase = TPM_ADDR;
+
+
+       if (pci_enable_device(pci_dev))
+               return -EIO;
+
+       /* select PM channel 1 */
+       tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
+
+       /* verify that it is a National part (SID) */
+       if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
+               nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
+                       (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
+               if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
+                       rc = -ENODEV;
+                       goto out_err;
+               }
+       }
+
+       hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
+       lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
+       tpm_nsc.base = (hi<<8) | lo;
+
+       dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
+       dev_dbg(&pci_dev->dev,
+               "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
+               tpm_read_index(nscAddrBase,0x07), 
tpm_read_index(nscAddrBase,0x20),
+               tpm_read_index(nscAddrBase,0x27));
+       dev_dbg(&pci_dev->dev,
+               "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
+               tpm_read_index(nscAddrBase,0x21), 
tpm_read_index(nscAddrBase,0x25),
+               tpm_read_index(nscAddrBase,0x26), 
tpm_read_index(nscAddrBase,0x28));
+       dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
+               (tpm_read_index(nscAddrBase,0x60) << 8) | 
tpm_read_index(nscAddrBase,0x61));
+       dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
+               (tpm_read_index(nscAddrBase,0x62) << 8) | 
tpm_read_index(nscAddrBase,0x63));
+       dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
+               tpm_read_index(nscAddrBase,0x70));
+       dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
+               tpm_read_index(nscAddrBase,0x71));
+       dev_dbg(&pci_dev->dev,
+               "NSC DMA channel select0 0x%x, select1 0x%x\n",
+               tpm_read_index(nscAddrBase,0x74), 
tpm_read_index(nscAddrBase,0x75));
+       dev_dbg(&pci_dev->dev,
+               "NSC Config "
+               "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+               tpm_read_index(nscAddrBase,0xF0), 
tpm_read_index(nscAddrBase,0xF1),
+               tpm_read_index(nscAddrBase,0xF2), 
tpm_read_index(nscAddrBase,0xF3),
+               tpm_read_index(nscAddrBase,0xF4), 
tpm_read_index(nscAddrBase,0xF5),
+               tpm_read_index(nscAddrBase,0xF6), 
tpm_read_index(nscAddrBase,0xF7),
+               tpm_read_index(nscAddrBase,0xF8), 
tpm_read_index(nscAddrBase,0xF9));
+
+       dev_info(&pci_dev->dev,
+                "NSC TPM revision %d\n",
+                tpm_read_index(nscAddrBase, 0x27) & 0x1F);
+
+       /* enable the DPM module */
+       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
+
+       if ((rc = tpm_register_hardware(&pci_dev->dev, &tpm_nsc)) < 0)
+               goto out_err;
+
+       return 0;
+
+out_err:
+       pci_disable_device(pci_dev);
+       return rc;
+}
+
+static void __devexit tpm_nsc_remove(struct pci_dev *pci_dev) 
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+
+       if ( chip )
+               tpm_remove_hardware(chip->dev);
+}
+
+static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+       {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+
+static struct pci_driver nsc_pci_driver = {
+       .name = "tpm_nsc",
+       .id_table = tpm_pci_tbl,
+       .probe = tpm_nsc_init,
+       .remove = __devexit_p(tpm_nsc_remove),
+       .suspend = tpm_pm_suspend,
+       .resume = tpm_pm_resume,
+};
+
+static int __init init_nsc(void)
+{
+       return pci_register_driver(&nsc_pci_driver);
+}
+
+static void __exit cleanup_nsc(void)
+{
+       pci_unregister_driver(&nsc_pci_driver);
+}
+
+fs_initcall(init_nsc);
+module_exit(cleanup_nsc);
+
+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h        Sat Oct 
 8 20:28:24 2005
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * evtchn.h
+ * 
+ * Interface to /dev/xen/evtchn.
+ * 
+ * Copyright (c) 2003-2005, K A Fraser
+ * 
+ * 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 __LINUX_PUBLIC_EVTCHN_H__
+#define __LINUX_PUBLIC_EVTCHN_H__
+
+/* /dev/xen/evtchn resides at device number major=10, minor=201 */
+#define EVTCHN_MINOR 201
+
+/*
+ * Bind a fresh port to VIRQ @virq.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_VIRQ                         \
+       _IOC(_IOC_NONE, 'E', 0, sizeof(struct ioctl_evtchn_bind_virq))
+struct ioctl_evtchn_bind_virq {
+       unsigned int virq;
+};
+
+/*
+ * Bind a fresh port to remote <@remote_domain, @remote_port>.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_INTERDOMAIN                  \
+       _IOC(_IOC_NONE, 'E', 1, sizeof(struct ioctl_evtchn_bind_interdomain))
+struct ioctl_evtchn_bind_interdomain {
+       unsigned int remote_domain, remote_port;
+};
+
+/*
+ * Allocate a fresh port for binding to @remote_domain.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_UNBOUND_PORT                 \
+       _IOC(_IOC_NONE, 'E', 2, sizeof(struct ioctl_evtchn_bind_unbound_port))
+struct ioctl_evtchn_bind_unbound_port {
+       unsigned int remote_domain;
+};
+
+/*
+ * Unbind previously allocated @port.
+ */
+#define IOCTL_EVTCHN_UNBIND                            \
+       _IOC(_IOC_NONE, 'E', 3, sizeof(struct ioctl_evtchn_unbind))
+struct ioctl_evtchn_unbind {
+       unsigned int port;
+};
+
+/*
+ * Unbind previously allocated @port.
+ */
+#define IOCTL_EVTCHN_NOTIFY                            \
+       _IOC(_IOC_NONE, 'E', 4, sizeof(struct ioctl_evtchn_notify))
+struct ioctl_evtchn_notify {
+       unsigned int port;
+};
+
+/* Clear and reinitialise the event buffer. Clear error condition. */
+#define IOCTL_EVTCHN_RESET                             \
+       _IOC(_IOC_NONE, 'E', 5, 0)
+
+#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/block
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/tools/examples/block      Sat Oct  8 20:28:24 2005
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+set -e
+
+export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH
+
+expand_dev() {
+  local dev
+  case $1 in
+  /*)
+    dev=$1
+    ;;
+  *)
+    dev=/dev/$1
+    ;;
+  esac
+  echo -n $dev
+}
+
+write_dev() {
+  local major
+  local minor
+  local pdev
+       
+  major=$(stat -L -c %t "$1")
+  minor=$(stat -L -c %T "$1")
+  pdev=$(printf "0x%02x%02x" 0x$major 0x$minor)
+  xenstore-write "$XENBUS_PATH"/physical-device $pdev \
+      "$XENBUS_PATH"/node $1
+}
+
+t=$(xenstore-read "$XENBUS_PATH"/type)
+
+case $1 in 
+  bind)
+    p=$(xenstore-read "$XENBUS_PATH"/params)
+    case $t in 
+      phy)
+        dev=$(expand_dev $p)
+       write_dev "$dev"
+       exit 0
+       ;;
+
+      file)
+       for dev in /dev/loop* ; do
+         echo "dev is $dev, p is $p"
+         if losetup $dev $p; then
+           write_dev "$dev"
+            exit 0
+         fi
+       done
+       exit 1
+       ;;
+
+      *)
+        [ -x /etc/xen/scripts/block-"$t" ] && \
+           /etc/xen/scripts/block-"$t" bind $p
+       ;;
+    esac
+    ;;
+
+  unbind)
+    node=$(xenstore-read "$XENBUS_PATH"/node)
+    case $t in 
+      phy)
+       exit 0
+       ;;
+
+      file)
+       losetup -d $node
+       exit 0
+       ;;
+
+      *)
+        [ -x /etc/xen/scripts/block-"$t" ] && \
+           /etc/xen/scripts/block-"$t" unbind $node
+       ;;
+
+    esac
+    ;;
+
+esac
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/examples/xen-backend.rules
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/tools/examples/xen-backend.rules  Sat Oct  8 20:28:24 2005
@@ -0,0 +1,4 @@
+SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="add", 
RUN+="/etc/xen/scripts/block bind"
+SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="remove", 
RUN+="/etc/xen/scripts/block unbind"
+SUBSYSTEM=="xen-backend", KERNEL=="vif*", ENV{PHYSDEVDRIVER}=="vif", 
ACTION=="online", RUN+="$env{script} up"
+SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm 
$env{XENBUS_PATH}"
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/README
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/tools/python/README       Sat Oct  8 20:28:24 2005
@@ -0,0 +1,3 @@
+The file test.py here is from the Zope project, and is Copyright (c) 2001,
+2002 Zope Corporation and Contributors.  This file is released under the Zope
+Public License, version 2.0, a copy of which is in the file ZPL-2.0.
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/ZPL-2.0
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/tools/python/ZPL-2.0      Sat Oct  8 20:28:24 2005
@@ -0,0 +1,59 @@
+Zope Public License (ZPL) Version 2.0
+-----------------------------------------------
+
+This software is Copyright (c) Zope Corporation (tm) and
+Contributors. All rights reserved.
+
+This license has been certified as open source. It has also
+been designated as GPL compatible by the Free Software
+Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions in source code must retain the above
+   copyright notice, this list of conditions, and the following
+   disclaimer.
+
+2. 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.
+
+3. The name Zope Corporation (tm) must not be used to
+   endorse or promote products derived from this software
+   without prior written permission from Zope Corporation.
+
+4. The right to distribute this software or to use it for
+   any purpose does not give you the right to use Servicemarks
+   (sm) or Trademarks (tm) of Zope Corporation. Use of them is
+   covered in a separate agreement (see
+   http://www.zope.com/Marks).
+
+5. If any files are modified, you must cause the modified
+   files to carry prominent notices stating that you changed
+   the files and the date of any change.
+
+Disclaimer
+
+  THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS''
+  AND ANY EXPRESSED 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 ZOPE CORPORATION OR ITS 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.
+
+
+This software consists of contributions made by Zope
+Corporation and many individuals on behalf of Zope
+Corporation.  Specific attributions are listed in the
+accompanying credits file.
\ No newline at end of file
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/test.py
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/tools/python/test.py      Sat Oct  8 20:28:24 2005
@@ -0,0 +1,1094 @@
+#! /usr/bin/env python2.3
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+test.py [-abBcdDfFgGhklLmMPprstTuUv] [modfilter [testfilter]]
+
+Find and run tests written using the unittest module.
+
+The test runner searches for Python modules that contain test suites.
+It collects those suites, and runs the tests.  There are many options
+for controlling how the tests are run.  There are options for using
+the debugger, reporting code coverage, and checking for refcount problems.
+
+The test runner uses the following rules for finding tests to run.  It
+searches for packages and modules that contain "tests" as a component
+of the name, e.g. "frob.tests.nitz" matches this rule because tests is
+a sub-package of frob.  Within each "tests" package, it looks for
+modules that begin with the name "test."  For each test module, it
+imports the module and calls the module's test_suite() function, which must
+return a unittest TestSuite object.
+
+Options can be specified as command line arguments (see below). However,
+options may also be specified in a file named 'test.config', a Python
+script which, if found, will be executed before the command line
+arguments are processed.
+
+The test.config script should specify options by setting zero or more of the
+global variables: LEVEL, BUILD, and other capitalized variable names found in
+the test runner script (see the list of global variables in process_args().).
+
+
+-a level
+--at-level level
+--all
+    Run the tests at the given level.  Any test at a level at or below
+    this is run, any test at a level above this is not run.  Level 0
+    runs all tests.  The default is to run tests at level 1.  --all is
+    a shortcut for -a 0.
+
+-b
+--build
+    Run "python setup.py build" before running tests, where "python"
+    is the version of python used to run test.py.  Highly recommended.
+    Tests will be run from the build directory.
+
+-B
+--build-inplace
+    Run "python setup.py build_ext -i" before running tests.  Tests will be
+    run from the source directory.
+
+-c
+--pychecker
+    use pychecker
+
+-d
+--debug
+    Instead of the normal test harness, run a debug version which
+    doesn't catch any exceptions.  This is occasionally handy when the
+    unittest code catching the exception doesn't work right.
+    Unfortunately, the debug harness doesn't print the name of the
+    test, so Use With Care.
+
+-D
+--debug-inplace
+    Works like -d, except that it loads pdb when an exception occurs.
+
+--dir directory
+-s directory
+    Option to limit where tests are searched for. This is important
+    when you *really* want to limit the code that gets run.  This can
+    be specified more than once to run tests in two different parts of
+    the source tree.
+    For example, if refactoring interfaces, you don't want to see the way
+    you have broken setups for tests in other packages. You *just* want to
+    run the interface tests.
+
+-f
+--skip-unit
+    Run functional tests but not unit tests.
+    Note that functional tests will be skipped if the module
+    zope.app.tests.functional cannot be imported.
+    Functional tests also expect to find the file ftesting.zcml,
+    which is used to configure the functional-test run.
+
+-F
+    DEPRECATED. Run both unit and functional tests.
+    This option is deprecated, because this is the new default mode.
+    Note that functional tests will be skipped if the module
+    zope.app.tests.functional cannot be imported.
+
+-g threshold
+--gc-threshold threshold
+    Set the garbage collector generation0 threshold.  This can be used
+    to stress memory and gc correctness.  Some crashes are only
+    reproducible when the threshold is set to 1 (agressive garbage
+    collection).  Do "-g 0" to disable garbage collection altogether.
+
+-G gc_option
+--gc-option gc_option
+    Set the garbage collection debugging flags.  The argument must be one
+    of the DEBUG_ flags defined bythe Python gc module.  Multiple options
+    can be specified by using "-G OPTION1 -G OPTION2."
+
+-k
+--keepbytecode
+    Do not delete all stale bytecode before running tests
+
+-l test_root
+--libdir test_root
+    Search for tests starting in the specified start directory
+    (useful for testing components being developed outside the main
+    "src" or "build" trees).
+
+-L
+--loop
+    Keep running the selected tests in a loop.  You may experience
+    memory leakage.
+
+-m
+-M  minimal GUI. See -U.
+
+-P
+--profile
+    Run the tests under hotshot and display the top 50 stats, sorted by
+    cumulative time and number of calls.
+
+-p
+--progress
+    Show running progress.  It can be combined with -v or -vv.
+
+-r
+--refcount
+    Look for refcount problems.
+    This requires that Python was built --with-pydebug.
+
+-t
+--top-fifty
+    Time the individual tests and print a list of the top 50, sorted from
+    longest to shortest.
+
+--times n
+--times outfile
+    With an integer argument, time the tests and print a list of the top <n>
+    tests, sorted from longest to shortest.
+    With a non-integer argument, specifies a file to which timing information
+    is to be printed.
+
+-T
+--trace
+    Use the trace module from Python for code coverage.  The current
+    utility writes coverage files to a directory named `coverage' that
+    is parallel to `build'.  It also prints a summary to stdout.
+
+-u
+--skip-functional
+    CHANGED. Run unit tests but not functional tests.
+    Note that the meaning of -u is changed from its former meaning,
+    which is now specified by -U or --gui.
+
+-U
+--gui
+    Use the PyUnit GUI instead of output to the command line.  The GUI
+    imports tests on its own, taking care to reload all dependencies
+    on each run.  The debug (-d), verbose (-v), progress (-p), and
+    Loop (-L) options will be ignored.  The testfilter filter is also
+    not applied.
+
+-m
+-M
+--minimal-gui
+    Note: -m is DEPRECATED in favour of -M or --minimal-gui.
+    -m starts the gui minimized.  Double-clicking the progress bar
+    will start the import and run all tests.
+
+
+-v
+--verbose
+    Verbose output.  With one -v, unittest prints a dot (".") for each
+    test run.  With -vv, unittest prints the name of each test (for
+    some definition of "name" ...).  With no -v, unittest is silent
+    until the end of the run, except when errors occur.
+
+    When -p is also specified, the meaning of -v is slightly
+    different.  With -p and no -v only the percent indicator is
+    displayed.  With -p and -v the test name of the current test is
+    shown to the right of the percent indicator.  With -p and -vv the
+    test name is not truncated to fit into 80 columns and it is not
+    cleared after the test finishes.
+
+
+modfilter
+testfilter
+    Case-sensitive regexps to limit which tests are run, used in search
+    (not match) mode.
+    In an extension of Python regexp notation, a leading "!" is stripped
+    and causes the sense of the remaining regexp to be negated (so "!bc"
+    matches any string that does not match "bc", and vice versa).
+    By default these act like ".", i.e. nothing is excluded.
+
+    modfilter is applied to a test file's path, starting at "build" and
+    including (OS-dependent) path separators.
+
+    testfilter is applied to the (method) name of the unittest methods
+    contained in the test files whose paths modfilter matched.
+
+Extreme (yet useful) examples:
+
+    test.py -vvb . "^testWriteClient$"
+
+    Builds the project silently, then runs unittest in verbose mode on all
+    tests whose names are precisely "testWriteClient".  Useful when
+    debugging a specific test.
+
+    test.py -vvb . "!^testWriteClient$"
+
+    As before, but runs all tests whose names aren't precisely
+    "testWriteClient".  Useful to avoid a specific failing test you don't
+    want to deal with just yet.
+
+    test.py -M . "!^testWriteClient$"
+
+    As before, but now opens up a minimized PyUnit GUI window (only showing
+    the progress bar).  Useful for refactoring runs where you continually want
+    to make sure all tests still pass.
+"""
+
+import gc
+import hotshot, hotshot.stats
+import os
+import re
+import pdb
+import sys
+import threading    # just to get at Thread objects created by tests
+import time
+import traceback
+import unittest
+import warnings
+
+def set_trace_doctest(stdin=sys.stdin, stdout=sys.stdout, trace=pdb.set_trace):
+    sys.stdin = stdin
+    sys.stdout = stdout
+    trace()
+
+pdb.set_trace_doctest = set_trace_doctest
+
+from distutils.util import get_platform
+
+PLAT_SPEC = "%s-%s" % (get_platform(), sys.version[0:3])
+
+class ImmediateTestResult(unittest._TextTestResult):
+
+    __super_init = unittest._TextTestResult.__init__
+    __super_startTest = unittest._TextTestResult.startTest
+    __super_printErrors = unittest._TextTestResult.printErrors
+
+    def __init__(self, stream, descriptions, verbosity, debug=False,
+                 count=None, progress=False):
+        self.__super_init(stream, descriptions, verbosity)
+        self._debug = debug
+        self._progress = progress
+        self._progressWithNames = False
+        self.count = count
+        self._testtimes = {}
+        if progress and verbosity == 1:
+            self.dots = False
+            self._progressWithNames = True
+            self._lastWidth = 0
+            self._maxWidth = 80
+            try:
+                import curses
+            except ImportError:
+                pass
+            else:
+                curses.setupterm()
+                self._maxWidth = curses.tigetnum('cols')
+            self._maxWidth -= len("xxxx/xxxx (xxx.x%): ") + 1
+
+    def stopTest(self, test):
+        self._testtimes[test] = time.time() - self._testtimes[test]
+        if gc.garbage:
+            print "The following test left garbage:"
+            print test
+            print gc.garbage
+            # XXX Perhaps eat the garbage here, so that the garbage isn't
+            #     printed for every subsequent test.
+
+        # Did the test leave any new threads behind?
+        new_threads = [t for t in threading.enumerate()
+                         if (t.isAlive()
+                             and
+                             t not in self._threads)]
+        if new_threads:
+            print "The following test left new threads behind:"
+            print test
+            print "New thread(s):", new_threads
+
+    def print_times(self, stream, count=None):
+        results = self._testtimes.items()
+        results.sort(lambda x, y: cmp(y[1], x[1]))
+        if count:
+            n = min(count, len(results))
+            if n:
+                print >>stream, "Top %d longest tests:" % n
+        else:
+            n = len(results)
+        if not n:
+            return
+        for i in range(n):
+            print >>stream, "%6dms" % int(results[i][1] * 1000), results[i][0]
+
+    def _print_traceback(self, msg, err, test, errlist):
+        if self.showAll or self.dots or self._progress:
+            self.stream.writeln("\n")
+            self._lastWidth = 0
+
+        tb = "".join(traceback.format_exception(*err))
+        self.stream.writeln(msg)
+        self.stream.writeln(tb)
+        errlist.append((test, tb))
+
+    def startTest(self, test):
+        if self._progress:
+            self.stream.write("\r%4d" % (self.testsRun + 1))
+            if self.count:
+                self.stream.write("/%d (%5.1f%%)" % (self.count,
+                                  (self.testsRun + 1) * 100.0 / self.count))
+            if self.showAll:
+                self.stream.write(": ")
+            elif self._progressWithNames:
+                # XXX will break with multibyte strings
+                name = self.getShortDescription(test)
+                width = len(name)
+                if width < self._lastWidth:
+                    name += " " * (self._lastWidth - width)
+                self.stream.write(": %s" % name)
+                self._lastWidth = width
+            self.stream.flush()
+        self._threads = threading.enumerate()
+        self.__super_startTest(test)
+        self._testtimes[test] = time.time()
+
+    def getShortDescription(self, test):
+        s = self.getDescription(test)
+        if len(s) > self._maxWidth:
+            pos = s.find(" (")
+            if pos >= 0:
+                w = self._maxWidth - (pos + 5)
+                if w < 1:
+                    # first portion (test method name) is too long
+                    s = s[:self._maxWidth-3] + "..."
+                else:
+                    pre = s[:pos+2]
+                    post = s[-w:]
+                    s = "%s...%s" % (pre, post)
+        return s[:self._maxWidth]
+
+    def addError(self, test, err):
+        if self._progress:
+            self.stream.write("\r")
+        if self._debug:
+            raise err[0], err[1], err[2]
+        self._print_traceback("Error in test %s" % test, err,
+                              test, self.errors)
+
+    def addFailure(self, test, err):
+        if self._progress:
+            self.stream.write("\r")
+        if self._debug:
+            raise err[0], err[1], err[2]
+        self._print_traceback("Failure in test %s" % test, err,
+                              test, self.failures)
+
+    def printErrors(self):
+        if self._progress and not (self.dots or self.showAll):
+            self.stream.writeln()
+        self.__super_printErrors()
+
+    def printErrorList(self, flavor, errors):
+        for test, err in errors:
+            self.stream.writeln(self.separator1)
+            self.stream.writeln("%s: %s" % (flavor, self.getDescription(test)))
+            self.stream.writeln(self.separator2)
+            self.stream.writeln(err)
+
+
+class ImmediateTestRunner(unittest.TextTestRunner):
+
+    __super_init = unittest.TextTestRunner.__init__
+
+    def __init__(self, **kwarg):
+        debug = kwarg.get("debug")
+        if debug is not None:
+            del kwarg["debug"]
+        progress = kwarg.get("progress")
+        if progress is not None:
+            del kwarg["progress"]
+        profile = kwarg.get("profile")
+        if profile is not None:
+            del kwarg["profile"]
+        self.__super_init(**kwarg)
+        self._debug = debug
+        self._progress = progress
+        self._profile = profile
+        # Create the test result here, so that we can add errors if
+        # the test suite search process has problems.  The count
+        # attribute must be set in run(), because we won't know the
+        # count until all test suites have been found.
+        self.result = ImmediateTestResult(
+            self.stream, self.descriptions, self.verbosity, debug=self._debug,
+            progress=self._progress)
+
+    def _makeResult(self):
+        # Needed base class run method.
+        return self.result
+
+    def run(self, test):
+        self.result.count = test.countTestCases()
+        if self._debug:
+            club_debug(test)
+        if self._profile:
+            prof = hotshot.Profile("tests_profile.prof")
+            args = (self, test)
+            r = prof.runcall(unittest.TextTestRunner.run, *args)
+            prof.close()
+            stats = hotshot.stats.load("tests_profile.prof")
+            stats.sort_stats('cumulative', 'calls')
+            stats.print_stats(50)
+            return r
+        return unittest.TextTestRunner.run(self, test)
+
+def club_debug(test):
+    # Beat a debug flag into debug-aware test cases
+    setDebugModeOn = getattr(test, 'setDebugModeOn', None)
+    if setDebugModeOn is not None:
+        setDebugModeOn()
+
+    for subtest in getattr(test, '_tests', ()):
+        club_debug(subtest)
+
+# setup list of directories to put on the path
+class PathInit:
+    def __init__(self, build, build_inplace, libdir=None):
+        self.inplace = None
+        # Figure out if we should test in-place or test in-build.  If the -b
+        # or -B option was given, test in the place we were told to build in.
+        # Otherwise, we'll look for a build directory and if we find one,
+        # we'll test there, otherwise we'll test in-place.
+        if build:
+            self.inplace = build_inplace
+        if self.inplace is None:
+            # Need to figure it out
+            if os.path.isdir(os.path.join("build", "lib.%s" % PLAT_SPEC)):
+                self.inplace = False
+            else:
+                self.inplace = True
+        # Calculate which directories we're going to add to sys.path, and cd
+        # to the appropriate working directory
+        self.org_cwd = os.getcwd()
+        if self.inplace:
+            self.libdir = "src"
+        else:
+            self.libdir = "lib.%s" % PLAT_SPEC
+            os.chdir("build")
+        # Hack sys.path
+        self.cwd = os.getcwd()
+        sys.path.insert(0, os.path.join(self.cwd, self.libdir))
+        # Hack again for external products.
+        global functional
+        kind = functional and "FUNCTIONAL" or "UNIT"
+        if libdir:
+            extra = os.path.join(self.org_cwd, libdir)
+            print "Running %s tests from %s" % (kind, extra)
+            self.libdir = extra
+            sys.path.insert(0, extra)
+        else:
+            print "Running %s tests from %s" % (kind, self.cwd)
+        # Make sure functional tests find ftesting.zcml
+        if functional:
+            config_file = 'ftesting.zcml'
+            if not self.inplace:
+                # We chdired into build, so ftesting.zcml is in the
+                # parent directory
+                config_file = os.path.join('..', 'ftesting.zcml')
+            print "Parsing %s" % config_file
+            from zope.app.tests.functional import FunctionalTestSetup
+            FunctionalTestSetup(config_file)
+
+def match(rx, s):
+    if not rx:
+        return True
+    if rx[0] == "!":
+        return re.search(rx[1:], s) is None
+    else:
+        return re.search(rx, s) is not None
+
+class TestFileFinder:
+    def __init__(self, prefix):
+        self.files = []
+        self._plen = len(prefix)
+        if not prefix.endswith(os.sep):
+            self._plen += 1
+        global functional
+        if functional:
+            self.dirname = "ftests"
+        else:
+            self.dirname = "tests"
+
+    def visit(self, rx, dir, files):
+        if os.path.split(dir)[1] != self.dirname:
+            # Allow tests/ftests module rather than package.
+            modfname = self.dirname + '.py'
+            if modfname in files:
+                path = os.path.join(dir, modfname)
+                if match(rx, path):
+                    self.files.append(path)
+                    return
+            return
+        # ignore tests that aren't in packages
+        if not "__init__.py" in files:
+            if not files or files == ["CVS"]:
+                return
+            print "not a package", dir
+            return
+
+        # Put matching files in matches.  If matches is non-empty,
+        # then make sure that the package is importable.
+        matches = []
+        for file in files:
+            if file.startswith('test') and os.path.splitext(file)[-1] == '.py':
+                path = os.path.join(dir, file)
+                if match(rx, path):
+                    matches.append(path)
+
+        # ignore tests when the package can't be imported, possibly due to
+        # dependency failures.
+        pkg = dir[self._plen:].replace(os.sep, '.')
+        try:
+            __import__(pkg)
+        # We specifically do not want to catch ImportError since that's useful
+        # information to know when running the tests.
+        except RuntimeError, e:
+            if VERBOSE:
+                print "skipping %s because: %s" % (pkg, e)
+            return
+        else:
+            self.files.extend(matches)
+
+    def module_from_path(self, path):
+        """Return the Python package name indicated by the filesystem path."""
+        assert path.endswith(".py")
+        path = path[self._plen:-3]
+        mod = path.replace(os.sep, ".")
+        return mod
+
+def walk_with_symlinks(top, func, arg):
+    """Like os.path.walk, but follows symlinks on POSIX systems.
+
+    This could theoreticaly result in an infinite loop, if you create symlink
+    cycles in your Zope sandbox, so don't do that.
+    """
+    try:
+        names = os.listdir(top)
+    except os.error:
+        return
+    func(arg, top, names)
+    exceptions = ('.', '..')
+    for name in names:
+        if name not in exceptions:
+            name = os.path.join(top, name)
+            if os.path.isdir(name):
+                walk_with_symlinks(name, func, arg)
+
+def find_test_dir(dir):
+    if os.path.exists(dir):
+        return dir
+    d = os.path.join(pathinit.libdir, dir)
+    if os.path.exists(d):
+        if os.path.isdir(d):
+            return d
+        raise ValueError("%s does not exist and %s is not a directory"
+                         % (dir, d))
+    raise ValueError("%s does not exist!" % dir)
+
+def find_tests(rx):
+    global finder
+    finder = TestFileFinder(pathinit.libdir)
+
+    if TEST_DIRS:
+        for d in TEST_DIRS:
+            d = find_test_dir(d)
+            walk_with_symlinks(d, finder.visit, rx)
+    else:
+        walk_with_symlinks(pathinit.libdir, finder.visit, rx)
+    return finder.files
+
+def package_import(modname):
+    mod = __import__(modname)
+    for part in modname.split(".")[1:]:
+        mod = getattr(mod, part)
+    return mod
+
+class PseudoTestCase:
+    """Minimal test case objects to create error reports.
+
+    If test.py finds something that looks like it should be a test but
+    can't load it or find its test suite, it will report an error
+    using a PseudoTestCase.
+    """
+
+    def __init__(self, name, descr=None):
+        self.name = name
+        self.descr = descr
+
+    def shortDescription(self):
+        return self.descr
+
+    def __str__(self):
+        return "Invalid Test (%s)" % self.name
+
+def get_suite(file, result):
+    modname = finder.module_from_path(file)
+    try:
+        mod = package_import(modname)
+        return mod.test_suite()
+    except:
+        result.addError(PseudoTestCase(modname), sys.exc_info())
+        return None
+
+def filter_testcases(s, rx):
+    new = unittest.TestSuite()
+    for test in s._tests:
+        # See if the levels match
+        dolevel = (LEVEL == 0) or LEVEL >= getattr(test, "level", 0)
+        if not dolevel:
+            continue
+        if isinstance(test, unittest.TestCase):
+            name = test.id() # Full test name: package.module.class.method
+            name = name[1 + name.rfind("."):] # extract method name
+            if not rx or match(rx, name):
+                new.addTest(test)
+        else:
+            filtered = filter_testcases(test, rx)
+            if filtered:
+                new.addTest(filtered)
+    return new
+
+def gui_runner(files, test_filter):
+    if BUILD_INPLACE:
+        utildir = os.path.join(os.getcwd(), "utilities")
+    else:
+        utildir = os.path.join(os.getcwd(), "..", "utilities")
+    sys.path.append(utildir)
+    import unittestgui
+    suites = []
+    for file in files:
+        suites.append(finder.module_from_path(file) + ".test_suite")
+
+    suites = ", ".join(suites)
+    minimal = (GUI == "minimal")
+    unittestgui.main(suites, minimal)
+
+class TrackRefs:
+    """Object to track reference counts across test runs."""
+
+    def __init__(self):
+        self.type2count = {}
+        self.type2all = {}
+
+    def update(self):
+        obs = sys.getobjects(0)
+        type2count = {}
+        type2all = {}
+        for o in obs:
+            all = sys.getrefcount(o)
+
+            if type(o) is str and o == '<dummy key>':
+                # avoid dictionary madness
+                continue
+            t = type(o)
+            if t in type2count:
+                type2count[t] += 1
+                type2all[t] += all
+            else:
+                type2count[t] = 1
+                type2all[t] = all
+
+        ct = [(type2count[t] - self.type2count.get(t, 0),
+               type2all[t] - self.type2all.get(t, 0),
+               t)
+              for t in type2count.iterkeys()]
+        ct.sort()
+        ct.reverse()
+        printed = False
+        for delta1, delta2, t in ct:
+            if delta1 or delta2:
+                if not printed:
+                    print "%-55s %8s %8s" % ('', 'insts', 'refs')
+                    printed = True
+                print "%-55s %8d %8d" % (t, delta1, delta2)
+
+        self.type2count = type2count
+        self.type2all = type2all
+
+def runner(files, test_filter, debug):
+    runner = ImmediateTestRunner(verbosity=VERBOSE, debug=DEBUG,
+                                 progress=PROGRESS, profile=PROFILE,
+                                 descriptions=False)
+    suite = unittest.TestSuite()
+    for file in files:
+        s = get_suite(file, runner.result)
+        # See if the levels match
+        dolevel = (LEVEL == 0) or LEVEL >= getattr(s, "level", 0)
+        if s is not None and dolevel:
+            s = filter_testcases(s, test_filter)
+            suite.addTest(s)
+    try:
+        r = runner.run(suite)
+        if TIMESFN:
+            r.print_times(open(TIMESFN, "w"))
+            if VERBOSE:
+                print "Wrote timing data to", TIMESFN
+        if TIMETESTS:
+            r.print_times(sys.stdout, TIMETESTS)
+    except:
+        if DEBUGGER:
+            print "%s:" % (sys.exc_info()[0], )
+            print sys.exc_info()[1]
+            pdb.post_mortem(sys.exc_info()[2])
+        else:
+            raise
+
+def remove_stale_bytecode(arg, dirname, names):
+    names = map(os.path.normcase, names)
+    for name in names:
+        if name.endswith(".pyc") or name.endswith(".pyo"):
+            srcname = name[:-1]
+            if srcname not in names:
+                fullname = os.path.join(dirname, name)
+                print "Removing stale bytecode file", fullname
+                os.unlink(fullname)
+
+def main(module_filter, test_filter, libdir):
+    if not KEEP_STALE_BYTECODE:
+        os.path.walk(os.curdir, remove_stale_bytecode, None)
+
+    configure_logging()
+
+    # Initialize the path and cwd
+    global pathinit
+    pathinit = PathInit(BUILD, BUILD_INPLACE, libdir)
+
+    files = find_tests(module_filter)
+    files.sort()
+
+    if GUI:
+        gui_runner(files, test_filter)
+    elif LOOP:
+        if REFCOUNT:
+            rc = sys.gettotalrefcount()
+            track = TrackRefs()
+        while True:
+            runner(files, test_filter, DEBUG)
+            gc.collect()
+            if gc.garbage:
+                print "GARBAGE:", len(gc.garbage), gc.garbage
+                return
+            if REFCOUNT:
+                prev = rc
+                rc = sys.gettotalrefcount()
+                print "totalrefcount=%-8d change=%-6d" % (rc, rc - prev)
+                track.update()
+    else:
+        runner(files, test_filter, DEBUG)
+
+    os.chdir(pathinit.org_cwd)
+
+
+def configure_logging():
+    """Initialize the logging module."""
+    import logging.config
+
+    # Get the log.ini file from the current directory instead of possibly
+    # buried in the build directory.  XXX This isn't perfect because if
+    # log.ini specifies a log file, it'll be relative to the build directory.
+    # Hmm...
+    logini = os.path.abspath("log.ini")
+
+    if os.path.exists(logini):
+        logging.config.fileConfig(logini)
+    else:
+        logging.basicConfig()
+
+    if os.environ.has_key("LOGGING"):
+        level = int(os.environ["LOGGING"])
+        logging.getLogger().setLevel(level)
+
+
+def process_args(argv=None):
+    import getopt
+    global MODULE_FILTER
+    global TEST_FILTER
+    global VERBOSE
+    global LOOP
+    global GUI
+    global TRACE
+    global REFCOUNT
+    global DEBUG
+    global DEBUGGER
+    global BUILD
+    global LEVEL
+    global LIBDIR
+    global TIMESFN
+    global TIMETESTS
+    global PROGRESS
+    global BUILD_INPLACE
+    global KEEP_STALE_BYTECODE
+    global TEST_DIRS
+    global PROFILE
+    global GC_THRESHOLD
+    global GC_FLAGS
+    global RUN_UNIT
+    global RUN_FUNCTIONAL
+    global PYCHECKER
+
+    if argv is None:
+        argv = sys.argv
+
+    MODULE_FILTER = None
+    TEST_FILTER = None
+    VERBOSE = 0
+    LOOP = False
+    GUI = False
+    TRACE = False
+    REFCOUNT = False
+    DEBUG = False # Don't collect test results; simply let tests crash
+    DEBUGGER = False
+    BUILD = False
+    BUILD_INPLACE = False
+    GC_THRESHOLD = None
+    gcdebug = 0
+    GC_FLAGS = []
+    LEVEL = 1
+    LIBDIR = None
+    PROGRESS = False
+    TIMESFN = None
+    TIMETESTS = 0
+    KEEP_STALE_BYTECODE = 0
+    RUN_UNIT = True
+    RUN_FUNCTIONAL = True
+    TEST_DIRS = []
+    PROFILE = False
+    PYCHECKER = False
+    config_filename = 'test.config'
+
+    # import the config file
+    if os.path.isfile(config_filename):
+        print 'Configuration file found.'
+        execfile(config_filename, globals())
+
+
+    try:
+        opts, args = getopt.getopt(argv[1:], "a:bBcdDfFg:G:hkl:LmMPprs:tTuUv",
+                                   ["all", "help", "libdir=", "times=",
+                                    "keepbytecode", "dir=", "build",
+                                    "build-inplace",
+                                    "at-level=",
+                                    "pychecker", "debug", "pdebug",
+                                    "gc-threshold=", "gc-option=",
+                                    "loop", "gui", "minimal-gui",
+                                    "profile", "progress", "refcount", "trace",
+                                    "top-fifty", "verbose",
+                                    ])
+    # fixme: add the long names
+    # fixme: add the extra documentation
+    # fixme: test for functional first!
+    except getopt.error, msg:
+        print msg
+        print "Try `python %s -h' for more information." % argv[0]
+        sys.exit(2)
+
+    for k, v in opts:
+        if k in ("-a", "--at-level"):
+            LEVEL = int(v)
+        elif k == "--all":
+            LEVEL = 0
+            os.environ["COMPLAIN_IF_TESTS_MISSED"]='1'
+        elif k in ("-b", "--build"):
+            BUILD = True
+        elif k in ("-B", "--build-inplace"):
+            BUILD = BUILD_INPLACE = True
+        elif k in("-c", "--pychecker"):
+            PYCHECKER = True
+        elif k in ("-d", "--debug"):
+            DEBUG = True
+        elif k in ("-D", "--pdebug"):
+            DEBUG = True
+            DEBUGGER = True
+        elif k in ("-f", "--skip-unit"):
+            RUN_UNIT = False
+        elif k in ("-u", "--skip-functional"):
+            RUN_FUNCTIONAL = False
+        elif k == "-F":
+            message = 'Unit plus functional is the default behaviour.'
+            warnings.warn(message, DeprecationWarning)
+            RUN_UNIT = True
+            RUN_FUNCTIONAL = True
+        elif k in ("-h", "--help"):
+            print __doc__
+            sys.exit(0)
+        elif k in ("-g", "--gc-threshold"):
+            GC_THRESHOLD = int(v)
+        elif k in ("-G", "--gc-option"):
+            if not v.startswith("DEBUG_"):
+                print "-G argument must be DEBUG_ flag, not", repr(v)
+                sys.exit(1)
+            GC_FLAGS.append(v)
+        elif k in ('-k', '--keepbytecode'):
+            KEEP_STALE_BYTECODE = 1
+        elif k in ('-l', '--libdir'):
+            LIBDIR = v
+        elif k in ("-L", "--loop"):
+            LOOP = 1
+        elif k == "-m":
+            GUI = "minimal"
+            msg = "Use -M or --minimal-gui instead of -m."
+            warnings.warn(msg, DeprecationWarning)
+        elif k in ("-M", "--minimal-gui"):
+            GUI = "minimal"
+        elif k in ("-P", "--profile"):
+            PROFILE = True
+        elif k in ("-p", "--progress"):
+            PROGRESS = True
+        elif k in ("-r", "--refcount"):
+                REFCOUNT = True
+        elif k in ("-T", "--trace"):
+            TRACE = True
+        elif k in ("-t", "--top-fifty"):
+            if not TIMETESTS:
+                TIMETESTS = 50
+        elif k in ("-u", "--gui"):
+            GUI = 1
+        elif k in ("-v", "--verbose"):
+            VERBOSE += 1
+        elif k == "--times":
+            try:
+                TIMETESTS = int(v)
+            except ValueError:
+                # must be a filename to write
+                TIMESFN = v
+        elif k in ('-s', '--dir'):
+            TEST_DIRS.append(v)
+
+    if PYCHECKER:
+        # make sure you have a recent version of pychecker
+        if not os.environ.get("PYCHECKER"):
+            os.environ["PYCHECKER"] = "-q"
+        import pychecker.checker
+
+    if REFCOUNT and not hasattr(sys, "gettotalrefcount"):
+        print "-r ignored, because it needs a debug build of Python"
+        REFCOUNT = False
+
+    if sys.version_info < ( 2,3,2 ):
+        print """\
+        ERROR: Your python version is not supported by Zope3.
+        Zope3 needs Python 2.3.2 or greater. You are running:""" + sys.version
+        sys.exit(1)
+
+    if GC_THRESHOLD is not None:
+        if GC_THRESHOLD == 0:
+            gc.disable()
+            print "gc disabled"
+        else:
+            gc.set_threshold(GC_THRESHOLD)
+            print "gc threshold:", gc.get_threshold()
+
+    if GC_FLAGS:
+        val = 0
+        for flag in GC_FLAGS:
+            v = getattr(gc, flag, None)
+            if v is None:
+                print "Unknown gc flag", repr(flag)
+                print gc.set_debug.__doc__
+                sys.exit(1)
+            val |= v
+        gcdebug |= v
+
+    if gcdebug:
+        gc.set_debug(gcdebug)
+
+    if BUILD:
+        # Python 2.3 is more sane in its non -q output
+        if sys.hexversion >= 0x02030000:
+            qflag = ""
+        else:
+            qflag = "-q"
+        cmd = sys.executable + " setup.py " + qflag + " build"
+        if BUILD_INPLACE:
+            cmd += "_ext -i"
+        if VERBOSE:
+            print cmd
+        sts = os.system(cmd)
+        if sts:
+            print "Build failed", hex(sts)
+            sys.exit(1)
+
+    k = []
+    if RUN_UNIT:
+        k.append(False)
+    if RUN_FUNCTIONAL:
+        k.append(True)
+
+    global functional
+    for functional in k:
+
+        if VERBOSE:
+            kind = functional and "FUNCTIONAL" or "UNIT"
+            if LEVEL == 0:
+                print "Running %s tests at all levels" % kind
+            else:
+                print "Running %s tests at level %d" % (kind, LEVEL)
+
+# This was to avoid functional tests outside of z3, but this doesn't really
+# work right.
+##         if functional:
+##             try:
+##                 from zope.app.tests.functional import FunctionalTestSetup
+##             except ImportError:
+##                 raise
+##                 print ('Skipping functional tests: could not import '
+##                        'zope.app.tests.functional')
+##                 continue
+
+        # XXX We want to change *visible* warnings into errors.  The next
+        # line changes all warnings into errors, including warnings we
+        # normally never see.  In particular, test_datetime does some
+        # short-integer arithmetic that overflows to long ints, and, by
+        # default, Python doesn't display the overflow warning that can
+        # be enabled when this happens.  The next line turns that into an
+        # error instead.  Guido suggests that a better to get what we're
+        # after is to replace warnings.showwarning() with our own thing
+        # that raises an error.
+        ## warnings.filterwarnings("error")
+        warnings.filterwarnings("ignore", module="logging")
+
+        if args:
+            if len(args) > 1:
+                TEST_FILTER = args[1]
+            MODULE_FILTER = args[0]
+        try:
+            if TRACE:
+                # if the trace module is used, then we don't exit with
+                # status if on a false return value from main.
+                coverdir = os.path.join(os.getcwd(), "coverage")
+                import trace
+                ignoremods = ["os", "posixpath", "stat"]
+                tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
+                                     ignoremods=ignoremods,
+                                     trace=False, count=True)
+
+                tracer.runctx("main(MODULE_FILTER, TEST_FILTER, LIBDIR)",
+                              globals=globals(), locals=vars())
+                r = tracer.results()
+                path = "/tmp/trace.%s" % os.getpid()
+                import cPickle
+                f = open(path, "wb")
+                cPickle.dump(r, f)
+                f.close()
+                print path
+                r.write_results(show_missing=True,
+                                summary=True, coverdir=coverdir)
+            else:
+                bad = main(MODULE_FILTER, TEST_FILTER, LIBDIR)
+                if bad:
+                    sys.exit(1)
+        except ImportError, err:
+            print err
+            print sys.path
+            raise
+
+
+if __name__ == "__main__":
+    process_args()
diff -r 0ba10f7fef51 -r 4e0c94871be2 tools/python/xen/xend/tests/test_sxp.py
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/tools/python/xen/xend/tests/test_sxp.py   Sat Oct  8 20:28:24 2005
@@ -0,0 +1,18 @@
+import unittest
+
+import xen.xend.sxp
+
+
+class test_sxp(unittest.TestCase):
+
+    def testAllFromString(self):
+        def t(input, expected):
+            self.assertEqual(xen.xend.sxp.all_from_string(input), expected)
+
+        t('String',           ['String'])
+        t('(String Thing)',   [['String', 'Thing']])
+        t('(String) (Thing)', [['String'], ['Thing']])
+
+
+def test_suite():
+    return unittest.makeSuite(test_sxp)
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/public/io/xs_wire.h
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/xen/include/public/io/xs_wire.h   Sat Oct  8 20:28:24 2005
@@ -0,0 +1,95 @@
+/*
+ * Details of the "wire" protocol between Xen Store Daemon and client
+ * library or guest kernel.
+ * 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 _XS_WIRE_H
+#define _XS_WIRE_H
+
+enum xsd_sockmsg_type
+{
+       XS_DEBUG,
+       XS_DIRECTORY,
+       XS_READ,
+       XS_GET_PERMS,
+       XS_WATCH,
+       XS_WATCH_ACK,
+       XS_UNWATCH,
+       XS_TRANSACTION_START,
+       XS_TRANSACTION_END,
+       XS_OP_READ_ONLY = XS_TRANSACTION_END,
+       XS_INTRODUCE,
+       XS_RELEASE,
+       XS_GET_DOMAIN_PATH,
+       XS_WRITE,
+       XS_MKDIR,
+       XS_RM,
+       XS_SET_PERMS,
+       XS_WATCH_EVENT,
+       XS_ERROR,
+};
+
+#define XS_WRITE_NONE "NONE"
+#define XS_WRITE_CREATE "CREATE"
+#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"
+
+/* We hand errors as strings, for portability. */
+struct xsd_errors
+{
+       int errnum;
+       const char *errstring;
+};
+#define XSD_ERROR(x) { x, #x }
+static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
+       XSD_ERROR(EINVAL),
+       XSD_ERROR(EACCES),
+       XSD_ERROR(EEXIST),
+       XSD_ERROR(EISDIR),
+       XSD_ERROR(ENOENT),
+       XSD_ERROR(ENOMEM),
+       XSD_ERROR(ENOSPC),
+       XSD_ERROR(EIO),
+       XSD_ERROR(ENOTEMPTY),
+       XSD_ERROR(ENOSYS),
+       XSD_ERROR(EROFS),
+       XSD_ERROR(EBUSY),
+       XSD_ERROR(EAGAIN),
+       XSD_ERROR(EISCONN),
+};
+struct xsd_sockmsg
+{
+       u32 type;
+       u32 len;                /* Length of data following this. */
+
+       /* Generally followed by nul-terminated string(s). */
+};
+
+enum xs_watch_type
+{
+       XS_WATCH_PATH = 0,
+       XS_WATCH_TOKEN,
+};
+
+#endif /* _XS_WIRE_H */
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/public/sched.h
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/xen/include/public/sched.h        Sat Oct  8 20:28:24 2005
@@ -0,0 +1,50 @@
+/******************************************************************************
+ * sched.h
+ * 
+ * Scheduler state interactions
+ * 
+ * Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx>
+ */
+
+#ifndef __XEN_PUBLIC_SCHED_H__
+#define __XEN_PUBLIC_SCHED_H__
+
+/*
+ * Prototype for this hypercall is:
+ *  int sched_op(int cmd, unsigned long arg)
+ * @cmd == SCHEDOP_??? (scheduler operation).
+ * @arg == Operation-specific extra argument(s).
+ */
+
+/*
+ * Voluntarily yield the CPU.
+ * @arg == 0.
+ */
+#define SCHEDOP_yield       0
+
+/*
+ * Block execution of this VCPU until an event is received for processing.
+ * If called with event upcalls masked, this operation will atomically
+ * reenable event delivery and check for pending events before blocking the
+ * VCPU. This avoids a "wakeup waiting" race.
+ * @arg == 0.
+ */
+#define SCHEDOP_block       1
+
+/*
+ * Halt execution of this domain (all VCPUs) and notify the system controller.
+ * @arg == SHUTDOWN_??? (reason for shutdown).
+ */
+#define SCHEDOP_shutdown    2
+
+/*
+ * Reason codes for SCHEDOP_shutdown. These may be interpreted by controller
+ * software to determine the appropriate action. For the most part, Xen does
+ * not care about the shutdown code.
+ */
+#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
+#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
+#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
+#define SHUTDOWN_crash      3  /* Tell controller we've crashed.             */
+
+#endif /* __XEN_PUBLIC_SCHED_H__ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 xen/include/public/vcpu.h
--- /dev/null   Sat Oct  8 17:37:45 2005
+++ b/xen/include/public/vcpu.h Sat Oct  8 20:28:24 2005
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * vcpu.h
+ * 
+ * VCPU initialisation, query, and hotplug.
+ * 
+ * Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx>
+ */
+
+#ifndef __XEN_PUBLIC_VCPU_H__
+#define __XEN_PUBLIC_VCPU_H__
+
+/*
+ * Prototype for this hypercall is:
+ *  int vcpu_op(int cmd, int vcpuid, void *extra_args)
+ * @cmd        == VCPUOP_??? (VCPU operation).
+ * @vcpuid     == VCPU to operate on.
+ * @extra_args == Operation-specific extra arguments (NULL if none).
+ */
+
+/*
+ * Initialise a VCPU. Each VCPU can be initialised only once. A 
+ * newly-initialised VCPU will not run until it is brought up by VCPUOP_up.
+ * 
+ * @extra_arg == pointer to vcpu_guest_context structure containing initial
+ *               state for the VCPU.
+ */
+#define VCPUOP_initialise           0
+
+/*
+ * Bring up a VCPU. This makes the VCPU runnable. This operation will fail
+ * if the VCPU has not been initialised (VCPUOP_initialise).
+ */
+#define VCPUOP_up                   1
+
+/*
+ * Bring down a VCPU (i.e., make it non-runnable).
+ * There are a few caveats that callers should observe:
+ *  1. This operation may return, and VCPU_is_up may return false, before the
+ *     VCPU stops running (i.e., the command is asynchronous). It is a good
+ *     idea to ensure that the VCPU has entered a non-critical loop before
+ *     bringing it down. Alternatively, this operation is guaranteed
+ *     synchronous if invoked by the VCPU itself.
+ *  2. After a VCPU is initialised, there is currently no way to drop all its
+ *     references to domain memory. Even a VCPU that is down still holds
+ *     memory references via its pagetable base pointer and GDT. It is good
+ *     practise to move a VCPU onto an 'idle' or default page table, LDT and
+ *     GDT before bringing it down.
+ */
+#define VCPUOP_down                 2
+
+/* Returns 1 if the given VCPU is up. */
+#define VCPUOP_is_up                3
+
+#endif /* __XEN_PUBLIC_VCPU_H__ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 buildconfigs/mk.linux-2.4-xenU
--- a/buildconfigs/mk.linux-2.4-xenU    Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,51 +0,0 @@
-
-OS           = linux
-
-LINUX_SERIES = 2.4
-LINUX_VER    = 2.4.30
-
-EXTRAVERSION = xenU
-
-LINUX_DIR    = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
-
-include buildconfigs/Rules.mk
-
-.PHONY: build clean delete
-
-# The real action starts here!
-build: $(LINUX_DIR)/include/linux/autoconf.h
-       if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) 
INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \
-       fi
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) 
install
-
-$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
-       rm -rf $(LINUX_DIR)
-       cp -al $(<D) $(LINUX_DIR)
-       # Apply arch-xen patches
-       ( cd linux-$(LINUX_SERIES)-xen-sparse ; \
-          LINUX_ARCH=$(LINUX_ARCH) ./mkbuildtree ../$(LINUX_DIR) )
-       # Re-use config from install dir if one exits else use default config
-       CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p' 
$(LINUX_DIR)/Makefile); \
-       [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
-         cp 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) 
$(LINUX_DIR)/.config \
-         || cp $(LINUX_DIR)/arch/xen/defconfig-$(EXTRAVERSION) \
-               $(LINUX_DIR)/.config
-       # Patch kernel Makefile to set EXTRAVERSION
-       ( cd $(LINUX_DIR) ; \
-         sed -e 's/^EXTRAVERSION.*/&$$(XENGUEST)\nXENGUEST = 
-$(EXTRAVERSION)/' Makefile >Mk.tmp ; \
-         rm -f Makefile ; mv Mk.tmp Makefile )
-       make -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) oldconfig
-       make -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) dep
-
-config: CONFIGMODE = menuconfig
-config: $(LINUX_DIR)/include/linux/autoconf.h
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) $(CONFIGMODE)
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) dep
-
-clean::
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
-
-delete: 
-       rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR) 
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/Makefile
--- a/linux-2.4-xen-sparse/Makefile     Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,592 +0,0 @@
-VERSION = 2
-PATCHLEVEL = 4
-SUBLEVEL = 30
-EXTRAVERSION =
-
-KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-
-# SUBARCH always tells us the underlying machine architecture.
-# Unless overridden, by default ARCH is equivalent to SUBARCH.
-# This will be overriden for Xen and UML builds.
-SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e 
s/arm.*/arm/ -e s/sa110/arm/)
-ARCH ?= $(SUBARCH)
-
-## XXX The following hack can be discarded after users have adjusted to the
-## architectural name change 'xeno' -> 'xen'.
-ifeq ($(ARCH),xeno)
-  ARCH := xen
-endif
-
-KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
-
-CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
-         else if [ -x /bin/bash ]; then echo /bin/bash; \
-         else echo sh; fi ; fi)
-TOPDIR := $(shell /bin/pwd)
-
-HPATH          = $(TOPDIR)/include
-FINDHPATH      = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net 
$(HPATH)/math-emu
-
-HOSTCC         = gcc
-HOSTCFLAGS     = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
-
-CROSS_COMPILE  =
-
-#
-# Include the make variables (CC, etc...)
-#
-
-AS             = $(CROSS_COMPILE)as
-LD             = $(CROSS_COMPILE)ld
-CC             = $(CROSS_COMPILE)gcc
-CPP            = $(CC) -E
-AR             = $(CROSS_COMPILE)ar
-NM             = $(CROSS_COMPILE)nm
-STRIP          = $(CROSS_COMPILE)strip
-OBJCOPY                = $(CROSS_COMPILE)objcopy
-OBJDUMP                = $(CROSS_COMPILE)objdump
-MAKEFILES      = $(TOPDIR)/.config
-GENKSYMS       = /sbin/genksyms
-DEPMOD         = /sbin/depmod
-MODFLAGS       = -DMODULE
-CFLAGS_KERNEL  =
-PERL           = perl
-AWK            = awk
-RPM            := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
-                       else echo rpm; fi)
-
-export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
-       CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
-       CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL 
AWK
-
-all:   do-it-all
-
-#
-# Make "config" the default target if there is no configuration file or
-# "depend" the target if there is no top-level dependency information.
-#
-
-ifeq (.config,$(wildcard .config))
-include .config
-ifeq (.depend,$(wildcard .depend))
-include .depend
-do-it-all:     Version vmlinux
-else
-CONFIGURATION = depend
-do-it-all:     depend
-endif
-else
-CONFIGURATION = config
-do-it-all:     config
-endif
-
-#
-# INSTALL_PATH specifies where to place the updated kernel and system map
-# images.  Uncomment if you want to place them anywhere other than root.
-#
-
-#export        INSTALL_PATH=/boot
-
-#
-# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
-# relocations required by build roots.  This is not defined in the
-# makefile but the arguement can be passed to make if needed.
-#
-
-MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
-export MODLIB
-
-#
-# standard CFLAGS
-#
-
-CPPFLAGS := -D__KERNEL__ -I$(HPATH)
-
-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
-         -fno-strict-aliasing -fno-common
-ifndef CONFIG_FRAME_POINTER
-CFLAGS += -fomit-frame-pointer
-endif
-AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
-
-#
-# ROOT_DEV specifies the default root-device when making the image.
-# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
-# the default of FLOPPY is used by 'build'.
-# This is i386 specific.
-#
-
-export ROOT_DEV = CURRENT
-
-#
-# If you want to preset the SVGA mode, uncomment the next line and
-# set SVGA_MODE to whatever number you want.
-# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
-# The number is the same as you would ordinarily press at bootup.
-# This is i386 specific.
-#
-
-export SVGA_MODE = -DSVGA_MODE=NORMAL_VGA
-
-#
-# If you want the RAM disk device, define this to be the size in blocks.
-# This is i386 specific.
-#
-
-#export RAMDISK = -DRAMDISK=512
-
-CORE_FILES     =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
-NETWORKS       =net/network.o
-
-LIBS           =$(TOPDIR)/lib/lib.a
-SUBDIRS                =kernel drivers mm fs net ipc lib crypto
-
-DRIVERS-n :=
-DRIVERS-y :=
-DRIVERS-m :=
-DRIVERS-  :=
-
-DRIVERS-$(CONFIG_ACPI_BOOT) += drivers/acpi/acpi.o
-DRIVERS-$(CONFIG_PARPORT) += drivers/parport/driver.o
-DRIVERS-y += drivers/char/char.o \
-       drivers/block/block.o \
-       drivers/misc/misc.o \
-       drivers/net/net.o
-DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o
-DRIVERS-$(CONFIG_DRM_NEW) += drivers/char/drm/drm.o
-DRIVERS-$(CONFIG_DRM_OLD) += drivers/char/drm-4.0/drm.o
-DRIVERS-$(CONFIG_NUBUS) += drivers/nubus/nubus.a
-DRIVERS-$(CONFIG_NET_FC) += drivers/net/fc/fc.o
-DRIVERS-$(CONFIG_DEV_APPLETALK) += drivers/net/appletalk/appletalk.o
-DRIVERS-$(CONFIG_TR) += drivers/net/tokenring/tr.o
-DRIVERS-$(CONFIG_WAN) += drivers/net/wan/wan.o
-DRIVERS-$(CONFIG_ARCNET) += drivers/net/arcnet/arcnetdrv.o
-DRIVERS-$(CONFIG_ATM) += drivers/atm/atm.o
-DRIVERS-$(CONFIG_IDE) += drivers/ide/idedriver.o
-DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
-DRIVERS-$(CONFIG_SCSI) += drivers/scsi/scsidrv.o
-DRIVERS-$(CONFIG_FUSION_BOOT) += drivers/message/fusion/fusion.o
-DRIVERS-$(CONFIG_IEEE1394) += drivers/ieee1394/ieee1394drv.o
-
-ifneq 
($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
-DRIVERS-y += drivers/cdrom/driver.o
-endif
-
-DRIVERS-$(CONFIG_SOUND) += drivers/sound/sounddrivers.o
-DRIVERS-$(CONFIG_PCI) += drivers/pci/driver.o
-DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtdlink.o
-DRIVERS-$(CONFIG_PCMCIA) += drivers/pcmcia/pcmcia.o
-DRIVERS-$(CONFIG_NET_PCMCIA) += drivers/net/pcmcia/pcmcia_net.o
-DRIVERS-$(CONFIG_NET_WIRELESS) += drivers/net/wireless/wireless_net.o
-DRIVERS-$(CONFIG_PCMCIA_CHRDEV) += drivers/char/pcmcia/pcmcia_char.o
-DRIVERS-$(CONFIG_DIO) += drivers/dio/dio.a
-DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o
-DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/driver.o
-DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
-DRIVERS-$(CONFIG_PPC32) += drivers/macintosh/macintosh.o
-DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
-DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
-DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
-DRIVERS-$(CONFIG_VT) += drivers/video/video.o
-DRIVERS-$(CONFIG_PARIDE) += drivers/block/paride/paride.a
-DRIVERS-$(CONFIG_HAMRADIO) += drivers/net/hamradio/hamradio.o
-DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
-DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
-DRIVERS-$(CONFIG_USB_GADGET) += drivers/usb/gadget/built-in.o
-DRIVERS-y +=drivers/media/media.o
-DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
-DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
-DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o
-DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
-DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
-DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
-DRIVERS-$(CONFIG_GSC) += drivers/gsc/gscbus.o
-DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
-DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
-DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
-DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o
-
-DRIVERS := $(DRIVERS-y)
-
-
-# files removed with 'make clean'
-CLEAN_FILES = \
-       kernel/ksyms.lst include/linux/compile.h \
-       vmlinux System.map \
-       .tmp* \
-       drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
-       drivers/char/conmakehash \
-       drivers/char/drm/*-mod.c \
-       drivers/pci/devlist.h drivers/pci/classlist.h drivers/pci/gen-devlist \
-       drivers/zorro/devlist.h drivers/zorro/gen-devlist \
-       drivers/sound/bin2hex drivers/sound/hex2hex \
-       drivers/atm/fore200e_mkfirm drivers/atm/{pca,sba}*{.bin,.bin1,.bin2} \
-       drivers/scsi/aic7xxx/aicasm/aicasm \
-       drivers/scsi/aic7xxx/aicasm/aicasm_gram.c \
-       drivers/scsi/aic7xxx/aicasm/aicasm_gram.h \
-       drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.c \
-       drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.h \
-       drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.c \
-       drivers/scsi/aic7xxx/aicasm/aicasm_scan.c \
-       drivers/scsi/aic7xxx/aicasm/aicdb.h \
-       drivers/scsi/aic7xxx/aicasm/y.tab.h \
-       drivers/scsi/53c700_d.h \
-       drivers/tc/lk201-map.c \
-       net/khttpd/make_times_h \
-       net/khttpd/times.h \
-       submenu* \
-       drivers/ieee1394/oui.c
-# directories removed with 'make clean'
-CLEAN_DIRS = \
-       modules
-
-# files removed with 'make mrproper'
-MRPROPER_FILES = \
-       include/linux/autoconf.h include/linux/version.h \
-       lib/crc32table.h lib/gen_crc32table \
-       drivers/net/hamradio/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h \
-       drivers/net/hamradio/soundmodem/sm_tbl_{hapn4800,psk4800}.h \
-       drivers/net/hamradio/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h \
-       drivers/net/hamradio/soundmodem/gentbl \
-       drivers/sound/*_boot.h drivers/sound/.*.boot \
-       drivers/sound/msndinit.c \
-       drivers/sound/msndperm.c \
-       drivers/sound/pndsperm.c \
-       drivers/sound/pndspini.c \
-       drivers/atm/fore200e_*_fw.c drivers/atm/.fore200e_*.fw \
-       .version .config* config.in config.old \
-       scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp \
-       scripts/lxdialog/*.o scripts/lxdialog/lxdialog \
-       .menuconfig.log \
-       include/asm \
-       .hdepend scripts/mkdep scripts/split-include scripts/docproc \
-       $(TOPDIR)/include/linux/modversions.h \
-       kernel.spec
-
-# directories removed with 'make mrproper'
-MRPROPER_DIRS = \
-       include/config \
-       $(TOPDIR)/include/linux/modules
-
-
-include arch/$(ARCH)/Makefile
-
-# Extra cflags for kbuild 2.4.  The default is to forbid includes by kernel 
code
-# from user space headers.  Some UML code requires user space headers, in the
-# UML Makefiles add 'kbuild_2_4_nostdinc :=' before include Rules.make.  No
-# other kernel code should include user space headers, if you need
-# 'kbuild_2_4_nostdinc :=' or -I/usr/include for kernel code and you are not 
UML
-# then your code is broken!  KAO.
-
-kbuild_2_4_nostdinc    := -nostdinc -iwithprefix include
-export kbuild_2_4_nostdinc
-
-export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
-
-export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
-
-.S.s:
-       $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
-.S.o:
-       $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -c -o $*.o $<
-
-Version: dummy
-       @rm -f include/linux/compile.h
-
-boot: vmlinux
-       @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
-
-vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o 
init/do_mounts.o linuxsubdirs
-       $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
-               --start-group \
-               $(CORE_FILES) \
-               $(DRIVERS) \
-               $(NETWORKS) \
-               $(LIBS) \
-               --end-group \
-               -o vmlinux
-       $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] 
\)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
-
-symlinks:
-       rm -f include/asm
-       ( cd include ; ln -sf asm-$(ARCH) asm)
-       @if [ ! -d include/linux/modules ]; then \
-               mkdir include/linux/modules; \
-       fi
-
-oldconfig: symlinks
-       $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
-
-xconfig: symlinks
-       $(MAKE) -C scripts kconfig.tk
-       wish -f scripts/kconfig.tk
-
-menuconfig: include/linux/version.h symlinks
-       $(MAKE) -C scripts/lxdialog all
-       $(CONFIG_SHELL) scripts/Menuconfig arch/$(ARCH)/config.in
-
-config: symlinks
-       $(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in
-
-include/config/MARKER: scripts/split-include include/linux/autoconf.h
-       scripts/split-include include/linux/autoconf.h include/config
-       @ touch include/config/MARKER
-
-linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))
-
-$(patsubst %, _dir_%, $(SUBDIRS)) : dummy include/linux/version.h 
include/config/MARKER
-       $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@)
-
-$(TOPDIR)/include/linux/version.h: include/linux/version.h
-$(TOPDIR)/include/linux/compile.h: include/linux/compile.h
-
-newversion:
-       . scripts/mkversion > .tmpversion
-       @mv -f .tmpversion .version
-
-uts_len                := 64
-uts_truncate   := sed -e 's/\(.\{1,$(uts_len)\}\).*/\1/'
-
-include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
-       @echo -n \#`cat .version` > .ver1
-       @if [ -n "$(CONFIG_SMP)" ] ; then echo -n " SMP" >> .ver1; fi
-       @if [ -f .name ]; then  echo -n \-`cat .name` >> .ver1; fi
-       @LANG=C echo ' '`date` >> .ver1
-       @echo \#define UTS_VERSION \"`cat .ver1 | $(uts_truncate)`\" > .ver
-       @LANG=C echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
-       @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
-       @echo \#define LINUX_COMPILE_HOST \"`hostname | $(uts_truncate)`\" >> 
.ver
-       @([ -x /bin/dnsdomainname ] && /bin/dnsdomainname > .ver1) || \
-        ([ -x /bin/domainname ] && /bin/domainname > .ver1) || \
-        echo > .ver1
-       @echo \#define LINUX_COMPILE_DOMAIN \"`cat .ver1 | $(uts_truncate)`\" 
>> .ver
-       @echo \#define LINUX_COMPILER \"`$(CC) $(CFLAGS) -v 2>&1 | tail -n 1`\" 
>> .ver
-       @mv -f .ver $@
-       @rm -f .ver1
-
-include/linux/version.h: ./Makefile
-       @expr length "$(KERNELRELEASE)" \<= $(uts_len) > /dev/null || \
-         (echo KERNELRELEASE \"$(KERNELRELEASE)\" exceeds $(uts_len) 
characters >&2; false)
-       @echo \#define UTS_RELEASE \"$(KERNELRELEASE)\" > .ver
-       @echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + 
$(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver
-       @echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' 
>>.ver
-       @mv -f .ver $@
-
-comma  := ,
-
-init/version.o: init/version.c include/linux/compile.h include/config/MARKER
-       $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(SUBARCH)"' 
-DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o 
init/version.c
-
-init/main.o: init/main.c include/config/MARKER
-       $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst 
$(comma),_,$(subst -,_,$(*F))) -c -o $@ $<
-
-init/do_mounts.o: init/do_mounts.c include/config/MARKER
-       $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst 
$(comma),_,$(subst -,_,$(*F))) -c -o $@ $<
-
-fs lib mm ipc kernel drivers net: dummy
-       $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
-
-TAGS: dummy
-       { find include/asm-${ARCH} -name '*.h' -print ; \
-       find include -type d \( -name "asm-*" -o -name config \) -prune -o 
-name '*.h' -print ; \
-       find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | 
grep -v '\.svn' | etags -
-
-# Exuberant ctags works better with -I
-tags: dummy
-       CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I 
__initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
-       ctags $$CTAGSF `find include/asm-$(ARCH) -name '*.h'` && \
-       find include -type d \( -name "asm-*" -o -name config \) -prune -o 
-name '*.h' -print | xargs ctags $$CTAGSF -a && \
-       find $(SUBDIRS) init -name '*.[ch]' | xargs ctags $$CTAGSF -a
-
-ifdef CONFIG_MODULES
-ifdef CONFIG_MODVERSIONS
-MODFLAGS += -DMODVERSIONS -include $(HPATH)/linux/modversions.h
-endif
-
-.PHONY: modules
-modules: $(patsubst %, _mod_%, $(SUBDIRS))
-
-.PHONY: $(patsubst %, _mod_%, $(SUBDIRS))
-$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h 
include/config/MARKER
-       $(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" 
MAKING_MODULES=1 modules
-
-.PHONY: modules_install
-modules_install: _modinst_ $(patsubst %, _modinst_%, $(SUBDIRS)) _modinst_post
-
-.PHONY: _modinst_
-_modinst_:
-       @rm -rf $(MODLIB)/kernel
-       @rm -f $(MODLIB)/build
-       @mkdir -p $(MODLIB)/kernel
-       @ln -s $(TOPDIR) $(MODLIB)/build
-
-# If System.map exists, run depmod.  This deliberately does not have a
-# dependency on System.map since that would run the dependency tree on
-# vmlinux.  This depmod is only for convenience to give the initial
-# boot a modules.dep even before / is mounted read-write.  However the
-# boot script depmod is the master version.
-ifeq "$(strip $(INSTALL_MOD_PATH))" ""
-depmod_opts    :=
-else
-depmod_opts    := -b $(INSTALL_MOD_PATH) -r
-endif
-.PHONY: _modinst_post
-_modinst_post: _modinst_post_pcmcia
-       if [ -r System.map ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) 
$(KERNELRELEASE); fi
-
-# Backwards compatibilty symlinks for people still using old versions
-# of pcmcia-cs with hard coded pathnames on insmod.  Remove
-# _modinst_post_pcmcia for kernel 2.4.1.
-.PHONY: _modinst_post_pcmcia
-_modinst_post_pcmcia:
-       cd $(MODLIB); \
-       mkdir -p pcmcia; \
-       find kernel -path '*/pcmcia/*' -name '*.o' | xargs -i -r ln -sf ../{} 
pcmcia
-
-.PHONY: $(patsubst %, _modinst_%, $(SUBDIRS))
-$(patsubst %, _modinst_%, $(SUBDIRS)) :
-       $(MAKE) -C $(patsubst _modinst_%, %, $@) modules_install
-
-# modules disabled....
-
-else
-modules modules_install: dummy
-       @echo
-       @echo "The present kernel configuration has modules disabled."
-       @echo "Type 'make config' and enable loadable module support."
-       @echo "Then build a kernel with module support enabled."
-       @echo
-       @exit 1
-endif
-
-clean: archclean
-       find . \( -name '*.[oas]' -o -name core -o -name '.*.flags' \) -type f 
-print \
-               | grep -v lxdialog/ | xargs rm -f
-       rm -f $(CLEAN_FILES)
-       rm -rf $(CLEAN_DIRS)
-       $(MAKE) -C Documentation/DocBook clean
-
-mrproper: clean archmrproper
-       find . \( -size 0 -o -name .depend \) -type f -print | xargs rm -f
-       rm -f $(MRPROPER_FILES)
-       rm -rf $(MRPROPER_DIRS)
-       $(MAKE) -C Documentation/DocBook mrproper
-
-distclean: mrproper
-       rm -f core `find . \( -not -type d \) -and \
-               \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-               -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-               -o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -type f 
-print` TAGS tags
-
-backup: mrproper
-       cd .. && tar cf - linux/ | gzip -9 > backup.gz
-       sync
-
-sgmldocs: 
-       chmod 755 $(TOPDIR)/scripts/docgen
-       chmod 755 $(TOPDIR)/scripts/gen-all-syms
-       chmod 755 $(TOPDIR)/scripts/kernel-doc
-       $(MAKE) -C $(TOPDIR)/Documentation/DocBook books
-
-psdocs: sgmldocs
-       $(MAKE) -C Documentation/DocBook ps
-
-pdfdocs: sgmldocs
-       $(MAKE) -C Documentation/DocBook pdf
-
-htmldocs: sgmldocs
-       $(MAKE) -C Documentation/DocBook html
-
-mandocs:
-       chmod 755 $(TOPDIR)/scripts/kernel-doc
-       chmod 755 $(TOPDIR)/scripts/split-man
-       $(MAKE) -C Documentation/DocBook man
-
-sums:
-       find . -type f -print | sort | xargs sum > .SUMS
-
-dep-files: scripts/mkdep archdep include/linux/version.h
-       rm -f .depend .hdepend
-       $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) 
_FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
-ifdef CONFIG_MODVERSIONS
-       $(MAKE) update-modverfile
-endif
-       scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) 
-prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-       scripts/mkdep -- init/*.c > .depend
-
-ifdef CONFIG_MODVERSIONS
-MODVERFILE := $(TOPDIR)/include/linux/modversions.h
-else
-MODVERFILE :=
-endif
-export MODVERFILE
-
-depend dep: dep-files
-
-checkconfig:
-       find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w 
scripts/checkconfig.pl
-
-checkhelp:
-       find * -name [cC]onfig.in -print | sort | xargs $(PERL) -w 
scripts/checkhelp.pl
-
-checkincludes:
-       find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w 
scripts/checkincludes.pl
-
-ifdef CONFIGURATION
-..$(CONFIGURATION):
-       @echo
-       @echo "You have a bad or nonexistent" .$(CONFIGURATION) ": running 
'make" $(CONFIGURATION)"'"
-       @echo
-       $(MAKE) $(CONFIGURATION)
-       @echo
-       @echo "Successful. Try re-making (ignore the error that follows)"
-       @echo
-       exit 1
-
-#dummy: ..$(CONFIGURATION)
-dummy:
-
-else
-
-dummy:
-
-endif
-
-include Rules.make
-
-#
-# This generates dependencies for the .h files.
-#
-
-scripts/mkdep: scripts/mkdep.c
-       $(HOSTCC) $(HOSTCFLAGS) -o scripts/mkdep scripts/mkdep.c
-
-scripts/split-include: scripts/split-include.c
-       $(HOSTCC) $(HOSTCFLAGS) -o scripts/split-include scripts/split-include.c
-
-#
-# RPM target
-#
-#      If you do a make spec before packing the tarball you can rpm -ta it
-#
-spec:
-       . scripts/mkspec >kernel.spec
-
-#
-#      Build a tar ball, generate an rpm from it and pack the result
-#      There arw two bits of magic here
-#      1) The use of /. to avoid tar packing just the symlink
-#      2) Removing the .dep files as they have source paths in them that
-#         will become invalid
-#
-rpm:   clean spec
-       find . \( -size 0 -o -name .depend -o -name .hdepend \) -type f -print 
| xargs rm -f
-       set -e; \
-       cd $(TOPDIR)/.. ; \
-       ln -sf $(TOPDIR) $(KERNELPATH) ; \
-       tar -cvz --exclude CVS -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
-       rm $(KERNELPATH) ; \
-       cd $(TOPDIR) ; \
-       . scripts/mkversion > .version ; \
-       $(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
-       rm $(TOPDIR)/../$(KERNELPATH).tar.gz
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/Makefile    Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,137 +0,0 @@
-#
-# xen/Makefile
-#
-# This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" and "archdep" for cleaning up and making dependencies for
-# this architecture
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994 by Linus Torvalds
-#
-# 19990713  Artur Skawina <skawina@xxxxxxxxxxxxx>
-#           Added '-march' and '-mpreferred-stack-boundary' support
-#
-
-# If no .config file exists then use the appropriate defconfig-* file
-ifneq (.config,$(wildcard .config))
-DUMMYX:=$(shell cp $(TOPDIR)/arch/xen/defconfig$(EXTRAVERSION) 
$(TOPDIR)/.config)
--include $(TOPDIR)/.config
-endif
-
-LD=$(CROSS_COMPILE)ld -m elf_i386
-OBJCOPY=$(CROSS_COMPILE)objcopy -R .note -R .comment -S
-LDFLAGS=-e stext
-LINKFLAGS =-T $(TOPDIR)/arch/xen/vmlinux.lds $(LDFLAGS)
-
-CFLAGS += -pipe
-
-check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 
2>&1; then echo "$(1)"; else echo "$(2)"; fi)
-
-# prevent gcc from keeping the stack 16 byte aligned
-CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,)
-
-ifdef CONFIG_M686
-CFLAGS += -march=i686
-endif
-
-ifdef CONFIG_MPENTIUMIII
-CFLAGS += -march=i686
-endif
-
-ifdef CONFIG_MPENTIUM4
-CFLAGS += -march=i686
-endif
-
-ifdef CONFIG_MK7
-CFLAGS += $(call check_gcc,-march=athlon,-march=i686 -malign-functions=4)
-endif
-
-# Disable unit-at-a-time mode, it makes gcc use a lot more stack
-# due to the lack of sharing of stacklots.
-CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
-
-HEAD := arch/xen/kernel/head.o arch/xen/kernel/init_task.o
-
-SUBDIRS += arch/xen/kernel arch/xen/mm arch/xen/lib
-SUBDIRS += arch/xen/drivers/console 
-SUBDIRS += arch/xen/drivers/evtchn
-SUBDIRS += arch/xen/drivers/blkif
-SUBDIRS += arch/xen/drivers/netif
-SUBDIRS += arch/xen/drivers/balloon
-ifdef CONFIG_XEN_PRIVILEGED_GUEST
-SUBDIRS += arch/xen/drivers/dom0 
-endif
-
-CORE_FILES += arch/xen/kernel/kernel.o arch/xen/mm/mm.o
-CORE_FILES += arch/xen/drivers/evtchn/drv.o
-CORE_FILES += arch/xen/drivers/console/drv.o
-DRIVERS += arch/xen/drivers/blkif/drv.o
-DRIVERS += arch/xen/drivers/netif/drv.o
-ifdef CONFIG_XEN_PRIVILEGED_GUEST
-CORE_FILES += arch/xen/drivers/dom0/drv.o
-endif
-CORE_FILES += arch/xen/drivers/balloon/drv.o
-LIBS := $(TOPDIR)/arch/xen/lib/lib.a $(LIBS) $(TOPDIR)/arch/xen/lib/lib.a
-
-arch/xen/kernel: dummy
-       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/kernel
-
-arch/xen/mm: dummy
-       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/mm
-
-arch/xen/drivers/console: dummy
-       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/console
-
-arch/xen/drivers/network: dummy
-       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/network
-
-arch/xen/drivers/block: dummy
-       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/block
-
-arch/xen/drivers/dom0: dummy
-       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/dom0
-
-arch/xen/drivers/balloon: dummy
-       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/balloon
-
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-
-vmlinux: arch/xen/vmlinux.lds
-
-FORCE: ;
-
-.PHONY: bzImage compressed clean archclean archmrproper archdep
-
-
-bzImage: vmlinux
-       @$(MAKEBOOT) bzImage
-
-INSTALL_NAME ?= $(KERNELRELEASE)
-install: bzImage
-       mkdir -p $(INSTALL_PATH)/boot
-       ln -f -s vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX) 
$(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
-       rm -f $(INSTALL_PATH)/boot/vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX)
-       install -m0644 arch/$(ARCH)/boot/bzImage 
$(INSTALL_PATH)/boot/vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX)
-       install -m0644 vmlinux 
$(INSTALL_PATH)/boot/vmlinux-syms-$(INSTALL_NAME)$(INSTALL_SUFFIX)
-       install -m0664 .config 
$(INSTALL_PATH)/boot/config-$(INSTALL_NAME)$(INSTALL_SUFFIX)
-       install -m0664 System.map 
$(INSTALL_PATH)/boot/System.map-$(INSTALL_NAME)$(INSTALL_SUFFIX)
-       ln -f -s vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX) 
$(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
-
-%_config: arch/xen/defconfig-%
-       rm -f .config arch/xen/defconfig
-       cp -f arch/xen/defconfig-$(@:_config=) arch/xen/defconfig
-       cp -f arch/xen/defconfig-$(@:_config=) .config
-
-
-archclean:
-       @$(MAKEBOOT) clean
-
-archmrproper:
-       rm -f include/asm-xen/xen-public/arch
-
-archdep:
-       @$(MAKEBOOT) dep
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/boot/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/boot/Makefile       Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,13 +0,0 @@
-#
-# arch/xen/boot/Makefile
-#
-
-bzImage: $(TOPDIR)/vmlinux
-       $(OBJCOPY) $< Image
-       gzip -f -9 < Image > $@
-       rm -f Image
-
-dep:
-
-clean:
-       rm -f bzImage Image
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/config.in
--- a/linux-2.4-xen-sparse/arch/xen/config.in   Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,327 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/config-language.txt.
-#
-mainmenu_name "Linux Kernel Configuration"
-
-define_bool CONFIG_XEN y
-
-define_bool CONFIG_X86 y
-define_bool CONFIG_ISA y
-define_bool CONFIG_SBUS n
-
-define_bool CONFIG_UID16 y
-
-mainmenu_option next_comment
-comment 'Xen'
-bool 'Support for privileged operations (domain 0)' CONFIG_XEN_PRIVILEGED_GUEST
-bool 'Device-driver domain (physical device access)' CONFIG_XEN_PHYSDEV_ACCESS
-bool 'Scrub memory before freeing it to Xen' CONFIG_XEN_SCRUB_PAGES
-bool 'Network-device frontend driver' CONFIG_XEN_NETDEV_FRONTEND
-bool 'Block-device frontend driver' CONFIG_XEN_BLKDEV_FRONTEND
-bool 'Block-device uses grant tables' CONFIG_XEN_BLKDEV_GRANT
-endmenu
-# The IBM S/390 patch needs this.
-define_bool CONFIG_NO_IDLE_HZ y
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   define_bool CONFIG_FOREIGN_PAGES y
-else
-   define_bool CONFIG_FOREIGN_PAGES n
-   define_bool CONFIG_NETDEVICES y
-   define_bool CONFIG_VT n
-fi
-
-mainmenu_option next_comment
-comment 'Code maturity level options'
-bool 'Prompt for development and/or incomplete code/drivers' 
CONFIG_EXPERIMENTAL
-endmenu
-
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'Processor type and features'
-choice 'Processor family' \
-       "Pentium-Pro/Celeron/Pentium-II         CONFIG_M686 \
-        Pentium-III/Celeron(Coppermine)        CONFIG_MPENTIUMIII \
-        Pentium-4                              CONFIG_MPENTIUM4 \
-        Athlon/Duron/K7                        CONFIG_MK7 \
-        Opteron/Athlon64/Hammer/K8             CONFIG_MK8 \
-        VIA-C3-2                               CONFIG_MVIAC3_2" Pentium-Pro
-
-   define_bool CONFIG_X86_WP_WORKS_OK y
-   define_bool CONFIG_X86_INVLPG y
-   define_bool CONFIG_X86_CMPXCHG y
-   define_bool CONFIG_X86_XADD y
-   define_bool CONFIG_X86_BSWAP y
-   define_bool CONFIG_X86_POPAD_OK y
-   define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
-   define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
-
-   define_bool CONFIG_X86_GOOD_APIC y
-   define_bool CONFIG_X86_PGE y
-   define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
-   define_bool CONFIG_X86_TSC y
-
-if [ "$CONFIG_M686" = "y" ]; then
-   define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-fi
-if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
-   define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-fi
-if [ "$CONFIG_MPENTIUM4" = "y" ]; then
-   define_int  CONFIG_X86_L1_CACHE_SHIFT 7
-fi
-if [ "$CONFIG_MK8" = "y" ]; then
-   define_bool CONFIG_MK7 y
-fi
-if [ "$CONFIG_MK7" = "y" ]; then
-   define_int  CONFIG_X86_L1_CACHE_SHIFT 6
-   define_bool CONFIG_X86_USE_3DNOW y
-fi
-if [ "$CONFIG_MVIAC3_2" = "y" ]; then
-   define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-fi
-
-#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-#   tristate 'BIOS Enhanced Disk Drive calls determine boot disk 
(EXPERIMENTAL)' CONFIG_EDD
-#fi
-
-choice 'High Memory Support' \
-       "off    CONFIG_NOHIGHMEM \
-        4GB    CONFIG_HIGHMEM4G" off
-#       64GB   CONFIG_HIGHMEM64G" off
-if [ "$CONFIG_HIGHMEM4G" = "y" ]; then
-   define_bool CONFIG_HIGHMEM y
-fi
-if [ "$CONFIG_HIGHMEM64G" = "y" ]; then
-   define_bool CONFIG_HIGHMEM y
-   define_bool CONFIG_X86_PAE y
-fi
-
-if [ "$CONFIG_HIGHMEM" = "y" ]; then
-   bool 'HIGHMEM I/O support' CONFIG_HIGHIO
-fi
-
-define_int CONFIG_FORCE_MAX_ZONEORDER 11
-
-#bool 'Symmetric multi-processing support' CONFIG_SMP
-#if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
-#   define_bool CONFIG_HAVE_DEC_LOCK y
-#fi
-endmenu
-
-mainmenu_option next_comment
-comment 'General setup'
-
-bool 'Networking support' CONFIG_NET
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   bool 'PCI support' CONFIG_PCI
-   source drivers/pci/Config.in
-
-   bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
-
-   if [ "$CONFIG_HOTPLUG" = "y" ] ; then
-      source drivers/pcmcia/Config.in
-      source drivers/hotplug/Config.in
-   else
-      define_bool CONFIG_PCMCIA n
-      define_bool CONFIG_HOTPLUG_PCI n
-   fi
-fi
-
-bool 'System V IPC' CONFIG_SYSVIPC
-bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
-bool 'Sysctl support' CONFIG_SYSCTL
-if [ "$CONFIG_PROC_FS" = "y" ]; then
-   choice 'Kernel core (/proc/kcore) format' \
-       "ELF            CONFIG_KCORE_ELF        \
-        A.OUT          CONFIG_KCORE_AOUT" ELF
-fi
-tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
-bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
-tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER
-
-endmenu
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   source drivers/mtd/Config.in
-
-   source drivers/parport/Config.in
-
-   source drivers/pnp/Config.in
-
-   source drivers/block/Config.in
-
-   source drivers/md/Config.in
-fi
-
-if [ "$CONFIG_NET" = "y" ]; then
-   source net/Config.in
-fi
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'ATA/IDE/MFM/RLL support'
-
-   tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
-
-   if [ "$CONFIG_IDE" != "n" ]; then
-      source drivers/ide/Config.in
-   else
-      define_bool CONFIG_BLK_DEV_HD n
-   fi
-   endmenu
-fi
-
-mainmenu_option next_comment
-comment 'SCSI support'
-
-tristate 'SCSI support' CONFIG_SCSI
-
-if [ "$CONFIG_SCSI" != "n" ]; then
-   source drivers/scsi/Config.in
-fi
-endmenu
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   source drivers/message/fusion/Config.in
-
-   source drivers/ieee1394/Config.in
-
-   source drivers/message/i2o/Config.in
-
-   if [ "$CONFIG_NET" = "y" ]; then
-      mainmenu_option next_comment
-      comment 'Network device support'
-
-      bool 'Network device support' CONFIG_NETDEVICES
-      if [ "$CONFIG_NETDEVICES" = "y" ]; then
-         source drivers/net/Config.in
-         if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
-            source drivers/atm/Config.in
-         fi
-      fi
-      endmenu
-   fi
-
-   source net/ax25/Config.in
-
-   source net/irda/Config.in
-
-   mainmenu_option next_comment
-   comment 'ISDN subsystem'
-   if [ "$CONFIG_NET" != "n" ]; then
-      tristate 'ISDN support' CONFIG_ISDN
-      if [ "$CONFIG_ISDN" != "n" ]; then
-         source drivers/isdn/Config.in
-      fi
-   fi
-   endmenu
-
-   if [ "$CONFIG_ISA" = "y" ]; then
-       mainmenu_option next_comment
-       comment 'Old CD-ROM drivers (not SCSI, not IDE)'
-   
-       bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
-       if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-          source drivers/cdrom/Config.in
-       fi
-       endmenu
-   fi
-
-   #
-   # input before char - char/joystick depends on it. As does USB.
-   #
-   source drivers/input/Config.in
-else
-   #
-   # Block device driver configuration
-   #
-   mainmenu_option next_comment
-   comment 'Block devices'
-   tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
-   dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
-   tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
-   if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
-      int '  Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
-   fi
-   dep_bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD 
$CONFIG_BLK_DEV_RAM
-   bool 'Per partition statistics in /proc/partitions' CONFIG_BLK_STATS
-   define_bool CONFIG_BLK_DEV_HD n
-   endmenu
-fi
-
-source drivers/char/Config.in
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   source drivers/media/Config.in
-fi
-
-source fs/Config.in
-
-mainmenu_option next_comment
-comment 'Console drivers'
-
-define_bool CONFIG_XEN_CONSOLE y
-
-if [ "$CONFIG_VT" = "y" ]; then
-   bool 'VGA text console' CONFIG_VGA_CONSOLE
-   bool 'Dummy console' CONFIG_DUMMY_CONSOLE 
-   if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-      bool 'Video mode selection support' CONFIG_VIDEO_SELECT
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-         tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' 
CONFIG_MDA_CONSOLE
-         source drivers/video/Config.in
-      fi
-   fi
-fi
-endmenu
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'Sound'
-
-   tristate 'Sound card support' CONFIG_SOUND
-   if [ "$CONFIG_SOUND" != "n" ]; then
-      source drivers/sound/Config.in
-   fi
-   endmenu
-fi
-
-if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
-   source drivers/usb/Config.in
-   source net/bluetooth/Config.in
-fi
-
-mainmenu_option next_comment
-comment 'Kernel hacking'
-
-bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
-if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
-   bool '  Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
-   bool '  Debug high memory support' CONFIG_DEBUG_HIGHMEM
-   bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
-   bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
-   bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
-   bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
-   bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
-   bool '  Load all symbols for debugging' CONFIG_KALLSYMS
-   bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
-fi
-
-int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
-
-endmenu
-
-source crypto/Config.in
-source lib/Config.in
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/defconfig-xen0
--- a/linux-2.4-xen-sparse/arch/xen/defconfig-xen0      Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,927 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_XEN=y
-CONFIG_X86=y
-CONFIG_ISA=y
-# CONFIG_SBUS is not set
-CONFIG_UID16=y
-
-#
-# Xen
-#
-CONFIG_XEN_PRIVILEGED_GUEST=y
-CONFIG_XEN_PHYSDEV_ACCESS=y
-# CONFIG_XEN_USB_BACKEND is not set
-CONFIG_XEN_SCRUB_PAGES=y
-CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_BLKDEV_GRANT=y
-# CONFIG_XEN_USB_FRONTEND is not set
-CONFIG_NO_IDLE_HZ=y
-CONFIG_FOREIGN_PAGES=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
-# Processor type and features
-#
-CONFIG_M686=y
-# CONFIG_MPENTIUMIII is not set
-# CONFIG_MPENTIUM4 is not set
-# CONFIG_MK7 is not set
-# CONFIG_MK8 is not set
-# CONFIG_MVIAC3_2 is not set
-CONFIG_X86_WP_WORKS_OK=y
-CONFIG_X86_INVLPG=y
-CONFIG_X86_CMPXCHG=y
-CONFIG_X86_XADD=y
-CONFIG_X86_BSWAP=y
-CONFIG_X86_POPAD_OK=y
-# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_X86_GOOD_APIC=y
-CONFIG_X86_PGE=y
-CONFIG_X86_USE_PPRO_CHECKSUM=y
-CONFIG_X86_TSC=y
-CONFIG_X86_L1_CACHE_SHIFT=5
-CONFIG_NOHIGHMEM=y
-# CONFIG_HIGHMEM4G is not set
-CONFIG_FORCE_MAX_ZONEORDER=11
-
-#
-# General setup
-#
-CONFIG_NET=y
-CONFIG_PCI=y
-CONFIG_PCI_NAMES=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
-# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_OOM_KILLER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play configuration
-#
-CONFIG_PNP=y
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_CISS_MONITOR_THREAD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-# CONFIG_MD_RAID0 is not set
-CONFIG_MD_RAID1=y
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-CONFIG_BLK_DEV_LVM=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-#   IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=y
-# CONFIG_IP_NF_MATCH_LIMIT is not set
-# CONFIG_IP_NF_MATCH_MAC is not set
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-# CONFIG_IP_NF_MATCH_MARK is not set
-# CONFIG_IP_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP_NF_MATCH_TOS is not set
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-# CONFIG_IP_NF_MATCH_AH_ESP is not set
-# CONFIG_IP_NF_MATCH_LENGTH is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_MATCH_PHYSDEV=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-# CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_IP_NF_TARGET_ULOG=y
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-#   IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-
-#
-#    SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_VLAN_8021Q=y
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=y
-CONFIG_BRIDGE_NF_EBTABLES=m
-CONFIG_BRIDGE_EBT_T_FILTER=m
-CONFIG_BRIDGE_EBT_T_NAT=m
-CONFIG_BRIDGE_EBT_BROUTE=m
-CONFIG_BRIDGE_EBT_LOG=m
-CONFIG_BRIDGE_EBT_IPF=m
-CONFIG_BRIDGE_EBT_ARPF=m
-CONFIG_BRIDGE_EBT_AMONG=m
-CONFIG_BRIDGE_EBT_LIMIT=m
-CONFIG_BRIDGE_EBT_VLANF=m
-CONFIG_BRIDGE_EBT_802_3=m
-CONFIG_BRIDGE_EBT_PKTTYPE=m
-CONFIG_BRIDGE_EBT_STP=m
-CONFIG_BRIDGE_EBT_MARKF=m
-CONFIG_BRIDGE_EBT_ARPREPLY=m
-CONFIG_BRIDGE_EBT_SNAT=m
-CONFIG_BRIDGE_EBT_DNAT=m
-CONFIG_BRIDGE_EBT_REDIRECT=m
-CONFIG_BRIDGE_EBT_MARK_T=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-CONFIG_IDEDISK_STROKE=y
-# CONFIG_BLK_DEV_IDECS is not set
-# CONFIG_BLK_DEV_DELKIN is not set
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
-CONFIG_BLK_DEV_IDESCSI=y
-CONFIG_IDE_TASK_IOCTL=y
-CONFIG_BLK_DEV_CMD640=y
-CONFIG_BLK_DEV_CMD640_ENHANCED=y
-# CONFIG_BLK_DEV_ISAPNP is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_OFFBOARD=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA100=y
-CONFIG_BLK_DEV_AEC62XX=y
-CONFIG_BLK_DEV_ALI15X3=y
-CONFIG_WDC_ALI15X3=y
-CONFIG_BLK_DEV_AMD74XX=y
-CONFIG_AMD74XX_OVERRIDE=y
-# CONFIG_BLK_DEV_ATIIXP is not set
-CONFIG_BLK_DEV_CMD64X=y
-CONFIG_BLK_DEV_TRIFLEX=y
-CONFIG_BLK_DEV_CY82C693=y
-CONFIG_BLK_DEV_CS5530=y
-CONFIG_BLK_DEV_HPT34X=y
-# CONFIG_HPT34X_AUTODMA is not set
-CONFIG_BLK_DEV_HPT366=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_NS87415=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_PDC202XX_OLD=y
-CONFIG_PDC202XX_BURST=y
-CONFIG_BLK_DEV_PDC202XX_NEW=y
-CONFIG_PDC202XX_FORCE=y
-CONFIG_BLK_DEV_RZ1000=y
-CONFIG_BLK_DEV_SC1200=y
-CONFIG_BLK_DEV_SVWKS=y
-CONFIG_BLK_DEV_SIIMAGE=y
-CONFIG_BLK_DEV_SIS5513=y
-CONFIG_BLK_DEV_SLC90E66=y
-CONFIG_BLK_DEV_TRM290=y
-CONFIG_BLK_DEV_VIA82CXXX=y
-CONFIG_IDE_CHIPSETS=y
-# CONFIG_BLK_DEV_4DRIVES is not set
-# CONFIG_BLK_DEV_ALI14XX is not set
-# CONFIG_BLK_DEV_DTC2278 is not set
-# CONFIG_BLK_DEV_HT6560B is not set
-# CONFIG_BLK_DEV_PDC4030 is not set
-# CONFIG_BLK_DEV_QD65XX is not set
-# CONFIG_BLK_DEV_UMC8672 is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_DMA_NONPCI is not set
-CONFIG_BLK_DEV_PDC202XX=y
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
-# CONFIG_BLK_DEV_ATARAID_SII is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-CONFIG_CHR_DEV_SG=y
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-CONFIG_SCSI_AACRAID=y
-CONFIG_SCSI_AIC7XXX=y
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
-# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
-CONFIG_AIC7XXX_DEBUG_MASK=0
-# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
-CONFIG_SCSI_AIC79XX=y
-CONFIG_AIC79XX_CMDS_PER_DEVICE=32
-CONFIG_AIC79XX_RESET_DELAY_MS=15000
-# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
-# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
-# CONFIG_AIC79XX_DEBUG_ENABLE is not set
-CONFIG_AIC79XX_DEBUG_MASK=0
-# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-CONFIG_SCSI_MEGARAID=y
-# CONFIG_SCSI_MEGARAID2 is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-CONFIG_SCSI_ATA_PIIX=y
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-CONFIG_SCSI_SATA_PROMISE=y
-CONFIG_SCSI_SATA_SX4=y
-CONFIG_SCSI_SATA_SIL=y
-CONFIG_SCSI_SATA_SIS=y
-# CONFIG_SCSI_SATA_ULI is not set
-CONFIG_SCSI_SATA_VIA=y
-CONFIG_SCSI_SATA_VITESSE=y
-CONFIG_SCSI_BUSLOGIC=y
-# CONFIG_SCSI_OMIT_FLASHPOINT is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx 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_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_BOOT is not set
-# CONFIG_FUSION_ISENSE is not set
-# CONFIG_FUSION_CTL is not set
-# CONFIG_FUSION_LAN is not set
-
-#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_SUNLANCE is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-CONFIG_NET_VENDOR_3COM=y
-# CONFIG_EL1 is not set
-# CONFIG_EL2 is not set
-# CONFIG_ELPLUS is not set
-# CONFIG_EL16 is not set
-# CONFIG_EL3 is not set
-# CONFIG_3C515 is not set
-# CONFIG_ELMC is not set
-# CONFIG_ELMC_II is not set
-CONFIG_VORTEX=y
-# CONFIG_TYPHOON is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_TULIP is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_DGRS is not set
-# CONFIG_DM9102 is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_EEPRO100_PIO is not set
-CONFIG_E100=y
-# CONFIG_LNE390 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-CONFIG_NE2K_PCI=y
-# CONFIG_FORCEDETH is not set
-# CONFIG_NE3210 is not set
-# CONFIG_ES3210 is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNDANCE_MMIO is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_RHINE_MMIO is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_NET_POCKET 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_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-CONFIG_TIGON3=y
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200 is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_RNG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-
-#
-# Direct Rendering Manager (XFree86 DRI support)
-#
-# CONFIG_DRM is not set
-# CONFIG_MWAVE is not set
-# CONFIG_OBMOUSE is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW 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_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_UMSDOS_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-CONFIG_ZISOFS_FS=y
-
-#
-# 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 is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8559-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Console drivers
-#
-CONFIG_XEN_CONSOLE=y
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_VIDEO_SELECT is not set
-# CONFIG_MDA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-# CONFIG_FB is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# Support for USB gadgets
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BLUEZ is not set
-
-#
-# Kernel hacking
-#
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_HIGHMEM is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_IOVIRT is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_KALLSYMS=y
-# CONFIG_FRAME_POINTER is not set
-CONFIG_LOG_BUF_SHIFT=0
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-# CONFIG_FW_LOADER is not set
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/defconfig-xenU
--- a/linux-2.4-xen-sparse/arch/xen/defconfig-xenU      Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,562 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_XEN=y
-CONFIG_X86=y
-CONFIG_ISA=y
-# CONFIG_SBUS is not set
-CONFIG_UID16=y
-
-#
-# Xen
-#
-# CONFIG_XEN_PRIVILEGED_GUEST is not set
-# CONFIG_XEN_PHYSDEV_ACCESS is not set
-CONFIG_XEN_SCRUB_PAGES=y
-CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_BLKDEV_GRANT=y
-# CONFIG_XEN_USB_FRONTEND is not set
-CONFIG_NO_IDLE_HZ=y
-# CONFIG_FOREIGN_PAGES is not set
-CONFIG_NETDEVICES=y
-# CONFIG_VT is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
-# Processor type and features
-#
-CONFIG_M686=y
-# CONFIG_MPENTIUMIII is not set
-# CONFIG_MPENTIUM4 is not set
-# CONFIG_MK7 is not set
-# CONFIG_MK8 is not set
-# CONFIG_MVIAC3_2 is not set
-CONFIG_X86_WP_WORKS_OK=y
-CONFIG_X86_INVLPG=y
-CONFIG_X86_CMPXCHG=y
-CONFIG_X86_XADD=y
-CONFIG_X86_BSWAP=y
-CONFIG_X86_POPAD_OK=y
-# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_X86_GOOD_APIC=y
-CONFIG_X86_PGE=y
-CONFIG_X86_USE_PPRO_CHECKSUM=y
-CONFIG_X86_TSC=y
-CONFIG_X86_L1_CACHE_SHIFT=5
-CONFIG_NOHIGHMEM=y
-# CONFIG_HIGHMEM4G is not set
-CONFIG_FORCE_MAX_ZONEORDER=11
-
-#
-# General setup
-#
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_OOM_KILLER is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-#   IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=y
-CONFIG_IP_NF_FTP=y
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_TFTP=y
-CONFIG_IP_NF_IRC=y
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=y
-# CONFIG_IP_NF_MATCH_LIMIT is not set
-# CONFIG_IP_NF_MATCH_MAC is not set
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-# CONFIG_IP_NF_MATCH_MARK is not set
-# CONFIG_IP_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP_NF_MATCH_TOS is not set
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-# CONFIG_IP_NF_MATCH_AH_ESP is not set
-# CONFIG_IP_NF_MATCH_LENGTH is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=y
-CONFIG_IP_NF_MATCH_CONNTRACK=y
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=y
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=y
-CONFIG_IP_NF_NAT_FTP=y
-CONFIG_IP_NF_NAT_TFTP=y
-# CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_IP_NF_TARGET_ULOG=y
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-#   IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-
-#
-#    SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_VLAN_8021Q=y
-
-#
-#  
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_MEGARAID2 is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_STATS is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
-# CONFIG_TIPAR is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-# CONFIG_INPUT_SERIO is not set
-# CONFIG_INPUT_SERPORT is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200 is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_RNG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-
-#
-# Direct Rendering Manager (XFree86 DRI support)
-#
-# CONFIG_DRM is not set
-# CONFIG_MWAVE is not set
-# CONFIG_OBMOUSE is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW 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_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_UMSDOS_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-CONFIG_ZISOFS_FS=y
-
-#
-# 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 is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8559-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Console drivers
-#
-CONFIG_XEN_CONSOLE=y
-
-#
-# Kernel hacking
-#
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_HIGHMEM is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_IOVIRT is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_KALLSYMS=y
-# CONFIG_FRAME_POINTER is not set
-CONFIG_LOG_BUF_SHIFT=0
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-# CONFIG_ZLIB_DEFLATE is not set
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/balloon/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/balloon/Makefile    Sat Oct  8 
17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,4 +0,0 @@
-O_TARGET := drv.o
-export-objs := balloon.o
-obj-y := balloon.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/blkif/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/blkif/Makefile      Sat Oct  8 
17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,10 +0,0 @@
-
-O_TARGET := drv.o
-
-subdir-$(CONFIG_XEN_BLKDEV_FRONTEND) += frontend
-obj-$(CONFIG_XEN_BLKDEV_FRONTEND)    += frontend/drv.o
-
-subdir-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend
-obj-$(CONFIG_XEN_PHYSDEV_ACCESS)    += backend/drv.o
-
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/blkif/backend/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/blkif/backend/Makefile      Sat Oct 
 8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,3 +0,0 @@
-O_TARGET := drv.o
-obj-y := main.o control.o interface.o vbd.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile     Sat Oct 
 8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,3 +0,0 @@
-O_TARGET := drv.o
-obj-y := blkfront.o vbd.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/common.h
--- a/linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/common.h     Sat Oct 
 8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,93 +0,0 @@
-/******************************************************************************
- * arch/xen/drivers/blkif/frontend/common.h
- * 
- * Shared definitions between all levels of XenoLinux Virtual block devices.
- */
-
-#ifndef __XEN_DRIVERS_COMMON_H__
-#define __XEN_DRIVERS_COMMON_H__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/hdreg.h>
-#include <linux/blkdev.h>
-#include <linux/major.h>
-#include <asm-xen/xen-public/xen.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <asm/uaccess.h>
-#include <asm-xen/xen-public/io/blkif.h>
-
-#if 1
-#define IPRINTK(fmt, args...) \
-    printk(KERN_INFO "xen_blk: " fmt, ##args)
-#else
-#define IPRINTK(fmt, args...) ((void)0)
-#endif
-
-#if 1
-#define WPRINTK(fmt, args...) \
-    printk(KERN_WARNING "xen_blk: " fmt, ##args)
-#else
-#define WPRINTK(fmt, args...) ((void)0)
-#endif
-
-#if 0
-#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a )
-#else
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
-
-#if 0
-#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
-#else
-#define DPRINTK_IOCTL(_f, _a...) ((void)0)
-#endif
-
-/* Private gendisk->flags[] values. */
-#define GENHD_FL_XEN        2 /* Is unit a Xen block device?  */
-#define GENHD_FL_VIRT_PARTNS 4 /* Are unit partitions virtual? */
-
-/*
- * We have one of these per vbd, whether ide, scsi or 'other'.
- * They hang in an array off the gendisk structure. We may end up putting
- * all kinds of interesting stuff here :-)
- */
-typedef struct xl_disk {
-    int usage;
-} xl_disk_t;
-
-extern int blkif_open(struct inode *inode, struct file *filep);
-extern int blkif_release(struct inode *inode, struct file *filep);
-extern int blkif_ioctl(struct inode *inode, struct file *filep,
-                                 unsigned command, unsigned long argument);
-extern int blkif_check(kdev_t dev);
-extern int blkif_revalidate(kdev_t dev);
-extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
-extern void do_blkif_request (request_queue_t *rq); 
-
-extern void xlvbd_update_vbds(void);
-
-static inline xl_disk_t *xldev_to_xldisk(kdev_t xldev)
-{
-    struct gendisk *gd = get_gendisk(xldev);
-    
-    if ( gd == NULL ) 
-        return NULL;
-    
-    return (xl_disk_t *)gd->real_devices + 
-        (MINOR(xldev) >> gd->minor_shift);
-}
-
-
-/* Virtual block-device subsystem. */
-extern int  xlvbd_init(void);
-extern void xlvbd_cleanup(void); 
-
-#endif /* __XEN_DRIVERS_COMMON_H__ */
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c
--- a/linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c        Sat Oct 
 8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,540 +0,0 @@
-/******************************************************************************
- * arch/xen/drivers/blkif/frontend/vbd.c
- * 
- * Xenolinux virtual block-device driver.
- * 
- * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
- * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
- */
-
-#include "common.h"
-#include <linux/blk.h>
-
-/*
- * For convenience we distinguish between ide, scsi and 'other' (i.e.
- * potentially combinations of the two) in the naming scheme and in a few 
- * other places (like default readahead, etc).
- */
-#define XLIDE_MAJOR_NAME  "hd"
-#define XLSCSI_MAJOR_NAME "sd"
-#define XLVBD_MAJOR_NAME "xvd"
-
-#define XLIDE_DEVS_PER_MAJOR   2
-#define XLSCSI_DEVS_PER_MAJOR 16
-#define XLVBD_DEVS_PER_MAJOR  16
-
-#define XLIDE_PARTN_SHIFT  6    /* amount to shift minor to get 'real' minor */
-#define XLIDE_MAX_PART    (1 << XLIDE_PARTN_SHIFT)     /* minors per ide vbd */
-
-#define XLSCSI_PARTN_SHIFT 4    /* amount to shift minor to get 'real' minor */
-#define XLSCSI_MAX_PART   (1 << XLSCSI_PARTN_SHIFT)   /* minors per scsi vbd */
-
-#define XLVBD_PARTN_SHIFT  4    /* amount to shift minor to get 'real' minor */
-#define XLVBD_MAX_PART    (1 << XLVBD_PARTN_SHIFT) /* minors per 'other' vbd */
-
-/* The below are for the generic drivers/block/ll_rw_block.c code. */
-static int xlide_blksize_size[256];
-static int xlide_hardsect_size[256];
-static int xlide_max_sectors[256];
-static int xlscsi_blksize_size[256];
-static int xlscsi_hardsect_size[256];
-static int xlscsi_max_sectors[256];
-static int xlvbd_blksize_size[256];
-static int xlvbd_hardsect_size[256];
-static int xlvbd_max_sectors[256];
-
-/* Information about our VBDs. */
-#define MAX_VBDS 64
-static int nr_vbds;
-static vdisk_t *vbd_info;
-
-static struct block_device_operations xlvbd_block_fops = 
-{
-    open:               blkif_open,
-    release:            blkif_release,
-    ioctl:              blkif_ioctl,
-    check_media_change: blkif_check,
-    revalidate:         blkif_revalidate,
-};
-
-static int xlvbd_get_vbd_info(vdisk_t *disk_info)
-{
-    vdisk_t         *buf = (vdisk_t *)__get_free_page(GFP_KERNEL);
-    blkif_request_t  req;
-    blkif_response_t rsp;
-    int              nr;
-
-    memset(&req, 0, sizeof(req));
-    req.operation   = BLKIF_OP_PROBE;
-    req.nr_segments = 1;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    blkif_control_probe_send(&req, &rsp,
-                             (unsigned long)(virt_to_machine(buf)));
-#else
-    req.frame_and_sects[0] = virt_to_machine(buf) | 7;
-
-    blkif_control_send(&req, &rsp);
-#endif
-
-    if ( rsp.status <= 0 )
-    {
-        printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status);
-        return -1;
-    }
-
-    if ( (nr = rsp.status) > MAX_VBDS )
-         nr = MAX_VBDS;
-    memcpy(disk_info, buf, nr * sizeof(vdisk_t));
-
-    return nr;
-}
-
-/*
- * xlvbd_init_device - initialise a VBD device
- * @disk:              a vdisk_t describing the VBD
- *
- * Takes a vdisk_t * that describes a VBD the domain has access to.
- * Performs appropriate initialisation and registration of the device.
- *
- * Care needs to be taken when making re-entrant calls to ensure that
- * corruption does not occur.  Also, devices that are in use should not have
- * their details updated.  This is the caller's responsibility.
- */
-static int xlvbd_init_device(vdisk_t *xd)
-{
-    int device = xd->device;
-    int major  = MAJOR(device); 
-    int minor  = MINOR(device);
-    int is_ide = IDE_DISK_MAJOR(major);  /* is this an ide device? */
-    int is_scsi= SCSI_BLK_MAJOR(major);  /* is this a scsi device? */
-    char *major_name;
-    struct gendisk *gd;
-    struct block_device *bd;
-    xl_disk_t *disk;
-    int i, rc = 0, max_part, partno;
-    unsigned long capacity;
-
-    unsigned char buf[64];
-
-    if ( (bd = bdget(device)) == NULL )
-        return -1;
-
-    if ( ((disk = xldev_to_xldisk(device)) != NULL) && (disk->usage != 0) )
-    {
-        printk(KERN_ALERT "VBD update failed - in use [dev=%x]\n", device);
-        rc = -1;
-        goto out;
-    }
-
-    if ( is_ide ) {
-
-       major_name = XLIDE_MAJOR_NAME; 
-       max_part   = XLIDE_MAX_PART;
-
-    } else if ( is_scsi ) {
-
-       major_name = XLSCSI_MAJOR_NAME;
-       max_part   = XLSCSI_MAX_PART;
-
-    } else { 
-
-        /* SMH: hmm - probably a CCISS driver or sim; assume CCISS for now */
-       printk(KERN_ALERT "Assuming device %02x:%02x is CCISS/SCSI\n", 
-              major, minor);
-       is_scsi    = 1; 
-       major_name = "cciss"; 
-       max_part   = XLSCSI_MAX_PART;
-
-    }
-    
-    partno = minor & (max_part - 1); 
-    
-    if ( (gd = get_gendisk(device)) == NULL )
-    {
-        rc = register_blkdev(major, major_name, &xlvbd_block_fops);
-        if ( rc < 0 )
-        {
-            printk(KERN_ALERT "XL VBD: can't get major %d\n", major);
-            goto out;
-        }
-
-        if ( is_ide )
-        { 
-            blksize_size[major]  = xlide_blksize_size;
-            hardsect_size[major] = xlide_hardsect_size;
-            max_sectors[major]   = xlide_max_sectors;
-            read_ahead[major]    = 8;
-        } 
-        else if ( is_scsi )
-        { 
-            blksize_size[major]  = xlscsi_blksize_size;
-            hardsect_size[major] = xlscsi_hardsect_size;
-            max_sectors[major]   = xlscsi_max_sectors;
-            read_ahead[major]    = 8;
-        }
-        else
-        { 
-            blksize_size[major]  = xlvbd_blksize_size;
-            hardsect_size[major] = xlvbd_hardsect_size;
-            max_sectors[major]   = xlvbd_max_sectors;
-            read_ahead[major]    = 8;
-        }
-
-        blk_init_queue(BLK_DEFAULT_QUEUE(major), do_blkif_request);
-
-        /*
-         * Turn off barking 'headactive' mode. We dequeue buffer heads as
-         * soon as we pass them to the back-end driver.
-         */
-        blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);
-
-        /* Construct an appropriate gendisk structure. */
-        gd             = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
-        gd->major      = major;
-        gd->major_name = major_name; 
-    
-        gd->max_p      = max_part; 
-        if ( is_ide )
-        { 
-            gd->minor_shift  = XLIDE_PARTN_SHIFT; 
-            gd->nr_real      = XLIDE_DEVS_PER_MAJOR; 
-        } 
-        else if ( is_scsi )
-        { 
-            gd->minor_shift  = XLSCSI_PARTN_SHIFT; 
-            gd->nr_real      = XLSCSI_DEVS_PER_MAJOR; 
-        }
-        else
-        { 
-            gd->minor_shift  = XLVBD_PARTN_SHIFT; 
-            gd->nr_real      = XLVBD_DEVS_PER_MAJOR; 
-        }
-
-        /* 
-        ** The sizes[] and part[] arrays hold the sizes and other 
-        ** information about every partition with this 'major' (i.e. 
-        ** every disk sharing the 8 bit prefix * max partns per disk) 
-        */
-        gd->sizes = kmalloc(max_part*gd->nr_real*sizeof(int), GFP_KERNEL);
-        gd->part  = kmalloc(max_part*gd->nr_real*sizeof(struct hd_struct), 
-                            GFP_KERNEL);
-        memset(gd->sizes, 0, max_part * gd->nr_real * sizeof(int));
-        memset(gd->part,  0, max_part * gd->nr_real 
-               * sizeof(struct hd_struct));
-
-
-        gd->real_devices = kmalloc(gd->nr_real * sizeof(xl_disk_t), 
-                                   GFP_KERNEL);
-        memset(gd->real_devices, 0, gd->nr_real * sizeof(xl_disk_t));
-
-        gd->next   = NULL;            
-        gd->fops   = &xlvbd_block_fops;
-
-        gd->de_arr = kmalloc(gd->nr_real * sizeof(*gd->de_arr), 
-                             GFP_KERNEL);
-        gd->flags  = kmalloc(gd->nr_real * sizeof(*gd->flags), GFP_KERNEL);
-    
-        memset(gd->de_arr, 0, gd->nr_real * sizeof(*gd->de_arr));
-        memset(gd->flags, 0, gd->nr_real *  sizeof(*gd->flags));
-
-        add_gendisk(gd);
-
-        blk_size[major] = gd->sizes;
-    }
-
-    if ( xd->info & VDISK_READONLY )
-        set_device_ro(device, 1);
-
-    gd->flags[minor >> gd->minor_shift] |= GENHD_FL_XEN;
-
-    /* NB. Linux 2.4 only handles 32-bit sector offsets and capacities. */
-    capacity = (unsigned long)xd->capacity;
-
-    if ( partno != 0 )
-    {
-        /*
-         * If this was previously set up as a real disc we will have set 
-         * up partition-table information. Virtual partitions override 
-         * 'real' partitions, and the two cannot coexist on a device.
-         */
-        if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) &&
-             (gd->sizes[minor & ~(max_part-1)] != 0) )
-        {
-            /*
-             * Any non-zero sub-partition entries must be cleaned out before
-             * installing 'virtual' partition entries. The two types cannot
-             * coexist, and virtual partitions are favoured.
-             */
-            kdev_t dev = device & ~(max_part-1);
-            for ( i = max_part - 1; i > 0; i-- )
-            {
-                invalidate_device(dev+i, 1);
-                gd->part[MINOR(dev+i)].start_sect = 0;
-                gd->part[MINOR(dev+i)].nr_sects   = 0;
-                gd->sizes[MINOR(dev+i)]           = 0;
-            }
-            printk(KERN_ALERT
-                   "Virtual partitions found for /dev/%s - ignoring any "
-                   "real partition information we may have found.\n",
-                   disk_name(gd, MINOR(device), buf));
-        }
-
-        /* Need to skankily setup 'partition' information */
-        gd->part[minor].start_sect = 0; 
-        gd->part[minor].nr_sects   = capacity; 
-        gd->sizes[minor]           = capacity >>(BLOCK_SIZE_BITS-9); 
-
-        gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS;
-    }
-    else
-    {
-        gd->part[minor].nr_sects = capacity;
-        gd->sizes[minor] = capacity>>(BLOCK_SIZE_BITS-9);
-        
-        /* Some final fix-ups depending on the device type */
-        if ( xd->info & VDISK_REMOVABLE )
-        { 
-            gd->flags[minor >> gd->minor_shift] |= GENHD_FL_REMOVABLE; 
-            printk(KERN_ALERT 
-                   "Skipping partition check on %s /dev/%s\n", 
-                   (xd->info & VDISK_CDROM) ? "cdrom" : "removable",
-                   disk_name(gd, MINOR(device), buf)); 
-        }
-        else
-        {
-            /* Only check partitions on real discs (not virtual!). */
-            if ( gd->flags[minor>>gd->minor_shift] & GENHD_FL_VIRT_PARTNS )
-            {
-                printk(KERN_ALERT
-                       "Skipping partition check on virtual /dev/%s\n",
-                       disk_name(gd, MINOR(device), buf));
-                break;
-            }
-            register_disk(gd, device, gd->max_p, &xlvbd_block_fops, capacity);
-        }
-    }
-
- out:
-    bdput(bd);    
-    return rc;
-}
-
-
-/*
- * xlvbd_remove_device - remove a device node if possible
- * @device:       numeric device ID
- *
- * Updates the gendisk structure and invalidates devices.
- *
- * This is OK for now but in future, should perhaps consider where this should
- * deallocate gendisks / unregister devices.
- */
-static int xlvbd_remove_device(int device)
-{
-    int i, rc = 0, minor = MINOR(device);
-    struct gendisk *gd;
-    struct block_device *bd;
-    xl_disk_t *disk = NULL;
-
-    if ( (bd = bdget(device)) == NULL )
-        return -1;
-
-    if ( ((gd = get_gendisk(device)) == NULL) ||
-         ((disk = xldev_to_xldisk(device)) == NULL) )
-        BUG();
-
-    if ( disk->usage != 0 )
-    {
-        printk(KERN_ALERT "VBD removal failed - in use [dev=%x]\n", device);
-        rc = -1;
-        goto out;
-    }
- 
-    if ( (minor & (gd->max_p-1)) != 0 )
-    {
-        /* 1: The VBD is mapped to a partition rather than a whole unit. */
-        invalidate_device(device, 1);
-       gd->part[minor].start_sect = 0;
-        gd->part[minor].nr_sects   = 0;
-        gd->sizes[minor]           = 0;
-
-        /* Clear the consists-of-virtual-partitions flag if possible. */
-        gd->flags[minor >> gd->minor_shift] &= ~GENHD_FL_VIRT_PARTNS;
-        for ( i = 1; i < gd->max_p; i++ )
-            if ( gd->sizes[(minor & ~(gd->max_p-1)) + i] != 0 )
-                gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS;
-
-        /*
-         * If all virtual partitions are now gone, and a 'whole unit' VBD is
-         * present, then we can try to grok the unit's real partition table.
-         */
-        if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) &&
-             (gd->sizes[minor & ~(gd->max_p-1)] != 0) &&
-             !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE) )
-        {
-            register_disk(gd,
-                          device&~(gd->max_p-1), 
-                          gd->max_p, 
-                          &xlvbd_block_fops,
-                          gd->part[minor&~(gd->max_p-1)].nr_sects);
-        }
-    }
-    else
-    {
-        /*
-         * 2: The VBD is mapped to an entire 'unit'. Clear all partitions.
-         * NB. The partition entries are only cleared if there are no VBDs
-         * mapped to individual partitions on this unit.
-         */
-        i = gd->max_p - 1; /* Default: clear subpartitions as well. */
-        if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS )
-            i = 0; /* 'Virtual' mode: only clear the 'whole unit' entry. */
-        while ( i >= 0 )
-        {
-            invalidate_device(device+i, 1);
-            gd->part[minor+i].start_sect = 0;
-            gd->part[minor+i].nr_sects   = 0;
-            gd->sizes[minor+i]           = 0;
-            i--;
-        }
-    }
-
- out:
-    bdput(bd);
-    return rc;
-}
-
-/*
- * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
- * state. The VBDs need to be updated in this way when the domain is
- * initialised and also each time we receive an XLBLK_UPDATE event.
- */
-void xlvbd_update_vbds(void)
-{
-    int i, j, k, old_nr, new_nr;
-    vdisk_t *old_info, *new_info, *merged_info;
-
-    old_info = vbd_info;
-    old_nr   = nr_vbds;
-
-    new_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
-    if (!new_info)
-        return;
-
-    if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 )
-        goto out;
-
-    /*
-     * Final list maximum size is old list + new list. This occurs only when
-     * old list and new list do not overlap at all, and we cannot yet destroy
-     * VBDs in the old list because the usage counts are busy.
-     */
-    merged_info = kmalloc((old_nr + new_nr) * sizeof(vdisk_t), GFP_KERNEL);
-    if (!merged_info)
-        goto out;
-
-    /* @i tracks old list; @j tracks new list; @k tracks merged list. */
-    i = j = k = 0;
-
-    while ( (i < old_nr) && (j < new_nr) )
-    {
-        if ( old_info[i].device < new_info[j].device )
-        {
-            if ( xlvbd_remove_device(old_info[i].device) != 0 )
-                memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
-            i++;
-        }
-        else if ( old_info[i].device > new_info[j].device )
-        {
-            if ( xlvbd_init_device(&new_info[j]) == 0 )
-                memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
-            j++;
-        }
-        else
-        {
-            if ( ((old_info[i].capacity == new_info[j].capacity) &&
-                  (old_info[i].info == new_info[j].info)) ||
-                 (xlvbd_remove_device(old_info[i].device) != 0) )
-                memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
-            else if ( xlvbd_init_device(&new_info[j]) == 0 )
-                memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
-            i++; j++;
-        }
-    }
-
-    for ( ; i < old_nr; i++ )
-    {
-        if ( xlvbd_remove_device(old_info[i].device) != 0 )
-            memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
-    }
-
-    for ( ; j < new_nr; j++ )
-    {
-        if ( xlvbd_init_device(&new_info[j]) == 0 )
-            memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
-    }
-
-    vbd_info = merged_info;
-    nr_vbds  = k;
-
-    kfree(old_info);
-out:
-    kfree(new_info);
-}
-
-
-/*
- * Set up all the linux device goop for the virtual block devices (vbd's) that
- * we know about. Note that although from the backend driver's p.o.v. VBDs are
- * addressed simply an opaque 16-bit device number, the domain creation tools 
- * conventionally allocate these numbers to correspond to those used by 'real' 
- * linux -- this is just for convenience as it means e.g. that the same 
- * /etc/fstab can be used when booting with or without Xen.
- */
-int xlvbd_init(void)
-{
-    int i;
-    
-    /*
-     * If compiled as a module, we don't support unloading yet. We therefore 
-     * permanently increment the reference count to disallow it.
-     */
-    SET_MODULE_OWNER(&xlvbd_block_fops);
-    MOD_INC_USE_COUNT;
-
-    /* Initialize the global arrays. */
-    for ( i = 0; i < 256; i++ ) 
-    {
-        xlide_blksize_size[i]  = 1024;
-        xlide_hardsect_size[i] = 512;
-        xlide_max_sectors[i]   = 512;
-
-        xlscsi_blksize_size[i]  = 1024;
-        xlscsi_hardsect_size[i] = 512;
-        xlscsi_max_sectors[i]   = 512;
-
-        xlvbd_blksize_size[i]  = 512;
-        xlvbd_hardsect_size[i] = 512;
-        xlvbd_max_sectors[i]   = 512;
-    }
-
-    vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
-    if (!vbd_info)
-        return -ENOMEM;
-
-    nr_vbds  = xlvbd_get_vbd_info(vbd_info);
-
-    if ( nr_vbds < 0 )
-    {
-        kfree(vbd_info);
-        vbd_info = NULL;
-        nr_vbds  = 0;
-    }
-    else
-    {
-        for ( i = 0; i < nr_vbds; i++ )
-            xlvbd_init_device(&vbd_info[i]);
-    }
-
-    return 0;
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/console/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/console/Makefile    Sat Oct  8 
17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,3 +0,0 @@
-O_TARGET := drv.o
-obj-$(CONFIG_XEN_CONSOLE) := console.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/dom0/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/dom0/Makefile       Sat Oct  8 
17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,3 +0,0 @@
-O_TARGET := drv.o
-obj-y := core.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/evtchn/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/evtchn/Makefile     Sat Oct  8 
17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,3 +0,0 @@
-O_TARGET := drv.o
-obj-y := evtchn.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/netif/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/netif/Makefile      Sat Oct  8 
17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,10 +0,0 @@
-
-O_TARGET := drv.o
-
-subdir-$(CONFIG_XEN_NETDEV_FRONTEND) += frontend
-obj-$(CONFIG_XEN_NETDEV_FRONTEND)    += frontend/drv.o
-
-subdir-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend
-obj-$(CONFIG_XEN_PHYSDEV_ACCESS)    += backend/drv.o
-
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/netif/backend/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/netif/backend/Makefile      Sat Oct 
 8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,4 +0,0 @@
-O_TARGET := drv.o
-export-objs := interface.o
-obj-y := main.o control.o interface.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/drivers/netif/frontend/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/drivers/netif/frontend/Makefile     Sat Oct 
 8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,3 +0,0 @@
-O_TARGET := drv.o
-obj-y := main.o
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/kernel/Makefile     Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,20 +0,0 @@
-
-.S.o:
-       $(CC) $(AFLAGS) -traditional -c $< -o $*.o
-
-all: kernel.o head.o init_task.o
-
-O_TARGET := kernel.o
-
-export-objs     := i386_ksyms.o gnttab.o skbuff.o ctrl_if.o
-
-obj-y  := process.o semaphore.o signal.o entry.o traps.o irq.o  \
-               ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o \
-               i386_ksyms.o i387.o evtchn.o ctrl_if.o pci-dma.o \
-               reboot.o fixup.o gnttab.o skbuff.o
-
-ifdef CONFIG_PCI
-obj-y  += pci-i386.o pci-pc.o
-endif
-
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/entry.S
--- a/linux-2.4-xen-sparse/arch/xen/kernel/entry.S      Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,779 +0,0 @@
-/*
- *  linux/arch/i386/entry.S
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-/*
- * entry.S contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch.
- *
- * NOTE: This code handles signal-recognition, which happens every time
- * after a timer-interrupt and after each system call.
- *
- * I changed all the .align's to 4 (16 byte alignment), as that's faster
- * on a 486.
- *
- * Stack layout in 'ret_to_user':
- *     ptrace needs to have all regs on the stack.
- *     if the order here is changed, it needs to be
- *     updated in fork.c:copy_process, signal.c:do_signal,
- *     ptrace.c and ptrace.h
- *
- *      0(%esp) - %ebx
- *      4(%esp) - %ecx
- *      8(%esp) - %edx
- *       C(%esp) - %esi
- *     10(%esp) - %edi
- *     14(%esp) - %ebp
- *     18(%esp) - %eax
- *     1C(%esp) - %ds
- *     20(%esp) - %es
- *     24(%esp) - orig_eax
- *     28(%esp) - %eip
- *     2C(%esp) - %cs
- *     30(%esp) - %eflags
- *     34(%esp) - %oldesp
- *     38(%esp) - %oldss
- *
- * "current" is in register %ebx during any slow entries.
- */
-
-#include <linux/config.h>
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/segment.h>
-#include <asm/smp.h>
-
-EBX            = 0x00
-ECX            = 0x04
-EDX            = 0x08
-ESI            = 0x0C
-EDI            = 0x10
-EBP            = 0x14
-EAX            = 0x18
-DS             = 0x1C
-ES             = 0x20
-ORIG_EAX       = 0x24
-EIP            = 0x28
-CS             = 0x2C
-EFLAGS         = 0x30
-OLDESP         = 0x34
-OLDSS          = 0x38
-
-CF_MASK                = 0x00000001
-TF_MASK                = 0x00000100
-IF_MASK                = 0x00000200
-DF_MASK                = 0x00000400
-NT_MASK                = 0x00004000
-
-/* Offsets into task_struct. */
-state          =  0
-flags          =  4
-sigpending     =  8
-addr_limit     = 12
-exec_domain    = 16
-need_resched   = 20
-tsk_ptrace     = 24
-processor      = 52
-
-/* Offsets into shared_info_t. */
-#define evtchn_upcall_pending /* 0 */
-#define evtchn_upcall_mask       1
-
-ENOSYS = 38
-
-
-#define SAVE_ALL \
-       cld; \
-       pushl %es; \
-       pushl %ds; \
-       pushl %eax; \
-       pushl %ebp; \
-       pushl %edi; \
-       pushl %esi; \
-       pushl %edx; \
-       pushl %ecx; \
-       pushl %ebx; \
-       movl $(__KERNEL_DS),%edx; \
-       movl %edx,%ds; \
-       movl %edx,%es;
-
-#define RESTORE_ALL    \
-       popl %ebx;      \
-       popl %ecx;      \
-       popl %edx;      \
-       popl %esi;      \
-       popl %edi;      \
-       popl %ebp;      \
-       popl %eax;      \
-1:     popl %ds;       \
-2:     popl %es;       \
-       addl $4,%esp;   \
-3:     iret;           \
-.section .fixup,"ax";  \
-4:     movl $0,(%esp); \
-       jmp 1b;         \
-5:     movl $0,(%esp); \
-       jmp 2b;         \
-6:     pushl %ss;      \
-       popl %ds;       \
-       pushl %ss;      \
-       popl %es;       \
-       pushl $11;      \
-       call do_exit;   \
-.previous;             \
-.section __ex_table,"a";\
-       .align 4;       \
-       .long 1b,4b;    \
-       .long 2b,5b;    \
-       .long 3b,6b;    \
-.previous
-
-#define GET_CURRENT(reg) \
-       movl $-8192, reg; \
-       andl %esp, reg
-
-ENTRY(lcall7)
-       pushfl                  # We get a different stack layout with call
-       pushl %eax              # gates, which has to be cleaned up later..
-       SAVE_ALL
-       movl EIP(%esp),%eax     # due to call gates, this is eflags, not eip..
-       movl CS(%esp),%edx      # this is eip..
-       movl EFLAGS(%esp),%ecx  # and this is cs..
-       movl %eax,EFLAGS(%esp)  #
-       andl $~(NT_MASK|TF_MASK|DF_MASK), %eax
-       pushl %eax
-       popfl
-       movl %edx,EIP(%esp)     # Now we move them to their "normal" places
-       movl %ecx,CS(%esp)      #
-       movl %esp,%ebx
-       pushl %ebx
-       andl $-8192,%ebx        # GET_CURRENT
-       movl exec_domain(%ebx),%edx     # Get the execution domain
-       movl 4(%edx),%edx       # Get the lcall7 handler for the domain
-       pushl $0x7
-       call *%edx
-       addl $4, %esp
-       popl %eax
-       jmp ret_to_user
-
-ENTRY(lcall27)
-       pushfl                  # We get a different stack layout with call
-       pushl %eax              # gates, which has to be cleaned up later..
-       SAVE_ALL
-       movl EIP(%esp),%eax     # due to call gates, this is eflags, not eip..
-       movl CS(%esp),%edx      # this is eip..
-       movl EFLAGS(%esp),%ecx  # and this is cs..
-       movl %eax,EFLAGS(%esp)  #
-       andl $~(NT_MASK|TF_MASK|DF_MASK), %eax
-       pushl %eax
-       popfl
-       movl %edx,EIP(%esp)     # Now we move them to their "normal" places
-       movl %ecx,CS(%esp)      #
-       movl %esp,%ebx
-       pushl %ebx
-       andl $-8192,%ebx        # GET_CURRENT
-       movl exec_domain(%ebx),%edx     # Get the execution domain
-       movl 4(%edx),%edx       # Get the lcall7 handler for the domain
-       pushl $0x27
-       call *%edx
-       addl $4, %esp
-       popl %eax
-       jmp ret_to_user
-
-ENTRY(ret_from_fork)
-       pushl %ebx
-       call SYMBOL_NAME(schedule_tail)
-       addl $4, %esp
-       GET_CURRENT(%ebx)
-       testb $0x02,tsk_ptrace(%ebx)    # PT_TRACESYS
-       jne tracesys_exit
-       jmp ret_to_user
-
-/*
- * Return to user mode is not as complex as all this looks,
- * but we want the default path for a system call return to
- * go as quickly as possible which is why some of this is
- * less clear than it otherwise should be.
- */
-ENTRY(system_call)
-       pushl %eax                      # save orig_eax
-       SAVE_ALL
-       GET_CURRENT(%ebx)
-       testb $0x02,tsk_ptrace(%ebx)    # PT_TRACESYS
-       jne tracesys
-       cmpl $(NR_syscalls),%eax
-       jae badsys
-       call *SYMBOL_NAME(sys_call_table)(,%eax,4)
-       movl %eax,EAX(%esp)             # save the return value
-ret_to_user:
-        movl SYMBOL_NAME(HYPERVISOR_shared_info),%esi
-        movb $1,evtchn_upcall_mask(%esi) # make tests atomic
-ret_to_user_nocli:
-       cmpl $0,need_resched(%ebx)
-       jne  reschedule
-       cmpl $0,sigpending(%ebx)
-       je   safesti                    # ensure need_resched updates are seen
-/*signal_return:*/
-       movb $0,evtchn_upcall_mask(%esi) # reenable event callbacks
-       movl %esp,%eax
-       xorl %edx,%edx
-       call SYMBOL_NAME(do_signal)
-       jmp  safesti
-
-       ALIGN
-restore_all:
-       RESTORE_ALL
-
-       ALIGN
-tracesys:
-       movl $-ENOSYS,EAX(%esp)
-       call SYMBOL_NAME(syscall_trace)
-       movl ORIG_EAX(%esp),%eax
-       cmpl $(NR_syscalls),%eax
-       jae tracesys_exit
-       call *SYMBOL_NAME(sys_call_table)(,%eax,4)
-       movl %eax,EAX(%esp)             # save the return value
-tracesys_exit:
-       call SYMBOL_NAME(syscall_trace)
-       jmp ret_to_user
-badsys:
-       movl $-ENOSYS,EAX(%esp)
-       jmp ret_to_user
-
-       ALIGN
-ENTRY(ret_from_intr)
-       GET_CURRENT(%ebx)
-ret_from_exception:
-       movb CS(%esp),%al
-       testl $2,%eax
-       jne ret_to_user
-       jmp restore_all
-
-       ALIGN
-reschedule:
-        movb $0,evtchn_upcall_mask(%esi)  # reenable event callbacks
-       call SYMBOL_NAME(schedule)        # test
-       jmp  ret_to_user
-
-ENTRY(divide_error)
-       pushl $0                # no error code
-       pushl $ SYMBOL_NAME(do_divide_error)
-       ALIGN
-error_code:
-       pushl %ds
-       pushl %eax
-       xorl %eax,%eax
-       pushl %ebp
-       pushl %edi
-       pushl %esi
-       pushl %edx
-       decl %eax                       # eax = -1
-       pushl %ecx
-       pushl %ebx
-       GET_CURRENT(%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
-       jmp ret_from_exception
-
-# A note on the "critical region" in our callback handler.
-# We want to avoid stacking callback handlers due to events occurring
-# during handling of the last event. To do this, we keep events disabled
-# until we've done all processing. HOWEVER, we must enable events before
-# popping the stack frame (can't be done atomically) and so it would still
-# be possible to get enough handler activations to overflow the stack.
-# Although unlikely, bugs of that kind are hard to track down, so we'd
-# like to avoid the possibility.
-# So, on entry to the handler we detect whether we interrupted an
-# existing activation in its critical region -- if so, we pop the current
-# activation and restart the handler using the previous one.
-ENTRY(hypervisor_callback)
-        pushl %eax
-        SAVE_ALL
-        GET_CURRENT(%ebx)
-        movl EIP(%esp),%eax
-        cmpl $scrit,%eax
-        jb   11f
-        cmpl $ecrit,%eax
-        jb   critical_region_fixup
-11:     push %esp
-        call evtchn_do_upcall
-        add  $4,%esp
-        movl SYMBOL_NAME(HYPERVISOR_shared_info),%esi
-        movb CS(%esp),%cl
-       test $2,%cl          # slow return to ring 2 or 3
-       jne  ret_to_user_nocli
-safesti:movb $0,evtchn_upcall_mask(%esi) # reenable event callbacks
-scrit:  /**** START OF CRITICAL REGION ****/
-        testb $0xFF,evtchn_upcall_pending(%esi)
-        jnz  14f              # process more events if necessary...
-        RESTORE_ALL
-14:     movb $1,evtchn_upcall_mask(%esi)
-        jmp  11b
-ecrit:  /**** END OF CRITICAL REGION ****/
-# [How we do the fixup]. We want to merge the current stack frame with the
-# just-interrupted frame. How we do this depends on where in the critical
-# region the interrupted handler was executing, and so how many saved
-# registers are in each frame. We do this quickly using the lookup table
-# 'critical_fixup_table'. For each byte offset in the critical region, it
-# provides the number of bytes which have already been popped from the
-# interrupted stack frame. 
-critical_region_fixup:
-        addl $critical_fixup_table-scrit,%eax
-        movzbl (%eax),%eax    # %eax contains num bytes popped
-        mov  %esp,%esi
-        add  %eax,%esi        # %esi points at end of src region
-        mov  %esp,%edi
-        add  $0x34,%edi       # %edi points at end of dst region
-        mov  %eax,%ecx
-        shr  $2,%ecx          # convert words to bytes
-        je   16f              # skip loop if nothing to copy
-15:     subl $4,%esi          # pre-decrementing copy loop
-        subl $4,%edi
-        movl (%esi),%eax
-        movl %eax,(%edi)
-        loop 15b
-16:     movl %edi,%esp        # final %edi is top of merged stack
-        jmp  11b
-        
-critical_fixup_table:        
-        .byte 0x00,0x00,0x00                  # testb $0xFF,(%esi)
-        .byte 0x00,0x00                       # jnz  14f
-        .byte 0x00                            # pop  %ebx
-        .byte 0x04                            # pop  %ecx
-        .byte 0x08                            # pop  %edx
-        .byte 0x0c                            # pop  %esi
-        .byte 0x10                            # pop  %edi
-        .byte 0x14                            # pop  %ebp
-        .byte 0x18                            # pop  %eax
-        .byte 0x1c                            # pop  %ds
-        .byte 0x20                            # pop  %es
-        .byte 0x24,0x24,0x24                  # add  $4,%esp
-        .byte 0x28                            # iret
-        .byte 0x00,0x00,0x00,0x00             # movb $1,4(%esi)
-        .byte 0x00,0x00                       # jmp  11b
-
-# Hypervisor uses this for application faults while it executes.
-ENTRY(failsafe_callback)
-1:      popl %ds
-2:      popl %es
-3:      popl %fs
-4:      popl %gs
-5:      iret
-.section .fixup,"ax";  \
-6:     movl $0,(%esp); \
-       jmp 1b;         \
-7:     movl $0,(%esp); \
-       jmp 2b;         \
-8:     movl $0,(%esp); \
-       jmp 3b;         \
-9:     movl $0,(%esp); \
-       jmp 4b;         \
-10:    pushl %ss;      \
-       popl %ds;       \
-       pushl %ss;      \
-       popl %es;       \
-       pushl $11;      \
-       call do_exit;   \
-.previous;             \
-.section __ex_table,"a";\
-       .align 4;       \
-       .long 1b,6b;    \
-       .long 2b,7b;    \
-       .long 3b,8b;    \
-       .long 4b,9b;    \
-       .long 5b,10b;   \
-.previous
-        
-ENTRY(coprocessor_error)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_coprocessor_error)
-       jmp error_code
-
-ENTRY(simd_coprocessor_error)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_simd_coprocessor_error)
-       jmp error_code
-
-ENTRY(device_not_available)
-       pushl $-1               # mark this as an int
-       SAVE_ALL
-       GET_CURRENT(%ebx)
-       call SYMBOL_NAME(math_state_restore)
-       jmp ret_from_exception
-
-ENTRY(debug)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_debug)
-       jmp error_code
-
-ENTRY(int3)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_int3)
-       jmp error_code
-
-ENTRY(overflow)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_overflow)
-       jmp error_code
-
-ENTRY(bounds)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_bounds)
-       jmp error_code
-
-ENTRY(invalid_op)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_invalid_op)
-       jmp error_code
-
-ENTRY(coprocessor_segment_overrun)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun)
-       jmp error_code
-
-ENTRY(double_fault)
-       pushl $ SYMBOL_NAME(do_double_fault)
-       jmp error_code
-
-ENTRY(invalid_TSS)
-       pushl $ SYMBOL_NAME(do_invalid_TSS)
-       jmp error_code
-
-ENTRY(segment_not_present)
-       pushl $ SYMBOL_NAME(do_segment_not_present)
-       jmp error_code
-
-ENTRY(stack_segment)
-       pushl $ SYMBOL_NAME(do_stack_segment)
-       jmp error_code
-
-ENTRY(general_protection)
-       pushl $ SYMBOL_NAME(do_general_protection)
-       jmp error_code
-
-ENTRY(alignment_check)
-       pushl $ SYMBOL_NAME(do_alignment_check)
-       jmp error_code
-
-# This handler is special, because it gets an extra value on its stack,
-# which is the linear faulting address.
-#define PAGE_FAULT_STUB(_name1, _name2)                                  \
-ENTRY(_name1)                                                            \
-       pushl %ds                                                      ; \
-       pushl %eax                                                     ; \
-       xorl %eax,%eax                                                 ; \
-       pushl %ebp                                                     ; \
-       pushl %edi                                                     ; \
-       pushl %esi                                                     ; \
-       pushl %edx                                                     ; \
-       decl %eax                      /* eax = -1 */                  ; \
-       pushl %ecx                                                     ; \
-       pushl %ebx                                                     ; \
-       GET_CURRENT(%ebx)                                              ; \
-       cld                                                            ; \
-       movl %es,%ecx                                                  ; \
-       movl ORIG_EAX(%esp), %esi      /* get the error code */        ; \
-       movl ES(%esp), %edi            /* get the faulting address */  ; \
-       movl %eax, ORIG_EAX(%esp)                                      ; \
-       movl %ecx, ES(%esp)                                            ; \
-       movl %esp,%edx                                                 ; \
-        pushl %edi                     /* push the faulting address */ ; \
-       pushl %esi                     /* push the error code */       ; \
-       pushl %edx                     /* push the pt_regs pointer */  ; \
-       movl $(__KERNEL_DS),%edx                                       ; \
-       movl %edx,%ds                                                  ; \
-       movl %edx,%es                                                  ; \
-       call SYMBOL_NAME(_name2)                                       ; \
-       addl $12,%esp                                                  ; \
-       jmp ret_from_exception                                         ;
-PAGE_FAULT_STUB(page_fault, do_page_fault)
-
-ENTRY(machine_check)
-       pushl $0
-       pushl $ SYMBOL_NAME(do_machine_check)
-       jmp error_code
-
-ENTRY(fixup_4gb_segment)
-       pushl $ SYMBOL_NAME(do_fixup_4gb_segment)
-       jmp error_code
-
-.data
-ENTRY(sys_call_table)
-       .long SYMBOL_NAME(sys_ni_syscall)       /* 0  -  old "setup()" system 
call*/
-       .long SYMBOL_NAME(sys_exit)
-       .long SYMBOL_NAME(sys_fork)
-       .long SYMBOL_NAME(sys_read)
-       .long SYMBOL_NAME(sys_write)
-       .long SYMBOL_NAME(sys_open)             /* 5 */
-       .long SYMBOL_NAME(sys_close)
-       .long SYMBOL_NAME(sys_waitpid)
-       .long SYMBOL_NAME(sys_creat)
-       .long SYMBOL_NAME(sys_link)
-       .long SYMBOL_NAME(sys_unlink)           /* 10 */
-       .long SYMBOL_NAME(sys_execve)
-       .long SYMBOL_NAME(sys_chdir)
-       .long SYMBOL_NAME(sys_time)
-       .long SYMBOL_NAME(sys_mknod)
-       .long SYMBOL_NAME(sys_chmod)            /* 15 */
-       .long SYMBOL_NAME(sys_lchown16)
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
break syscall holder */
-       .long SYMBOL_NAME(sys_stat)
-       .long SYMBOL_NAME(sys_lseek)
-       .long SYMBOL_NAME(sys_getpid)           /* 20 */
-       .long SYMBOL_NAME(sys_mount)
-       .long SYMBOL_NAME(sys_oldumount)
-       .long SYMBOL_NAME(sys_setuid16)
-       .long SYMBOL_NAME(sys_getuid16)
-       .long SYMBOL_NAME(sys_stime)            /* 25 */
-       .long SYMBOL_NAME(sys_ptrace)
-       .long SYMBOL_NAME(sys_alarm)
-       .long SYMBOL_NAME(sys_fstat)
-       .long SYMBOL_NAME(sys_pause)
-       .long SYMBOL_NAME(sys_utime)            /* 30 */
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
stty syscall holder */
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
gtty syscall holder */
-       .long SYMBOL_NAME(sys_access)
-       .long SYMBOL_NAME(sys_nice)
-       .long SYMBOL_NAME(sys_ni_syscall)       /* 35 */                /* old 
ftime syscall holder */
-       .long SYMBOL_NAME(sys_sync)
-       .long SYMBOL_NAME(sys_kill)
-       .long SYMBOL_NAME(sys_rename)
-       .long SYMBOL_NAME(sys_mkdir)
-       .long SYMBOL_NAME(sys_rmdir)            /* 40 */
-       .long SYMBOL_NAME(sys_dup)
-       .long SYMBOL_NAME(sys_pipe)
-       .long SYMBOL_NAME(sys_times)
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
prof syscall holder */
-       .long SYMBOL_NAME(sys_brk)              /* 45 */
-       .long SYMBOL_NAME(sys_setgid16)
-       .long SYMBOL_NAME(sys_getgid16)
-       .long SYMBOL_NAME(sys_signal)
-       .long SYMBOL_NAME(sys_geteuid16)
-       .long SYMBOL_NAME(sys_getegid16)        /* 50 */
-       .long SYMBOL_NAME(sys_acct)
-       .long SYMBOL_NAME(sys_umount)                                   /* 
recycled never used phys() */
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
lock syscall holder */
-       .long SYMBOL_NAME(sys_ioctl)
-       .long SYMBOL_NAME(sys_fcntl)            /* 55 */
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
mpx syscall holder */
-       .long SYMBOL_NAME(sys_setpgid)
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
ulimit syscall holder */
-       .long SYMBOL_NAME(sys_olduname)
-       .long SYMBOL_NAME(sys_umask)            /* 60 */
-       .long SYMBOL_NAME(sys_chroot)
-       .long SYMBOL_NAME(sys_ustat)
-       .long SYMBOL_NAME(sys_dup2)
-       .long SYMBOL_NAME(sys_getppid)
-       .long SYMBOL_NAME(sys_getpgrp)          /* 65 */
-       .long SYMBOL_NAME(sys_setsid)
-       .long SYMBOL_NAME(sys_sigaction)
-       .long SYMBOL_NAME(sys_sgetmask)
-       .long SYMBOL_NAME(sys_ssetmask)
-       .long SYMBOL_NAME(sys_setreuid16)       /* 70 */
-       .long SYMBOL_NAME(sys_setregid16)
-       .long SYMBOL_NAME(sys_sigsuspend)
-       .long SYMBOL_NAME(sys_sigpending)
-       .long SYMBOL_NAME(sys_sethostname)
-       .long SYMBOL_NAME(sys_setrlimit)        /* 75 */
-       .long SYMBOL_NAME(sys_old_getrlimit)
-       .long SYMBOL_NAME(sys_getrusage)
-       .long SYMBOL_NAME(sys_gettimeofday)
-       .long SYMBOL_NAME(sys_settimeofday)
-       .long SYMBOL_NAME(sys_getgroups16)      /* 80 */
-       .long SYMBOL_NAME(sys_setgroups16)
-       .long SYMBOL_NAME(old_select)
-       .long SYMBOL_NAME(sys_symlink)
-       .long SYMBOL_NAME(sys_lstat)
-       .long SYMBOL_NAME(sys_readlink)         /* 85 */
-       .long SYMBOL_NAME(sys_uselib)
-       .long SYMBOL_NAME(sys_swapon)
-       .long SYMBOL_NAME(sys_reboot)
-       .long SYMBOL_NAME(old_readdir)
-       .long SYMBOL_NAME(old_mmap)             /* 90 */
-       .long SYMBOL_NAME(sys_munmap)
-       .long SYMBOL_NAME(sys_truncate)
-       .long SYMBOL_NAME(sys_ftruncate)
-       .long SYMBOL_NAME(sys_fchmod)
-       .long SYMBOL_NAME(sys_fchown16)         /* 95 */
-       .long SYMBOL_NAME(sys_getpriority)
-       .long SYMBOL_NAME(sys_setpriority)
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old 
profil syscall holder */
-       .long SYMBOL_NAME(sys_statfs)
-       .long SYMBOL_NAME(sys_fstatfs)          /* 100 */
-       .long SYMBOL_NAME(sys_ioperm)
-       .long SYMBOL_NAME(sys_socketcall)
-       .long SYMBOL_NAME(sys_syslog)
-       .long SYMBOL_NAME(sys_setitimer)
-       .long SYMBOL_NAME(sys_getitimer)        /* 105 */
-       .long SYMBOL_NAME(sys_newstat)
-       .long SYMBOL_NAME(sys_newlstat)
-       .long SYMBOL_NAME(sys_newfstat)
-       .long SYMBOL_NAME(sys_uname)
-       .long SYMBOL_NAME(sys_iopl)             /* 110 */
-       .long SYMBOL_NAME(sys_vhangup)
-       .long SYMBOL_NAME(sys_ni_syscall)       /* old "idle" system call */
-       .long SYMBOL_NAME(sys_ni_syscall) /* was VM86 */
-       .long SYMBOL_NAME(sys_wait4)
-       .long SYMBOL_NAME(sys_swapoff)          /* 115 */
-       .long SYMBOL_NAME(sys_sysinfo)
-       .long SYMBOL_NAME(sys_ipc)
-       .long SYMBOL_NAME(sys_fsync)
-       .long SYMBOL_NAME(sys_sigreturn)
-       .long SYMBOL_NAME(sys_clone)            /* 120 */
-       .long SYMBOL_NAME(sys_setdomainname)
-       .long SYMBOL_NAME(sys_newuname)
-       .long SYMBOL_NAME(sys_modify_ldt)
-       .long SYMBOL_NAME(sys_adjtimex)
-       .long SYMBOL_NAME(sys_mprotect)         /* 125 */
-       .long SYMBOL_NAME(sys_sigprocmask)
-       .long SYMBOL_NAME(sys_create_module)
-       .long SYMBOL_NAME(sys_init_module)
-       .long SYMBOL_NAME(sys_delete_module)
-       .long SYMBOL_NAME(sys_get_kernel_syms)  /* 130 */
-       .long SYMBOL_NAME(sys_quotactl)
-       .long SYMBOL_NAME(sys_getpgid)
-       .long SYMBOL_NAME(sys_fchdir)
-       .long SYMBOL_NAME(sys_bdflush)
-       .long SYMBOL_NAME(sys_sysfs)            /* 135 */
-       .long SYMBOL_NAME(sys_personality)
-       .long SYMBOL_NAME(sys_ni_syscall)       /* for afs_syscall */
-       .long SYMBOL_NAME(sys_setfsuid16)
-       .long SYMBOL_NAME(sys_setfsgid16)
-       .long SYMBOL_NAME(sys_llseek)           /* 140 */
-       .long SYMBOL_NAME(sys_getdents)
-       .long SYMBOL_NAME(sys_select)
-       .long SYMBOL_NAME(sys_flock)
-       .long SYMBOL_NAME(sys_msync)
-       .long SYMBOL_NAME(sys_readv)            /* 145 */
-       .long SYMBOL_NAME(sys_writev)
-       .long SYMBOL_NAME(sys_getsid)
-       .long SYMBOL_NAME(sys_fdatasync)
-       .long SYMBOL_NAME(sys_sysctl)
-       .long SYMBOL_NAME(sys_mlock)            /* 150 */
-       .long SYMBOL_NAME(sys_munlock)
-       .long SYMBOL_NAME(sys_mlockall)
-       .long SYMBOL_NAME(sys_munlockall)
-       .long SYMBOL_NAME(sys_sched_setparam)
-       .long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
-       .long SYMBOL_NAME(sys_sched_setscheduler)
-       .long SYMBOL_NAME(sys_sched_getscheduler)
-       .long SYMBOL_NAME(sys_sched_yield)
-       .long SYMBOL_NAME(sys_sched_get_priority_max)
-       .long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
-       .long SYMBOL_NAME(sys_sched_rr_get_interval)
-       .long SYMBOL_NAME(sys_nanosleep)
-       .long SYMBOL_NAME(sys_mremap)
-       .long SYMBOL_NAME(sys_setresuid16)
-       .long SYMBOL_NAME(sys_getresuid16)      /* 165 */
-       .long SYMBOL_NAME(sys_ni_syscall) /* was VM86 */
-       .long SYMBOL_NAME(sys_query_module)
-       .long SYMBOL_NAME(sys_poll)
-       .long SYMBOL_NAME(sys_nfsservctl)
-       .long SYMBOL_NAME(sys_setresgid16)      /* 170 */
-       .long SYMBOL_NAME(sys_getresgid16)
-       .long SYMBOL_NAME(sys_prctl)
-       .long SYMBOL_NAME(sys_rt_sigreturn)
-       .long SYMBOL_NAME(sys_rt_sigaction)
-       .long SYMBOL_NAME(sys_rt_sigprocmask)   /* 175 */
-       .long SYMBOL_NAME(sys_rt_sigpending)
-       .long SYMBOL_NAME(sys_rt_sigtimedwait)
-       .long SYMBOL_NAME(sys_rt_sigqueueinfo)
-       .long SYMBOL_NAME(sys_rt_sigsuspend)
-       .long SYMBOL_NAME(sys_pread)            /* 180 */
-       .long SYMBOL_NAME(sys_pwrite)
-       .long SYMBOL_NAME(sys_chown16)
-       .long SYMBOL_NAME(sys_getcwd)
-       .long SYMBOL_NAME(sys_capget)
-       .long SYMBOL_NAME(sys_capset)           /* 185 */
-       .long SYMBOL_NAME(sys_sigaltstack)
-       .long SYMBOL_NAME(sys_sendfile)
-       .long SYMBOL_NAME(sys_ni_syscall)               /* streams1 */
-       .long SYMBOL_NAME(sys_ni_syscall)               /* streams2 */
-       .long SYMBOL_NAME(sys_vfork)            /* 190 */
-       .long SYMBOL_NAME(sys_getrlimit)
-       .long SYMBOL_NAME(sys_mmap2)
-       .long SYMBOL_NAME(sys_truncate64)
-       .long SYMBOL_NAME(sys_ftruncate64)
-       .long SYMBOL_NAME(sys_stat64)           /* 195 */
-       .long SYMBOL_NAME(sys_lstat64)
-       .long SYMBOL_NAME(sys_fstat64)
-       .long SYMBOL_NAME(sys_lchown)
-       .long SYMBOL_NAME(sys_getuid)
-       .long SYMBOL_NAME(sys_getgid)           /* 200 */
-       .long SYMBOL_NAME(sys_geteuid)
-       .long SYMBOL_NAME(sys_getegid)
-       .long SYMBOL_NAME(sys_setreuid)
-       .long SYMBOL_NAME(sys_setregid)
-       .long SYMBOL_NAME(sys_getgroups)        /* 205 */
-       .long SYMBOL_NAME(sys_setgroups)
-       .long SYMBOL_NAME(sys_fchown)
-       .long SYMBOL_NAME(sys_setresuid)
-       .long SYMBOL_NAME(sys_getresuid)
-       .long SYMBOL_NAME(sys_setresgid)        /* 210 */
-       .long SYMBOL_NAME(sys_getresgid)
-       .long SYMBOL_NAME(sys_chown)
-       .long SYMBOL_NAME(sys_setuid)
-       .long SYMBOL_NAME(sys_setgid)
-       .long SYMBOL_NAME(sys_setfsuid)         /* 215 */
-       .long SYMBOL_NAME(sys_setfsgid)
-       .long SYMBOL_NAME(sys_pivot_root)
-       .long SYMBOL_NAME(sys_mincore)
-       .long SYMBOL_NAME(sys_madvise)
-       .long SYMBOL_NAME(sys_getdents64)       /* 220 */
-       .long SYMBOL_NAME(sys_fcntl64)
-       .long SYMBOL_NAME(sys_ni_syscall)       /* reserved for TUX */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* Reserved for Security */
-       .long SYMBOL_NAME(sys_gettid)
-       .long SYMBOL_NAME(sys_readahead)        /* 225 */
-       .long SYMBOL_NAME(sys_setxattr)
-       .long SYMBOL_NAME(sys_lsetxattr)
-       .long SYMBOL_NAME(sys_fsetxattr)
-       .long SYMBOL_NAME(sys_getxattr)
-       .long SYMBOL_NAME(sys_lgetxattr)        /* 230 */
-       .long SYMBOL_NAME(sys_fgetxattr)
-       .long SYMBOL_NAME(sys_listxattr)
-       .long SYMBOL_NAME(sys_llistxattr)
-       .long SYMBOL_NAME(sys_flistxattr)
-       .long SYMBOL_NAME(sys_removexattr)      /* 235 */
-       .long SYMBOL_NAME(sys_lremovexattr)
-       .long SYMBOL_NAME(sys_fremovexattr)
-       .long SYMBOL_NAME(sys_tkill)
-       .long SYMBOL_NAME(sys_sendfile64)
-       .long SYMBOL_NAME(sys_ni_syscall)       /* 240 reserved for futex */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* reserved for 
sched_setaffinity */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* reserved for 
sched_getaffinity */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_set_thread_area */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_get_thread_area */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* 245 sys_io_setup */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_io_destroy */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_io_getevents */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_io_submit */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_io_cancel */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* 250 sys_alloc_hugepages */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_free_hugepages */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_exit_group */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_lookup_dcookie */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_epoll_create */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_epoll_ctl 255 */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_epoll_wait */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_remap_file_pages */
-       .long SYMBOL_NAME(sys_ni_syscall)       /* sys_set_tid_address */
-
-       .rept NR_syscalls-(.-sys_call_table)/4
-               .long SYMBOL_NAME(sys_ni_syscall)
-       .endr
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/kernel/head.S
--- a/linux-2.4-xen-sparse/arch/xen/kernel/head.S       Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,41 +0,0 @@
-
-.section __xen_guest
-    .ascii "GUEST_OS=linux,GUEST_VER=2.4,XEN_VER=3.0,VIRT_BASE=0xC0000000"
-    .ascii ",LOADER=generic"
-    .byte  0
-
-.text
-#include <linux/config.h>
-#include <linux/threads.h>
-#include <linux/linkage.h>
-#include <asm/segment.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/desc.h>
-
-ENTRY(stext)
-ENTRY(_stext)
-        cld
-        lss stack_start,%esp
-        /* Copy the necessary stuff from xen_start_info structure. */
-        mov $SYMBOL_NAME(xen_start_info_union),%edi
-        mov $128,%ecx
-        rep movsl
-        jmp SYMBOL_NAME(start_kernel)
-
-ENTRY(stack_start)
-       .long SYMBOL_NAME(init_task_union)+8192, __KERNEL_DS
-
-.org 0x1000
-ENTRY(empty_zero_page)
-
-.org 0x2000
-ENTRY(default_ldt)
-
-.org 0x3000
-ENTRY(cpu0_pte_quicklist)
-
-.org 0x3400
-ENTRY(cpu0_pgd_quicklist)
-        
-.org 0x3800
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/i386_ksyms.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/i386_ksyms.c Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,180 +0,0 @@
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/user.h>
-#include <linux/elfcore.h>
-#include <linux/mca.h>
-#include <linux/sched.h>
-#include <linux/in6.h>
-#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
-#include <linux/pm.h>
-#include <linux/pci.h>
-#include <linux/apm_bios.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/tty.h>
-
-#include <asm/semaphore.h>
-#include <asm/processor.h>
-#include <asm/i387.h>
-#include <asm/uaccess.h>
-#include <asm/checksum.h>
-#include <asm/io.h>
-#include <asm/hardirq.h>
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/mmx.h>
-#include <asm/desc.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-
-extern void dump_thread(struct pt_regs *, struct user *);
-extern spinlock_t rtc_lock;
-
-#if defined(CONFIG_APMXXX) || defined(CONFIG_APM_MODULEXXX)
-extern void machine_real_restart(unsigned char *, int);
-EXPORT_SYMBOL(machine_real_restart);
-extern void default_idle(void);
-EXPORT_SYMBOL(default_idle);
-#endif
-
-#ifdef CONFIG_SMP
-extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
-extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
-#endif
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || 
defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
-// XXX extern unsigned long get_cmos_time(void);
-
-/* platform dependent support */
-EXPORT_SYMBOL(boot_cpu_data);
-EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(dump_extended_fpu);
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(disable_irq_nosync);
-EXPORT_SYMBOL(probe_irq_mask);
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(pm_idle);
-EXPORT_SYMBOL(pm_power_off);
-EXPORT_SYMBOL(apm_info);
-//EXPORT_SYMBOL(gdt);
-EXPORT_SYMBOL(empty_zero_page);
-EXPORT_SYMBOL(phys_to_machine_mapping);
-
-
-#ifdef CONFIG_DEBUG_IOVIRT
-EXPORT_SYMBOL(__io_virt_debug);
-#endif
-
-EXPORT_SYMBOL_NOVERS(__down_failed);
-EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
-EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
-EXPORT_SYMBOL_NOVERS(__up_wakeup);
-/* Networking helper routines. */
-EXPORT_SYMBOL(csum_partial_copy_generic);
-/* Delay loops */
-EXPORT_SYMBOL(__ndelay);
-EXPORT_SYMBOL(__udelay);
-EXPORT_SYMBOL(__delay);
-EXPORT_SYMBOL(__const_udelay);
-
-EXPORT_SYMBOL_NOVERS(__get_user_1);
-EXPORT_SYMBOL_NOVERS(__get_user_2);
-EXPORT_SYMBOL_NOVERS(__get_user_4);
-
-EXPORT_SYMBOL(strtok);
-EXPORT_SYMBOL(strpbrk);
-EXPORT_SYMBOL(strstr);
-
-EXPORT_SYMBOL(strncpy_from_user);
-EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(clear_user);
-EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(__generic_copy_from_user);
-EXPORT_SYMBOL(__generic_copy_to_user);
-EXPORT_SYMBOL(strnlen_user);
-
-
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
-
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(pcibios_penalize_isa_irq);
-EXPORT_SYMBOL(pci_mem_start);
-#endif
-
-
-#ifdef CONFIG_X86_USE_3DNOW
-EXPORT_SYMBOL(_mmx_memcpy);
-EXPORT_SYMBOL(mmx_clear_page);
-EXPORT_SYMBOL(mmx_copy_page);
-#endif
-
-#ifdef CONFIG_SMP
-EXPORT_SYMBOL(cpu_data);
-EXPORT_SYMBOL(kernel_flag_cacheline);
-EXPORT_SYMBOL(smp_num_cpus);
-EXPORT_SYMBOL(cpu_online_map);
-EXPORT_SYMBOL_NOVERS(__write_lock_failed);
-EXPORT_SYMBOL_NOVERS(__read_lock_failed);
-
-/* Global SMP irq stuff */
-EXPORT_SYMBOL(synchronize_irq);
-EXPORT_SYMBOL(global_irq_holder);
-EXPORT_SYMBOL(__global_cli);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
-EXPORT_SYMBOL(smp_call_function);
-
-/* TLB flushing */
-EXPORT_SYMBOL(flush_tlb_page);
-
-/* HT support */
-EXPORT_SYMBOL(smp_num_siblings);
-EXPORT_SYMBOL(cpu_sibling_map);
-#endif
-
-#ifdef CONFIG_X86_IO_APIC
-EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-#endif
-
-#ifdef CONFIG_VT
-EXPORT_SYMBOL(screen_info);
-#endif
-
-EXPORT_SYMBOL(get_wchan);
-
-EXPORT_SYMBOL(rtc_lock);
-
-#undef memcpy
-#undef memset
-extern void * memset(void *,int,__kernel_size_t);
-extern void * memcpy(void *,const void *,__kernel_size_t);
-EXPORT_SYMBOL_NOVERS(memcpy);
-EXPORT_SYMBOL_NOVERS(memset);
-
-#ifdef CONFIG_HAVE_DEC_LOCK
-EXPORT_SYMBOL(atomic_dec_and_lock);
-#endif
-
-#ifdef CONFIG_MULTIQUAD
-EXPORT_SYMBOL(xquad_portio);
-#endif
-
-#include <asm/xen_proc.h>
-EXPORT_SYMBOL(create_xen_proc_entry);
-EXPORT_SYMBOL(remove_xen_proc_entry);
-
-EXPORT_SYMBOL(evtchn_do_upcall);
-EXPORT_SYMBOL(force_evtchn_callback);
-EXPORT_SYMBOL(HYPERVISOR_shared_info);
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/kernel/irq.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/irq.c        Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,1242 +0,0 @@
-/*
- *     linux/arch/i386/kernel/irq.c
- *
- *     Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
- *
- * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- */
-
-/*
- * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
- *
- * IRQs are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
- */
-
-#include <linux/config.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/irq.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include <asm/atomic.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/delay.h>
-#include <asm/desc.h>
-#include <asm/irq.h>
-
-
-
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
-
-/*
- * Controller mappings for all interrupt sources:
- */
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
-       { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
-
-static void register_irq_proc (unsigned int irq);
-
-/*
- * Special irq handlers.
- */
-
-void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
-
-/*
- * Generic no controller code
- */
-
-static void enable_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-static void disable_none(unsigned int irq) { }
-static void ack_none(unsigned int irq)
-{
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesnt deserve
- * a generic callback i think.
- */
-#if CONFIG_X86
-       printk("unexpected IRQ trap at vector %02x\n", irq);
-#ifdef CONFIG_X86_LOCAL_APIC
-       /*
-        * Currently unexpected vectors happen only on SMP and APIC.
-        * We _must_ ack these because every local APIC has only N
-        * irq slots per priority level, and a 'hanging, unacked' IRQ
-        * holds up an irq slot - in excessive cases (when multiple
-        * unexpected vectors occur) that might lock up the APIC
-        * completely.
-        */
-       ack_APIC_irq();
-#endif
-#endif
-}
-
-/* startup is the same as "enable", shutdown is same as "disable" */
-#define shutdown_none  disable_none
-#define end_none       enable_none
-
-struct hw_interrupt_type no_irq_type = {
-       "none",
-       startup_none,
-       shutdown_none,
-       enable_none,
-       disable_none,
-       ack_none,
-       end_none
-};
-
-atomic_t irq_err_count;
-#ifdef CONFIG_X86_IO_APIC
-#ifdef APIC_MISMATCH_DEBUG
-atomic_t irq_mis_count;
-#endif
-#endif
-
-/*
- * Generic, controller-independent functions:
- */
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       int i, j;
-       struct irqaction * action;
-
-       seq_printf(p, "           ");
-       for (j=0; j<smp_num_cpus; j++)
-               seq_printf(p, "CPU%d       ",j);
-       seq_putc(p,'\n');
-
-       for (i = 0 ; i < NR_IRQS ; i++) {
-               action = irq_desc[i].action;
-               if (!action) 
-                       continue;
-               seq_printf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
-               seq_printf(p, "%10u ", kstat_irqs(i));
-#else
-               for (j = 0; j < smp_num_cpus; j++)
-                       seq_printf(p, "%10u ",
-                               kstat.irqs[cpu_logical_map(j)][i]);
-#endif
-               seq_printf(p, " %14s", irq_desc[i].handler->typename);
-               seq_printf(p, "  %s", action->name);
-
-               for (action=action->next; action; action = action->next)
-                       seq_printf(p, ", %s", action->name);
-               seq_putc(p,'\n');
-       }
-       seq_printf(p, "NMI: ");
-       for (j = 0; j < smp_num_cpus; j++)
-               seq_printf(p, "%10u ",
-                       nmi_count(cpu_logical_map(j)));
-       seq_printf(p, "\n");
-#if CONFIG_X86_LOCAL_APIC
-       seq_printf(p, "LOC: ");
-       for (j = 0; j < smp_num_cpus; j++)
-               seq_printf(p, "%10u ",
-                       apic_timer_irqs[cpu_logical_map(j)]);
-       seq_printf(p, "\n");
-#endif
-       seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-#ifdef CONFIG_X86_IO_APIC
-#ifdef APIC_MISMATCH_DEBUG
-       seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
-#endif
-#endif
-
-       return 0;
-}
-
-
-/*
- * Global interrupt locks for SMP. Allow interrupts to come in on any
- * CPU, yet make cli/sti act globally to protect critical regions..
- */
-
-#ifdef CONFIG_SMP
-unsigned char global_irq_holder = NO_PROC_ID;
-unsigned volatile long global_irq_lock; /* pendantic: long for set_bit --RR */
-
-extern void show_stack(unsigned long* esp);
-
-static void show(char * str)
-{
-       int i;
-       int cpu = smp_processor_id();
-
-       printk("\n%s, CPU %d:\n", str, cpu);
-       printk("irq:  %d [",irqs_running());
-       for(i=0;i < smp_num_cpus;i++)
-               printk(" %d",local_irq_count(i));
-       printk(" ]\nbh:   %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
-       for(i=0;i < smp_num_cpus;i++)
-               printk(" %d",local_bh_count(i));
-
-       printk(" ]\nStack dumps:");
-       for(i = 0; i < smp_num_cpus; i++) {
-               unsigned long esp;
-               if (i == cpu)
-                       continue;
-               printk("\nCPU %d:",i);
-               esp = init_tss[i].esp0;
-               if (!esp) {
-                       /* tss->esp0 is set to NULL in cpu_init(),
-                        * it's initialized when the cpu returns to user
-                        * space. -- manfreds
-                        */
-                       printk(" <unknown> ");
-                       continue;
-               }
-               esp &= ~(THREAD_SIZE-1);
-               esp += sizeof(struct task_struct);
-               show_stack((void*)esp);
-       }
-       printk("\nCPU %d:",cpu);
-       show_stack(NULL);
-       printk("\n");
-}
-       
-#define MAXCOUNT 100000000
-
-/*
- * I had a lockup scenario where a tight loop doing
- * spin_unlock()/spin_lock() on CPU#1 was racing with
- * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
- * apparently the spin_unlock() information did not make it
- * through to CPU#0 ... nasty, is this by design, do we have to limit
- * 'memory update oscillation frequency' artificially like here?
- *
- * Such 'high frequency update' races can be avoided by careful design, but
- * some of our major constructs like spinlocks use similar techniques,
- * it would be nice to clarify this issue. Set this define to 0 if you
- * want to check whether your system freezes.  I suspect the delay done
- * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
- * i thought that such things are guaranteed by design, since we use
- * the 'LOCK' prefix.
- */
-#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
-
-#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
-# define SYNC_OTHER_CORES(x) udelay(x+1)
-#else
-/*
- * We have to allow irqs to arrive between __sti and __cli
- */
-# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
-#endif
-
-static inline void wait_on_irq(int cpu)
-{
-       int count = MAXCOUNT;
-
-       for (;;) {
-
-               /*
-                * Wait until all interrupts are gone. Wait
-                * for bottom half handlers unless we're
-                * already executing in one..
-                */
-               if (!irqs_running())
-                       if (local_bh_count(cpu) || 
!spin_is_locked(&global_bh_lock))
-                               break;
-
-               /* Duh, we have to loop. Release the lock to avoid deadlocks */
-               clear_bit(0,&global_irq_lock);
-
-               for (;;) {
-                       if (!--count) {
-                               show("wait_on_irq");
-                               count = ~0;
-                       }
-                       __sti();
-                       SYNC_OTHER_CORES(cpu);
-                       __cli();
-                       if (irqs_running())
-                               continue;
-                       if (global_irq_lock)
-                               continue;
-                       if (!local_bh_count(cpu) && 
spin_is_locked(&global_bh_lock))
-                               continue;
-                       if (!test_and_set_bit(0,&global_irq_lock))
-                               break;
-               }
-       }
-}
-
-/*
- * This is called when we want to synchronize with
- * interrupts. We may for example tell a device to
- * stop sending interrupts: but to make sure there
- * are no interrupts that are executing on another
- * CPU we need to call this function.
- */
-void synchronize_irq(void)
-{
-       if (irqs_running()) {
-               /* Stupid approach */
-               cli();
-               sti();
-       }
-}
-
-static inline void get_irqlock(int cpu)
-{
-       if (test_and_set_bit(0,&global_irq_lock)) {
-               /* do we already hold the lock? */
-               if ((unsigned char) cpu == global_irq_holder)
-                       return;
-               /* Uhhuh.. Somebody else got it. Wait.. */
-               do {
-                       do {
-                               rep_nop();
-                       } while (test_bit(0,&global_irq_lock));
-               } while (test_and_set_bit(0,&global_irq_lock));         
-       }
-       /* 
-        * We also to make sure that nobody else is running
-        * in an interrupt context. 
-        */
-       wait_on_irq(cpu);
-
-       /*
-        * Ok, finally..
-        */
-       global_irq_holder = cpu;
-}
-
-/*
- * A global "cli()" while in an interrupt context
- * turns into just a local cli(). Interrupts
- * should use spinlocks for the (very unlikely)
- * case that they ever want to protect against
- * each other.
- *
- * If we already have local interrupts disabled,
- * this will not turn a local disable into a
- * global one (problems with spinlocks: this makes
- * save_flags+cli+sti usable inside a spinlock).
- */
-void __global_cli(void)
-{
-       unsigned int flags;
-
-       __save_flags(flags);
-       if (!flags) {
-               int cpu = smp_processor_id();
-               __cli();
-               if (!local_irq_count(cpu))
-                       get_irqlock(cpu);
-       }
-}
-
-void __global_sti(void)
-{
-       int cpu = smp_processor_id();
-
-       if (!local_irq_count(cpu))
-               release_irqlock(cpu);
-       __sti();
-}
-
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long __global_save_flags(void)
-{
-       int retval;
-       int local_enabled;
-       unsigned long flags;
-       int cpu = smp_processor_id();
-
-       __save_flags(flags);
-       local_enabled = !flags;
-       /* default to local */
-       retval = 2 + local_enabled;
-
-       /* check for global flags if we're not in an interrupt */
-       if (!local_irq_count(cpu)) {
-               if (local_enabled)
-                       retval = 1;
-               if (global_irq_holder == cpu)
-                       retval = 0;
-       }
-       return retval;
-}
-
-void __global_restore_flags(unsigned long flags)
-{
-       switch (flags) {
-       case 0:
-               __global_cli();
-               break;
-       case 1:
-               __global_sti();
-               break;
-       case 2:
-               __cli();
-               break;
-       case 3:
-               __sti();
-               break;
-       default:
-               printk("global_restore_flags: %08lx (%08lx)\n",
-                       flags, (&flags)[-1]);
-       }
-}
-
-#endif
-
-/*
- * This should really return information about whether
- * we should do bottom half handling etc. Right now we
- * end up _always_ checking the bottom half, which is a
- * waste of time and is not what some drivers would
- * prefer.
- */
-int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction 
* action)
-{
-       int status;
-       int cpu = smp_processor_id();
-
-       irq_enter(cpu, irq);
-
-       status = 1;     /* Force the "do bottom halves" bit */
-
-       if (!(action->flags & SA_INTERRUPT))
-               __sti();
-
-       do {
-               status |= action->flags;
-               action->handler(irq, action->dev_id, regs);
-               action = action->next;
-       } while (action);
-       if (status & SA_SAMPLE_RANDOM)
-               add_interrupt_randomness(irq);
-       __cli();
-
-       irq_exit(cpu, irq);
-
-       return status;
-}
-
-/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock. 
- */
- 
-/**
- *     disable_irq_nosync - disable an irq without waiting
- *     @irq: Interrupt to disable
- *
- *     Disable the selected interrupt line.  Disables and Enables are
- *     nested.
- *     Unlike disable_irq(), this function does not ensure existing
- *     instances of the IRQ handler have completed before returning.
- *
- *     This function may be called from IRQ context.
- */
- 
-inline void disable_irq_nosync(unsigned int irq)
-{
-       irq_desc_t *desc = irq_desc + irq;
-       unsigned long flags;
-
-       spin_lock_irqsave(&desc->lock, flags);
-       if (!desc->depth++) {
-               desc->status |= IRQ_DISABLED;
-               desc->handler->disable(irq);
-       }
-       spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *     disable_irq - disable an irq and wait for completion
- *     @irq: Interrupt to disable
- *
- *     Disable the selected interrupt line.  Enables and Disables are
- *     nested.
- *     This function waits for any pending IRQ handlers for this interrupt
- *     to complete before returning. If you use this function while
- *     holding a resource the IRQ handler may need you will deadlock.
- *
- *     This function may be called - with care - from IRQ context.
- */
- 
-void disable_irq(unsigned int irq)
-{
-       disable_irq_nosync(irq);
-
-       if (!local_irq_count(smp_processor_id())) {
-               do {
-                       barrier();
-                       cpu_relax();
-               } while (irq_desc[irq].status & IRQ_INPROGRESS);
-       }
-}
-
-/**
- *     enable_irq - enable handling of an irq
- *     @irq: Interrupt to enable
- *
- *     Undoes the effect of one call to disable_irq().  If this
- *     matches the last disable, processing of interrupts on this
- *     IRQ line is re-enabled.
- *
- *     This function may be called from IRQ context.
- */
- 
-void enable_irq(unsigned int irq)
-{
-       irq_desc_t *desc = irq_desc + irq;
-       unsigned long flags;
-
-       spin_lock_irqsave(&desc->lock, flags);
-       switch (desc->depth) {
-       case 1: {
-               unsigned int status = desc->status & ~IRQ_DISABLED;
-               desc->status = status;
-               if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-                       desc->status = status | IRQ_REPLAY;
-                       hw_resend_irq(desc->handler,irq);
-               }
-               desc->handler->enable(irq);
-               /* fall-through */
-       }
-       default:
-               desc->depth--;
-               break;
-       case 0:
-               printk("enable_irq(%u) unbalanced from %p\n", irq,
-                      __builtin_return_address(0));
-       }
-       spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- */
-asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
-{      
-       /* 
-        * We ack quickly, we don't want the irq controller
-        * thinking we're snobs just because some other CPU has
-        * disabled global interrupts (we have already done the
-        * INT_ACK cycles, it's too late to try to pretend to the
-        * controller that we aren't taking the interrupt).
-        *
-        * 0 return value means that this irq is already being
-        * handled by some other CPU. (or is disabled)
-        */
-       int irq = regs->orig_eax & 0xff; /* high bits used in ret_from_ code */
-       int cpu = smp_processor_id();
-       irq_desc_t *desc = irq_desc + irq;
-       struct irqaction * action;
-       unsigned int status;
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
-       long esp;
-
-       /* Debugging check for stack overflow: is there less than 1KB free? */
-       __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191));
-       if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
-               extern void show_stack(unsigned long *);
-
-               printk("do_IRQ: stack overflow: %ld\n",
-                       esp - sizeof(struct task_struct));
-               __asm__ __volatile__("movl %%esp,%0" : "=r" (esp));
-               show_stack((void *)esp);
-       }
-#endif
-
-       kstat.irqs[cpu][irq]++;
-       spin_lock(&desc->lock);
-       desc->handler->ack(irq);
-       /*
-          REPLAY is when Linux resends an IRQ that was dropped earlier
-          WAITING is used by probe to mark irqs that are being tested
-          */
-       status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-       status |= IRQ_PENDING; /* we _want_ to handle it */
-
-       /*
-        * If the IRQ is disabled for whatever reason, we cannot
-        * use the action we have.
-        */
-       action = NULL;
-       if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-               action = desc->action;
-               status &= ~IRQ_PENDING; /* we commit to handling */
-               status |= IRQ_INPROGRESS; /* we are handling it */
-       }
-       desc->status = status;
-
-       /*
-        * If there is no IRQ handler or it was disabled, exit early.
-          Since we set PENDING, if another processor is handling
-          a different instance of this same irq, the other processor
-          will take care of it.
-        */
-       if (!action)
-               goto out;
-
-       /*
-        * Edge triggered interrupts need to remember
-        * pending events.
-        * This applies to any hw interrupts that allow a second
-        * instance of the same irq to arrive while we are in do_IRQ
-        * or in the handler. But the code here only handles the _second_
-        * instance of the irq, not the third or fourth. So it is mostly
-        * useful for irq hardware that does not mask cleanly in an
-        * SMP environment.
-        */
-       for (;;) {
-               spin_unlock(&desc->lock);
-               handle_IRQ_event(irq, regs, action);
-               spin_lock(&desc->lock);
-               
-               if (!(desc->status & IRQ_PENDING))
-                       break;
-               desc->status &= ~IRQ_PENDING;
-       }
-       desc->status &= ~IRQ_INPROGRESS;
-out:
-       /*
-        * The ->end() handler has to deal with interrupts which got
-        * disabled while the handler was running.
-        */
-       desc->handler->end(irq);
-       spin_unlock(&desc->lock);
-
-       if (softirq_pending(cpu))
-               do_softirq();
-       return 1;
-}
-
-/**
- *     request_irq - allocate an interrupt line
- *     @irq: Interrupt line to allocate
- *     @handler: Function to be called when the IRQ occurs
- *     @irqflags: Interrupt type flags
- *     @devname: An ascii name for the claiming device
- *     @dev_id: A cookie passed back to the handler function
- *
- *     This call allocates interrupt resources and enables the
- *     interrupt line and IRQ handling. From the point this
- *     call is made your handler function may be invoked. Since
- *     your handler function must clear any interrupt the board 
- *     raises, you must take care both to initialise your hardware
- *     and to set up the interrupt handler in the right order.
- *
- *     Dev_id must be globally unique. Normally the address of the
- *     device data structure is used as the cookie. Since the handler
- *     receives this value it makes sense to use it.
- *
- *     If your interrupt is shared you must pass a non NULL dev_id
- *     as this is required when freeing the interrupt.
- *
- *     Flags:
- *
- *     SA_SHIRQ                Interrupt is shared
- *
- *     SA_INTERRUPT            Disable local interrupts while processing
- *
- *     SA_SAMPLE_RANDOM        The interrupt can be used for entropy
- *
- */
- 
-int request_irq(unsigned int irq, 
-               void (*handler)(int, void *, struct pt_regs *),
-               unsigned long irqflags, 
-               const char * devname,
-               void *dev_id)
-{
-       int retval;
-       struct irqaction * action;
-
-#if 1
-       /*
-        * Sanity-check: shared interrupts should REALLY pass in
-        * a real dev-ID, otherwise we'll have trouble later trying
-        * to figure out which interrupt is which (messes up the
-        * interrupt freeing logic etc).
-        */
-       if (irqflags & SA_SHIRQ) {
-               if (!dev_id)
-                       printk("Bad boy: %s (at 0x%x) called us without a 
dev_id!\n", devname, (&irq)[-1]);
-       }
-#endif
-
-       if (irq >= NR_IRQS)
-               return -EINVAL;
-       if (!handler)
-               return -EINVAL;
-
-       action = (struct irqaction *)
-                       kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-       if (!action)
-               return -ENOMEM;
-
-       action->handler = handler;
-       action->flags = irqflags;
-       action->mask = 0;
-       action->name = devname;
-       action->next = NULL;
-       action->dev_id = dev_id;
-
-       retval = setup_irq(irq, action);
-       if (retval)
-               kfree(action);
-       return retval;
-}
-
-/*
- * Internal function to unregister an irqaction - typically used to
- * deallocate special interrupts that are part of the architecture.
- */
-int teardown_irq(unsigned int irq, struct irqaction * old)
-{
-       irq_desc_t *desc;
-       struct irqaction **p;
-       unsigned long flags;
-
-       if (irq >= NR_IRQS)
-               return -ENOENT;
-
-       desc = irq_desc + irq;
-       spin_lock_irqsave(&desc->lock,flags);
-       p = &desc->action;
-       for (;;) {
-               struct irqaction * action = *p;
-               if (action) {
-                       struct irqaction **pp = p;
-                       p = &action->next;
-                       if (action != old)
-                               continue;
-
-                       /* Found it - now remove it from the list of entries */
-                       *pp = action->next;
-                       if (!desc->action) {
-                               desc->status |= IRQ_DISABLED;
-                               desc->handler->shutdown(irq);
-                       }
-                       spin_unlock_irqrestore(&desc->lock,flags);
-
-#ifdef CONFIG_SMP
-                       /* Wait to make sure it's not being used on another CPU 
*/
-                       while (desc->status & IRQ_INPROGRESS) {
-                               barrier();
-                               cpu_relax();
-                       }
-#endif
-                       return 0;
-               }
-               printk("Trying to free free IRQ%d\n",irq);
-               spin_unlock_irqrestore(&desc->lock,flags);
-               return -ENOENT;
-       }
-}
-
-/**
- *     free_irq - free an interrupt
- *     @irq: Interrupt line to free
- *     @dev_id: Device identity to free
- *
- *     Remove an interrupt handler. The handler is removed and if the
- *     interrupt line is no longer in use by any driver it is disabled.
- *     On a shared IRQ the caller must ensure the interrupt is disabled
- *     on the card it drives before calling this function. The function
- *     does not return until any executing interrupts for this IRQ
- *     have completed.
- *
- *     This function may be called from interrupt context. 
- *
- *     Bugs: Attempting to free an irq in a handler for the same irq hangs
- *           the machine.
- */
- 
-void free_irq(unsigned int irq, void *dev_id)
-{
-       irq_desc_t *desc;
-       struct irqaction *action;
-       unsigned long flags;
-
-       if (irq >= NR_IRQS)
-               return;
-
-       desc = irq_desc + irq;
-       spin_lock_irqsave(&desc->lock,flags);
-       for (action = desc->action; action != NULL; action = action->next) {
-               if (action->dev_id != dev_id)
-                       continue;
-
-               spin_unlock_irqrestore(&desc->lock,flags);
-
-               if (teardown_irq(irq, action) == 0)
-                       kfree(action);
-               return;
-       }
-       printk("Trying to free free IRQ%d\n",irq);
-       spin_unlock_irqrestore(&desc->lock,flags);
-       return;
-}
-
-/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-
-static DECLARE_MUTEX(probe_sem);
-
-/**
- *     probe_irq_on    - begin an interrupt autodetect
- *
- *     Commence probing for an interrupt. The interrupts are scanned
- *     and a mask of potential interrupt lines is returned.
- *
- */
- 
-unsigned long probe_irq_on(void)
-{
-       unsigned int i;
-       irq_desc_t *desc;
-       unsigned long val;
-       unsigned long delay;
-
-       down(&probe_sem);
-       /* 
-        * something may have generated an irq long ago and we want to
-        * flush such a longstanding irq before considering it as spurious. 
-        */
-       for (i = NR_PIRQS-1; i > 0; i--)  {
-               desc = irq_desc + i;
-
-               spin_lock_irq(&desc->lock);
-               if (!irq_desc[i].action) 
-                       irq_desc[i].handler->startup(i);
-               spin_unlock_irq(&desc->lock);
-       }
-
-       /* Wait for longstanding interrupts to trigger. */
-       for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-               /* about 20ms delay */ synchronize_irq();
-
-       /*
-        * enable any unassigned irqs
-        * (we must startup again here because if a longstanding irq
-        * happened in the previous stage, it may have masked itself)
-        */
-       for (i = NR_PIRQS-1; i > 0; i--) {
-               desc = irq_desc + i;
-
-               spin_lock_irq(&desc->lock);
-               if (!desc->action) {
-                       desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-                       if (desc->handler->startup(i))
-                               desc->status |= IRQ_PENDING;
-               }
-               spin_unlock_irq(&desc->lock);
-       }
-
-       /*
-        * Wait for spurious interrupts to trigger
-        */
-       for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-               /* about 100ms delay */ synchronize_irq();
-
-       /*
-        * Now filter out any obviously spurious interrupts
-        */
-       val = 0;
-       for (i = 0; i < NR_PIRQS; i++) {
-               irq_desc_t *desc = irq_desc + i;
-               unsigned int status;
-
-               spin_lock_irq(&desc->lock);
-               status = desc->status;
-
-               if (status & IRQ_AUTODETECT) {
-                       /* It triggered already - consider it spurious. */
-                       if (!(status & IRQ_WAITING)) {
-                               desc->status = status & ~IRQ_AUTODETECT;
-                               desc->handler->shutdown(i);
-                       } else
-                               if (i < 32)
-                                       val |= 1 << i;
-               }
-               spin_unlock_irq(&desc->lock);
-       }
-
-       return val;
-}
-
-/*
- * Return a mask of triggered interrupts (this
- * can handle only legacy ISA interrupts).
- */
- 
-/**
- *     probe_irq_mask - scan a bitmap of interrupt lines
- *     @val:   mask of interrupts to consider
- *
- *     Scan the ISA bus interrupt lines and return a bitmap of
- *     active interrupts. The interrupt probe logic state is then
- *     returned to its previous value.
- *
- *     Note: we need to scan all the irq's even though we will
- *     only return ISA irq numbers - just so that we reset them
- *     all to a known state.
- */
-unsigned int probe_irq_mask(unsigned long val)
-{
-       int i;
-       unsigned int mask;
-
-       mask = 0;
-       for (i = 0; i < NR_PIRQS; i++) {
-               irq_desc_t *desc = irq_desc + i;
-               unsigned int status;
-
-               spin_lock_irq(&desc->lock);
-               status = desc->status;
-
-               if (status & IRQ_AUTODETECT) {
-                       if (i < 16 && !(status & IRQ_WAITING))
-                               mask |= 1 << i;
-
-                       desc->status = status & ~IRQ_AUTODETECT;
-                       desc->handler->shutdown(i);
-               }
-               spin_unlock_irq(&desc->lock);
-       }
-       up(&probe_sem);
-
-       return mask & val;
-}
-
-/*
- * Return the one interrupt that triggered (this can
- * handle any interrupt source).
- */
-
-/**
- *     probe_irq_off   - end an interrupt autodetect
- *     @val: mask of potential interrupts (unused)
- *
- *     Scans the unused interrupt lines and returns the line which
- *     appears to have triggered the interrupt. If no interrupt was
- *     found then zero is returned. If more than one interrupt is
- *     found then minus the first candidate is returned to indicate
- *     their is doubt.
- *
- *     The interrupt probe logic state is returned to its previous
- *     value.
- *
- *     BUGS: When used in a module (which arguably shouldnt happen)
- *     nothing prevents two IRQ probe callers from overlapping. The
- *     results of this are non-optimal.
- */
- 
-int probe_irq_off(unsigned long val)
-{
-       int i, irq_found, nr_irqs;
-
-       nr_irqs = 0;
-       irq_found = 0;
-       for (i = 0; i < NR_PIRQS; i++) {
-               irq_desc_t *desc = irq_desc + i;
-               unsigned int status;
-
-               spin_lock_irq(&desc->lock);
-               status = desc->status;
-
-               if (status & IRQ_AUTODETECT) {
-                       if (!(status & IRQ_WAITING)) {
-                               if (!nr_irqs)
-                                       irq_found = i;
-                               nr_irqs++;
-                       }
-                       desc->status = status & ~IRQ_AUTODETECT;
-                       desc->handler->shutdown(i);
-               }
-               spin_unlock_irq(&desc->lock);
-       }
-       up(&probe_sem);
-
-       if (nr_irqs > 1)
-               irq_found = -irq_found;
-       return irq_found;
-}
-
-/* this was setup_x86_irq but it seems pretty generic */
-int setup_irq(unsigned int irq, struct irqaction * new)
-{
-       int shared = 0;
-       unsigned long flags;
-       struct irqaction *old, **p;
-       irq_desc_t *desc = irq_desc + irq;
-
-       /*
-        * Some drivers like serial.c use request_irq() heavily,
-        * so we have to be careful not to interfere with a
-        * running system.
-        */
-       if (new->flags & SA_SAMPLE_RANDOM) {
-               /*
-                * This function might sleep, we want to call it first,
-                * outside of the atomic block.
-                * Yes, this might clear the entropy pool if the wrong
-                * driver is attempted to be loaded, without actually
-                * installing a new handler, but is this really a problem,
-                * only the sysadmin is able to do this.
-                */
-               rand_initialize_irq(irq);
-       }
-
-       /*
-        * The following block of code has to be executed atomically
-        */
-       spin_lock_irqsave(&desc->lock,flags);
-       p = &desc->action;
-       if ((old = *p) != NULL) {
-               /* Can't share interrupts unless both agree to */
-               if (!(old->flags & new->flags & SA_SHIRQ)) {
-                       spin_unlock_irqrestore(&desc->lock,flags);
-                       return -EBUSY;
-               }
-
-               /* add new interrupt at end of irq queue */
-               do {
-                       p = &old->next;
-                       old = *p;
-               } while (old);
-               shared = 1;
-       }
-
-       *p = new;
-
-       if (!shared) {
-               desc->depth = 0;
-               desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | 
IRQ_INPROGRESS);
-               desc->handler->startup(irq);
-       }
-       spin_unlock_irqrestore(&desc->lock,flags);
-
-       register_irq_proc(irq);
-       return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir [NR_IRQS];
-
-#define HEX_DIGITS 8
-
-static unsigned int parse_hex_value (const char *buffer,
-               unsigned long count, unsigned long *ret)
-{
-       unsigned char hexnum [HEX_DIGITS];
-       unsigned long value;
-       int i;
-
-       if (!count)
-               return -EINVAL;
-       if (count > HEX_DIGITS)
-               count = HEX_DIGITS;
-       if (copy_from_user(hexnum, buffer, count))
-               return -EFAULT;
-
-       /*
-        * Parse the first 8 characters as a hex string, any non-hex char
-        * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
-        */
-       value = 0;
-
-       for (i = 0; i < count; i++) {
-               unsigned int c = hexnum[i];
-
-               switch (c) {
-                       case '0' ... '9': c -= '0'; break;
-                       case 'a' ... 'f': c -= 'a'-10; break;
-                       case 'A' ... 'F': c -= 'A'-10; break;
-               default:
-                       goto out;
-               }
-               value = (value << 4) | c;
-       }
-out:
-       *ret = value;
-       return 0;
-}
-
-#if CONFIG_SMP
-
-static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
-
-static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
-static int irq_affinity_read_proc (char *page, char **start, off_t off,
-                       int count, int *eof, void *data)
-{
-       if (count < HEX_DIGITS+1)
-               return -EINVAL;
-       return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
-}
-
-static int irq_affinity_write_proc (struct file *file, const char *buffer,
-                                       unsigned long count, void *data)
-{
-       int irq = (long) data, full_count = count, err;
-       unsigned long new_value;
-
-       if (!irq_desc[irq].handler->set_affinity)
-               return -EIO;
-
-       err = parse_hex_value(buffer, count, &new_value);
-
-       /*
-        * Do not allow disabling IRQs completely - it's a too easy
-        * way to make the system unusable accidentally :-) At least
-        * one online CPU still has to be targeted.
-        */
-       if (!(new_value & cpu_online_map))
-               return -EINVAL;
-
-       irq_affinity[irq] = new_value;
-       irq_desc[irq].handler->set_affinity(irq, new_value);
-
-       return full_count;
-}
-
-#endif
-
-static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
-                       int count, int *eof, void *data)
-{
-       unsigned long *mask = (unsigned long *) data;
-       if (count < HEX_DIGITS+1)
-               return -EINVAL;
-       return sprintf (page, "%08lx\n", *mask);
-}
-
-static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
-                                       unsigned long count, void *data)
-{
-       unsigned long *mask = (unsigned long *) data, full_count = count, err;
-       unsigned long new_value;
-
-       err = parse_hex_value(buffer, count, &new_value);
-       if (err)
-               return err;
-
-       *mask = new_value;
-       return full_count;
-}
-
-#define MAX_NAMELEN 10
-
-static void register_irq_proc (unsigned int irq)
-{
-       char name [MAX_NAMELEN];
-
-       if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
-                       irq_dir[irq])
-               return;
-
-       memset(name, 0, MAX_NAMELEN);
-       sprintf(name, "%d", irq);
-
-       /* create /proc/irq/1234 */
-       irq_dir[irq] = proc_mkdir(name, root_irq_dir);
-
-#if CONFIG_SMP
-       {
-               struct proc_dir_entry *entry;
-
-               /* create /proc/irq/1234/smp_affinity */
-               entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
-
-               if (entry) {
-                       entry->nlink = 1;
-                       entry->data = (void *)(long)irq;
-                       entry->read_proc = irq_affinity_read_proc;
-                       entry->write_proc = irq_affinity_write_proc;
-               }
-
-               smp_affinity_entry[irq] = entry;
-       }
-#endif
-}
-
-unsigned long prof_cpu_mask = -1;
-
-void init_irq_proc (void)
-{
-       struct proc_dir_entry *entry;
-       int i;
-
-       /* create /proc/irq */
-       root_irq_dir = proc_mkdir("irq", 0);
-
-       /* create /proc/irq/prof_cpu_mask */
-       entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
-
-       if (!entry)
-           return;
-
-       entry->nlink = 1;
-       entry->data = (void *)&prof_cpu_mask;
-       entry->read_proc = prof_cpu_mask_read_proc;
-       entry->write_proc = prof_cpu_mask_write_proc;
-
-       /*
-        * Create entries for all existing IRQs.
-        */
-       for (i = 0; i < NR_IRQS; i++)
-               register_irq_proc(i);
-}
-
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/kernel/ldt.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/ldt.c        Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,272 +0,0 @@
-/*
- * linux/kernel/ldt.c
- *
- * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
- * Copyright (C) 1999 Ingo Molnar <mingo@xxxxxxxxxx>
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-
-#include <asm/mmu_context.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/ldt.h>
-#include <asm/desc.h>
-
-#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
-static void flush_ldt(void *mm)
-{
-       if (current->active_mm)
-               load_LDT(&current->active_mm->context);
-}
-#endif
-
-static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-{
-       void *oldldt;
-       void *newldt;
-       int oldsize;
-
-       if (mincount <= pc->size)
-               return 0;
-       oldsize = pc->size;
-       mincount = (mincount+511)&(~511);
-       if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
-               newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
-       else
-               newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
-
-       if (!newldt)
-               return -ENOMEM;
-
-       if (oldsize)
-               memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
-
-       oldldt = pc->ldt;
-       memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, 
(mincount-oldsize)*LDT_ENTRY_SIZE);
-       wmb();
-       pc->ldt = newldt;
-       pc->size = mincount;
-       if (reload) {
-               make_pages_readonly(
-                       pc->ldt,
-                       (pc->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
-               load_LDT(pc);
-#ifdef CONFIG_SMP
-               if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
-                       smp_call_function(flush_ldt, 0, 1, 1);
-#endif
-       }
-       wmb();
-       if (oldsize) {
-               make_pages_writable(
-                       oldldt, (oldsize*LDT_ENTRY_SIZE)/PAGE_SIZE);
-               if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
-                       vfree(oldldt);
-               else
-                       kfree(oldldt);
-       }
-       return 0;
-}
-
-static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-{
-       int err = alloc_ldt(new, old->size, 0);
-       if (err < 0) {
-               printk(KERN_WARNING "ldt allocation failed\n");
-               new->size = 0;
-               return err;
-       }
-       memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-       make_pages_readonly(new->ldt, (new->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
-       return 0;
-}
-
-/*
- * we do not have to muck with descriptors here, that is
- * done in switch_mm() as needed.
- */
-int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
-       struct mm_struct * old_mm;
-       int retval = 0;
-
-       init_MUTEX(&mm->context.sem);
-       mm->context.size = 0;
-       old_mm = current->mm;
-       if (old_mm && old_mm->context.size > 0) {
-               down(&old_mm->context.sem);
-               retval = copy_ldt(&mm->context, &old_mm->context);
-               up(&old_mm->context.sem);
-       }
-       return retval;
-}
-
-/*
- * No need to lock the MM as we are the last user
- * Do not touch the ldt register, we are already
- * in the next thread.
- */
-void destroy_context(struct mm_struct *mm)
-{
-       if (mm->context.size) {
-               make_pages_writable(
-                       mm->context.ldt, 
-                       (mm->context.size*LDT_ENTRY_SIZE)/PAGE_SIZE);
-               if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
-                       vfree(mm->context.ldt);
-               else
-                       kfree(mm->context.ldt);
-               mm->context.size = 0;
-       }
-}
-
-static int read_ldt(void * ptr, unsigned long bytecount)
-{
-       int err;
-       unsigned long size;
-       struct mm_struct * mm = current->mm;
-
-       if (!mm->context.size)
-               return 0;
-       if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
-               bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
-
-       down(&mm->context.sem);
-       size = mm->context.size*LDT_ENTRY_SIZE;
-       if (size > bytecount)
-               size = bytecount;
-
-       err = 0;
-       if (copy_to_user(ptr, mm->context.ldt, size))
-               err = -EFAULT;
-       up(&mm->context.sem);
-       if (err < 0)
-               return err;
-       if (size != bytecount) {
-               /* zero-fill the rest */
-               clear_user(ptr+size, bytecount-size);
-       }
-       return bytecount;
-}
-
-static int read_default_ldt(void * ptr, unsigned long bytecount)
-{
-       int err;
-       unsigned long size;
-       void *address;
-
-       err = 0;
-       address = &default_ldt[0];
-       size = 5*sizeof(struct desc_struct);
-       if (size > bytecount)
-               size = bytecount;
-
-       err = size;
-       if (copy_to_user(ptr, address, size))
-               err = -EFAULT;
-
-       return err;
-}
-
-static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
-{
-       struct mm_struct * mm = current->mm;
-       __u32 entry_1, entry_2, *lp;
-       unsigned long mach_lp;
-       int error;
-       struct modify_ldt_ldt_s ldt_info;
-
-       error = -EINVAL;
-       if (bytecount != sizeof(ldt_info))
-               goto out;
-       error = -EFAULT;        
-       if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
-               goto out;
-
-       error = -EINVAL;
-       if (ldt_info.entry_number >= LDT_ENTRIES)
-               goto out;
-       if (ldt_info.contents == 3) {
-               if (oldmode)
-                       goto out;
-               if (ldt_info.seg_not_present == 0)
-                       goto out;
-       }
-
-       down(&mm->context.sem);
-       if (ldt_info.entry_number >= mm->context.size) {
-               error = alloc_ldt(&current->mm->context, 
ldt_info.entry_number+1, 1);
-               if (error < 0)
-                       goto out_unlock;
-       }
-
-       lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) 
mm->context.ldt);
-       mach_lp = arbitrary_virt_to_machine(lp);
-
-       /* Allow LDTs to be cleared by the user. */
-       if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
-               if (oldmode ||
-                   (ldt_info.contents == 0             &&
-                    ldt_info.read_exec_only == 1       &&
-                    ldt_info.seg_32bit == 0            &&
-                    ldt_info.limit_in_pages == 0       &&
-                    ldt_info.seg_not_present == 1      &&
-                    ldt_info.useable == 0 )) {
-                       entry_1 = 0;
-                       entry_2 = 0;
-                       goto install;
-               }
-       }
-
-       entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
-                 (ldt_info.limit & 0x0ffff);
-       entry_2 = (ldt_info.base_addr & 0xff000000) |
-                 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
-                 (ldt_info.limit & 0xf0000) |
-                 ((ldt_info.read_exec_only ^ 1) << 9) |
-                 (ldt_info.contents << 10) |
-                 ((ldt_info.seg_not_present ^ 1) << 15) |
-                 (ldt_info.seg_32bit << 22) |
-                 (ldt_info.limit_in_pages << 23) |
-                 0x7000;
-       if (!oldmode)
-               entry_2 |= (ldt_info.useable << 20);
-
-       /* Install the new entry ...  */
-install:
-       error = HYPERVISOR_update_descriptor(mach_lp, entry_1, entry_2);
-
-out_unlock:
-       up(&mm->context.sem);
-out:
-       return error;
-}
-
-asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-{
-       int ret = -ENOSYS;
-
-       switch (func) {
-       case 0:
-               ret = read_ldt(ptr, bytecount);
-               break;
-       case 1:
-               ret = write_ldt(ptr, bytecount, 1);
-               break;
-       case 2:
-               ret = read_default_ldt(ptr, bytecount);
-               break;
-       case 0x11:
-               ret = write_ldt(ptr, bytecount, 0);
-               break;
-       }
-       return ret;
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/pci-pc.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/pci-pc.c     Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,260 +0,0 @@
-/*
- *     Low-Level PCI Support for PC
- *
- *     (c) 1999--2000 Martin Mares <mj@xxxxxx>
- *
- * Adjusted to use Xen's interface by Rolf Neugebauer, Intel Research Cambridge
- * Further modifications by Keir Fraser, University of Cambridge
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-
-#include <asm-xen/xen-public/xen.h>
-#include <asm-xen/xen-public/physdev.h>
-
-#include "pci-i386.h"
-
-/*
- * NB. The following interface functions are not included here:
- *  1. void eisa_set_level_irq(unsigned int irq)
- *  2. irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
- *  3. int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
- * All are used by the ACPI driver. This should be ported to Xen if it is
- * ever required -- Xen is the ultimate source for IRQ-routing knowledge.
- */
-
-struct pci_ops *pci_root_ops = NULL;
-
-int (*pci_config_read)(int seg, int bus, int dev, int fn, 
-                       int reg, int len, u32 *value) = NULL;
-int (*pci_config_write)(int seg, int bus, int dev, int fn,
-                        int reg, int len, u32 value) = NULL;
-
-unsigned int pci_probe = PCI_PROBE_BIOS;
-
-struct pci_fixup pcibios_fixups[] = { { 0 } };
-
-static int pci_confx_read(int seg, int bus, int dev, int fn, int reg, 
-                          int len, u32 *value)
-{
-    int ret;
-    physdev_op_t op;
-
-    if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
-        return -EINVAL;
-
-    op.cmd = PHYSDEVOP_PCI_CFGREG_READ;
-    op.u.pci_cfgreg_read.bus  = bus;
-    op.u.pci_cfgreg_read.dev  = dev;
-    op.u.pci_cfgreg_read.func = fn;
-    op.u.pci_cfgreg_read.reg  = reg;
-    op.u.pci_cfgreg_read.len  = len;
-
-    if ( (ret = HYPERVISOR_physdev_op(&op)) != 0 )
-        return ret;
-
-    *value = op.u.pci_cfgreg_read.value;
-
-    return 0;
-}
-
-static int pci_confx_write(int seg, int bus, int dev, int fn, int reg, 
-                           int len, u32 value)
-{
-    int ret;
-    physdev_op_t op;
-
-    if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 
-        return -EINVAL;
-
-    op.cmd = PHYSDEVOP_PCI_CFGREG_WRITE;
-    op.u.pci_cfgreg_write.bus   = bus;
-    op.u.pci_cfgreg_write.dev   = dev;
-    op.u.pci_cfgreg_write.func  = fn;
-    op.u.pci_cfgreg_write.reg   = reg;
-    op.u.pci_cfgreg_write.len   = len;
-    op.u.pci_cfgreg_write.value = value;
-
-    if ( (ret = HYPERVISOR_physdev_op(&op)) != 0 )
-        return ret;
-    return 0;
-}
-
-
-static int pci_confx_read_config_byte(struct pci_dev *dev, 
-                                      int where, u8 *value)
-{
-    int result; 
-    u32 data;
-
-    result = pci_confx_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
-                            PCI_FUNC(dev->devfn), where, 1, &data);
-
-    *value = (u8)data;
-
-    return result;
-}
-
-static int pci_confx_read_config_word(struct pci_dev *dev, 
-                                      int where, u16 *value)
-{
-    int result; 
-    u32 data;
-
-    result = pci_confx_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
-                            PCI_FUNC(dev->devfn), where, 2, &data);
-
-    *value = (u16)data;
-
-    return result;
-}
-
-static int pci_confx_read_config_dword(struct pci_dev *dev, 
-                                       int where, u32 *value)
-{
-    return pci_confx_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
-                          PCI_FUNC(dev->devfn), where, 4, value);
-}
-
-static int pci_confx_write_config_byte(struct pci_dev *dev, 
-                                       int where, u8 value)
-{
-    return pci_confx_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
-                           PCI_FUNC(dev->devfn), where, 1, value);
-}
-
-static int pci_confx_write_config_word(struct pci_dev *dev, 
-                                       int where, u16 value)
-{
-    return pci_confx_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
-                           PCI_FUNC(dev->devfn), where, 2, value);
-}
-
-static int pci_confx_write_config_dword(struct pci_dev *dev, 
-                                        int where, u32 value)
-{
-    return pci_confx_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
-                           PCI_FUNC(dev->devfn), where, 4, value);
-}
-
-static struct pci_ops pci_conf_xen = {
-    pci_confx_read_config_byte,
-    pci_confx_read_config_word,
-    pci_confx_read_config_dword,
-    pci_confx_write_config_byte,
-    pci_confx_write_config_word,
-    pci_confx_write_config_dword
-};
-
-void pcibios_penalize_isa_irq(int irq)
-{ 
-    /* nothing */
-}
-
-void __devinit pcibios_fixup_bus(struct pci_bus *b)
-{
-    pci_read_bridge_bases(b);
-}
-
-struct pci_bus * __devinit pcibios_scan_root(int busnum)
-{
-    struct list_head *list;
-    struct pci_bus *bus;
-
-    list_for_each ( list, &pci_root_buses )
-    {
-        bus = pci_bus_b(list);
-        if ( bus->number == busnum )
-            return bus;
-    }
-
-    printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
-    return pci_scan_bus(busnum, pci_root_ops, NULL);
-}
-
-void __init pcibios_init(void)
-{
-    int bus;
-    physdev_op_t op;
-
-    if ( !pci_probe )
-        return;
-
-    pci_root_ops     = &pci_conf_xen;
-    pci_config_read  = pci_confx_read;
-    pci_config_write = pci_confx_write;
-
-    pcibios_set_cacheline_size();
-
-    op.cmd = PHYSDEVOP_PCI_PROBE_ROOT_BUSES;
-    if ( HYPERVISOR_physdev_op(&op) != 0 )
-    {
-        printk(KERN_WARNING "PCI: System does not support PCI\n");
-        return;
-    }
-
-    printk(KERN_INFO "PCI: Probing PCI hardware\n");
-    for ( bus = 0; bus < 256; bus++ )
-        if ( test_bit(bus, &op.u.pci_probe_root_buses.busmask[0]) )
-            (void)pcibios_scan_root(bus);
-
-    pcibios_resource_survey();
-}
-
-char * __devinit pcibios_setup(char *str)
-{
-    if ( !strcmp(str, "off") )
-        pci_probe = 0;
-    return NULL;
-}
-
-unsigned int pcibios_assign_all_busses(void)
-{
-    return 0;
-}
-
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
-    int err;
-    u8  pin;
-    physdev_op_t op;
-
-    /* Inform Xen that we are going to use this device. */
-    op.cmd = PHYSDEVOP_PCI_INITIALISE_DEVICE;
-    op.u.pci_initialise_device.bus  = dev->bus->number;
-    op.u.pci_initialise_device.dev  = PCI_SLOT(dev->devfn);
-    op.u.pci_initialise_device.func = PCI_FUNC(dev->devfn);
-    if ( (err = HYPERVISOR_physdev_op(&op)) != 0 )
-        return err;
-
-    /* Now we can bind to the very final IRQ line. */
-    pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &pin);
-    dev->irq = pin;
-
-    /* Turn on device I/O and memory access as necessary. */
-    if ( (err = pcibios_enable_resources(dev, mask)) < 0 )
-        return err;
-
-    /* Sanity-check that an interrupt-producing device is routed to an IRQ. */
-    pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-    if ( pin != 0 )
-    {
-        if ( dev->irq != 0 )
-            printk(KERN_INFO "PCI: Obtained IRQ %d for device %s\n",
-                   dev->irq, dev->slot_name);
-        else
-            printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of "
-                   "device %s.\n", 'A' + pin - 1, dev->slot_name);
-    }
-
-    return 0;
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/process.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/process.c    Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,448 +0,0 @@
-/*
- *  linux/arch/i386/kernel/process.c
- *
- *  Copyright (C) 1995  Linus Torvalds
- *
- *  Pentium III FXSR, SSE support
- *     Gareth Hughes <gareth@xxxxxxxxxxx>, May 2000
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
- */
-
-#define __KERNEL_SYSCALLS__
-#include <stdarg.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/config.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/mc146818rtc.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/ldt.h>
-#include <asm/processor.h>
-#include <asm/i387.h>
-#include <asm/desc.h>
-#include <asm/mmu_context.h>
-#include <asm-xen/xen-public/physdev.h>
-
-#include <linux/irq.h>
-
-asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
-
-int hlt_counter;
-
-/*
- * Powermanagement idle function, if any..
- */
-void (*pm_idle)(void);
-
-/*
- * Power off function, if any
- */
-void (*pm_power_off)(void);
-
-void disable_hlt(void)
-{
-    hlt_counter++;
-}
-
-void enable_hlt(void)
-{
-    hlt_counter--;
-}
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle (void)
-{
-    extern int set_timeout_timer(void);
-
-    /* Endless idle loop with no priority at all. */
-    init_idle();
-    current->nice = 20;
-    current->counter = -100;
-
-    for ( ; ; )
-    {
-        while ( !current->need_resched )
-        {
-            __cli();
-            if ( current->need_resched )
-            {
-                /* The race-free check for events failed. */
-                __sti();
-                break;
-            }
-            else if ( set_timeout_timer() == 0 )
-            {
-                /* NB. Blocking reenable events in a race-free manner. */
-                HYPERVISOR_block();
-            }
-            else
-            {
-                /* No race here: yielding will get us the CPU again anyway. */
-                __sti();
-                HYPERVISOR_yield();
-            }
-        }
-        schedule();
-        check_pgt_cache();
-    }
-}
-
-extern void show_trace(unsigned long* esp);
-
-void show_regs(struct pt_regs * regs)
-{
-    printk("\n");
-    printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
-    printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, 
smp_processor_id());
-    if (regs->xcs & 2)
-        printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
-    printk(" EFLAGS: %08lx    %s\n",regs->eflags, print_tainted());
-    printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
-           regs->eax,regs->ebx,regs->ecx,regs->edx);
-    printk("ESI: %08lx EDI: %08lx EBP: %08lx",
-           regs->esi, regs->edi, regs->ebp);
-    printk(" DS: %04x ES: %04x\n",
-           0xffff & regs->xds,0xffff & regs->xes);
-
-    show_trace(&regs->esp);
-}
-
-
-/*
- * Create a kernel thread
- */
-int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-    long retval, d0;
-
-    __asm__ __volatile__(
-        "movl %%esp,%%esi\n\t"
-        "int $0x80\n\t"                /* Linux/i386 system call */
-        "cmpl %%esp,%%esi\n\t" /* child or parent? */
-        "je 1f\n\t"            /* parent - jump */
-        /* Load the argument into eax, and push it.  That way, it does
-         * not matter whether the called function is compiled with
-         * -mregparm or not.  */
-        "movl %4,%%eax\n\t"
-        "pushl %%eax\n\t"              
-        "call *%5\n\t"         /* call fn */
-        "movl %3,%0\n\t"       /* exit */
-        "int $0x80\n"
-        "1:\t"
-        :"=&a" (retval), "=&S" (d0)
-        :"0" (__NR_clone), "i" (__NR_exit),
-        "r" (arg), "r" (fn),
-        "b" (flags | CLONE_VM)
-        : "memory");
-
-    return retval;
-}
-
-/*
- * Free current thread data structures etc..
- */
-void exit_thread(void)
-{
-    /* nothing to do ... */
-}
-
-void flush_thread(void)
-{
-    struct task_struct *tsk = current;
-
-    memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
-
-    /*
-     * Forget coprocessor state..
-     */
-    clear_fpu(tsk);
-    tsk->used_math = 0;
-}
-
-void release_thread(struct task_struct *dead_task)
-{
-    if (dead_task->mm) {
-        // temporary debugging check
-        if (dead_task->mm->context.size) {
-            printk("WARNING: dead process %8s still has LDT? <%p/%08x>\n",
-                   dead_task->comm, 
-                  dead_task->mm->context.ldt,
-                  dead_task->mm->context.size);
-            BUG();
-        }
-    }
-    //release_x86_irqs(dead_task);
-}
-
-
-/*
- * Save a segment.
- */
-#define savesegment(seg,value) \
-       asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value)))
-
-int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
-                unsigned long unused,
-                struct task_struct * p, struct pt_regs * regs)
-{
-    struct pt_regs * childregs;
-
-    childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
-    struct_cpy(childregs, regs);
-    childregs->eax = 0;
-    childregs->esp = esp;
-
-    p->thread.esp = (unsigned long) childregs;
-    p->thread.esp0 = (unsigned long) (childregs+1);
-
-    p->thread.eip = (unsigned long) ret_from_fork;
-
-    savesegment(fs,p->thread.fs);
-    savesegment(gs,p->thread.gs);
-
-    unlazy_fpu(current);
-    struct_cpy(&p->thread.i387, &current->thread.i387);
-
-    p->thread.io_pl = current->thread.io_pl;
-
-    return 0;
-}
-
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-    int i;
-
-/* changed the size calculations - should hopefully work better. lbt */
-    dump->magic = CMAGIC;
-    dump->start_code = 0;
-    dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
-    dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
-    dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> 
PAGE_SHIFT;
-    dump->u_dsize -= dump->u_tsize;
-    dump->u_ssize = 0;
-    for (i = 0; i < 8; i++)
-        dump->u_debugreg[i] = current->thread.debugreg[i];  
-
-    if (dump->start_stack < TASK_SIZE)
-        dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> 
PAGE_SHIFT;
-
-    dump->regs.ebx = regs->ebx;
-    dump->regs.ecx = regs->ecx;
-    dump->regs.edx = regs->edx;
-    dump->regs.esi = regs->esi;
-    dump->regs.edi = regs->edi;
-    dump->regs.ebp = regs->ebp;
-    dump->regs.eax = regs->eax;
-    dump->regs.ds = regs->xds;
-    dump->regs.es = regs->xes;
-    savesegment(fs,dump->regs.fs);
-    savesegment(gs,dump->regs.gs);
-    dump->regs.orig_eax = regs->orig_eax;
-    dump->regs.eip = regs->eip;
-    dump->regs.cs = regs->xcs;
-    dump->regs.eflags = regs->eflags;
-    dump->regs.esp = regs->esp;
-    dump->regs.ss = regs->xss;
-
-    dump->u_fpvalid = dump_fpu (regs, &dump->i387);
-}
-
-/*
- *     switch_to(x,yn) should switch tasks from x to y.
- *
- * We fsave/fwait so that an exception goes off at the right time
- * (as a call from the fsave or fwait in effect) rather than to
- * the wrong process. Lazy FP saving no longer makes any sense
- * with modern CPU's, and this simplifies a lot of things (SMP
- * and UP become the same).
- *
- * NOTE! We used to use the x86 hardware context switching. The
- * reason for not using it any more becomes apparent when you
- * try to recover gracefully from saved state that is no longer
- * valid (stale segment register values in particular). With the
- * hardware task-switch, there is no way to fix up bad state in
- * a reasonable manner.
- *
- * The fact that Intel documents the hardware task-switching to
- * be slow is a fairly red herring - this code is not noticeably
- * faster. However, there _is_ some room for improvement here,
- * so the performance issues may eventually be a valid point.
- * More important, however, is the fact that this allows us much
- * more flexibility.
- */
-void fastcall __switch_to(struct task_struct *prev_p, struct task_struct 
*next_p)
-{
-    struct thread_struct *next = &next_p->thread;
-    physdev_op_t op;
-    multicall_entry_t _mcl[8], *mcl = _mcl;
-
-    /*
-     * This is basically 'unlazy_fpu', except that we queue a multicall to 
-     * indicate FPU task switch, rather than synchronously trapping to Xen.
-     */
-    if ( prev_p->flags & PF_USEDFPU )
-    {
-       if ( cpu_has_fxsr )
-            asm volatile( "fxsave %0 ; fnclex"
-                          : "=m" (prev_p->thread.i387.fxsave) );
-       else
-            asm volatile( "fnsave %0 ; fwait"
-                          : "=m" (prev_p->thread.i387.fsave) );
-       prev_p->flags &= ~PF_USEDFPU;
-        mcl->op      = __HYPERVISOR_fpu_taskswitch;
-        mcl->args[0] = 1;
-        mcl++;
-    }
-
-    mcl->op      = __HYPERVISOR_stack_switch;
-    mcl->args[0] = __KERNEL_DS;
-    mcl->args[1] = next->esp0;
-    mcl++;
-
-    if ( prev_p->thread.io_pl != next->io_pl ) 
-    {
-        op.cmd             = PHYSDEVOP_SET_IOPL;
-       op.u.set_iopl.iopl = next->io_pl;
-        mcl->op      = __HYPERVISOR_physdev_op;
-        mcl->args[0] = (unsigned long)&op;
-        mcl++;
-    }
-
-    (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
-
-    /*
-     * Restore %fs and %gs.
-     */
-    loadsegment(fs, next->fs);
-    loadsegment(gs, next->gs);
-
-    /*
-     * Now maybe reload the debug registers
-     */
-    if ( next->debugreg[7] != 0 )
-    {
-        HYPERVISOR_set_debugreg(0, next->debugreg[0]);
-        HYPERVISOR_set_debugreg(1, next->debugreg[1]);
-        HYPERVISOR_set_debugreg(2, next->debugreg[2]);
-        HYPERVISOR_set_debugreg(3, next->debugreg[3]);
-        /* no 4 and 5 */
-        HYPERVISOR_set_debugreg(6, next->debugreg[6]);
-        HYPERVISOR_set_debugreg(7, next->debugreg[7]);
-    }
-}
-
-asmlinkage int sys_fork(struct pt_regs regs)
-{
-    return do_fork(SIGCHLD, regs.esp, &regs, 0);
-}
-
-asmlinkage int sys_clone(struct pt_regs regs)
-{
-    unsigned long clone_flags;
-    unsigned long newsp;
-
-    clone_flags = regs.ebx;
-    newsp = regs.ecx;
-    if (!newsp)
-        newsp = regs.esp;
-    return do_fork(clone_flags, newsp, &regs, 0);
-}
-
-/*
- * This is trivial, and on the face of it looks like it
- * could equally well be done in user mode.
- *
- * Not so, for quite unobvious reasons - register pressure.
- * In user mode vfork() cannot have a stack frame, and if
- * done by calling the "clone()" system call directly, you
- * do not have enough call-clobbered registers to hold all
- * the information you need.
- */
-asmlinkage int sys_vfork(struct pt_regs regs)
-{
-    return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0);
-}
-
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(struct pt_regs regs)
-{
-    int error;
-    char * filename;
-
-    filename = getname((char *) regs.ebx);
-    error = PTR_ERR(filename);
-    if (IS_ERR(filename))
-        goto out;
-    error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);
-    if (error == 0)
-        current->ptrace &= ~PT_DTRACE;
-    putname(filename);
- out:
-    return error;
-}
-
-/*
- * These bracket the sleeping functions..
- */
-extern void scheduling_functions_start_here(void);
-extern void scheduling_functions_end_here(void);
-#define first_sched    ((unsigned long) scheduling_functions_start_here)
-#define last_sched     ((unsigned long) scheduling_functions_end_here)
-
-unsigned long get_wchan(struct task_struct *p)
-{
-    unsigned long ebp, esp, eip;
-    unsigned long stack_page;
-    int count = 0;
-    if (!p || p == current || p->state == TASK_RUNNING)
-        return 0;
-    stack_page = (unsigned long)p;
-    esp = p->thread.esp;
-    if (!stack_page || esp < stack_page || esp > 8188+stack_page)
-        return 0;
-    /* include/asm-i386/system.h:switch_to() pushes ebp last. */
-    ebp = *(unsigned long *) esp;
-    do {
-        if (ebp < stack_page || ebp > 8184+stack_page)
-            return 0;
-        eip = *(unsigned long *) (ebp+4);
-        if (eip < first_sched || eip >= last_sched)
-            return eip;
-        ebp = *(unsigned long *) ebp;
-    } while (count++ < 16);
-    return 0;
-}
-#undef last_sched
-#undef first_sched
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/setup.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/setup.c      Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,1213 +0,0 @@
-/*
- *  linux/arch/i386/kernel/setup.c
- *
- *  Copyright (C) 1995  Linus Torvalds
- */
-
-/*
- * This file handles the architecture-dependent parts of initialization
- */
-
-#define __KERNEL_SYSCALLS__
-static int errno;
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/apm_bios.h>
-#ifdef CONFIG_BLK_DEV_RAM
-#include <linux/blk.h>
-#endif
-#include <linux/highmem.h>
-#include <linux/bootmem.h>
-#include <linux/seq_file.h>
-#include <linux/reboot.h>
-#include <asm/processor.h>
-#include <linux/console.h>
-#include <linux/module.h>
-#include <asm/mtrr.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/msr.h>
-#include <asm/desc.h>
-#include <asm/dma.h>
-#include <asm/mpspec.h>
-#include <asm/mmu_context.h>
-#include <asm/ctrl_if.h>
-#include <asm/hypervisor.h>
-#include <asm-xen/xen-public/physdev.h>
-#include <linux/netdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/tqueue.h>
-#include <net/pkt_sched.h> /* dev_(de)activate */
-
-/*
- * Point at the empty zero page to start with. We map the real shared_info
- * page as soon as fixmap is up and running.
- */
-shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
-
-unsigned int *phys_to_machine_mapping, *pfn_to_mfn_frame_list;
-
-/*
- * Machine setup..
- */
-
-char ignore_irq13;             /* set if exception 16 works */
-struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
-
-unsigned long mmu_cr4_features;
-
-unsigned char * vgacon_mmap;
-
-/*
- * Bus types ..
- */
-#ifdef CONFIG_EISA
-int EISA_bus;
-#endif
-int MCA_bus;
-
-/* for MCA, but anyone else can use it if they want */
-unsigned int machine_id;
-unsigned int machine_submodel_id;
-unsigned int BIOS_revision;
-unsigned int mca_pentium_flag;
-
-/* For PCI or other memory-mapped resources */
-unsigned long pci_mem_start = 0x10000000;
-
-/*
- * Setup options
- */
-struct drive_info_struct { char dummy[32]; } drive_info;
-struct screen_info screen_info;
-struct apm_info apm_info;
-struct sys_desc_table_struct {
-    unsigned short length;
-    unsigned char table[0];
-};
-
-unsigned char aux_device_present;
-
-extern int root_mountflags;
-extern char _text, _etext, _edata, _end;
-
-extern int blk_nohighio;
-
-int enable_acpi_smp_table;
-
-/* Raw start-of-day parameters from the hypervisor. */
-union xen_start_info_union xen_start_info_union;
-
-#define COMMAND_LINE_SIZE MAX_GUEST_CMDLINE
-static char command_line[COMMAND_LINE_SIZE];
-char saved_command_line[COMMAND_LINE_SIZE];
-
-/* parse_mem_cmdline()
- * returns the value of the mem= boot param converted to pages or 0
- */ 
-static int __init parse_mem_cmdline (char ** cmdline_p)
-{
-    char c = ' ', *to = command_line, *from = saved_command_line;
-    int len = 0;
-    unsigned long long bytes;
-    int mem_param = 0;
-
-    /* Save unparsed command line copy for /proc/cmdline */
-    memcpy(saved_command_line, xen_start_info.cmd_line, COMMAND_LINE_SIZE);
-    saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-
-    for (;;) {
-        /*
-         * "mem=nopentium" disables the 4MB page tables.
-         * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
-         * to <mem>, overriding the bios size.
-         * "mem=XXX[KkmM]@XXX[KkmM]" defines a memory region from
-         * <start> to <start>+<mem>, overriding the bios size.
-         */
-        if (c == ' ' && !memcmp(from, "mem=", 4)) {
-            if (to != command_line)
-                to--;
-            if (!memcmp(from+4, "nopentium", 9)) {
-                from += 9+4;
-            } else if (!memcmp(from+4, "exactmap", 8)) {
-                from += 8+4;
-            } else {
-                bytes = memparse(from+4, &from);
-                mem_param = bytes>>PAGE_SHIFT;
-               if (*from == '@')
-                    (void)memparse(from+1, &from);
-            }
-        }
-
-        c = *(from++);
-        if (!c)
-            break;
-        if (COMMAND_LINE_SIZE <= ++len)
-            break;
-        *(to++) = c;
-    }
-    *to = '\0';
-    *cmdline_p = command_line;
-
-    return mem_param;
-}
-
-/*
- * Every exception-fixup table is sorted (i.e., kernel main table, and every
- * module table. Some elements may be out of order if they reference text.init,
- * for example. 
- */
-static void sort_exception_table(struct exception_table_entry *start,
-                                 struct exception_table_entry *end)
-{
-    struct exception_table_entry *p, *q, tmp;
-
-    for ( p = start; p < end; p++ )
-    {
-        for ( q = p-1; q > start; q-- )
-            if ( p->insn > q->insn )
-                break;
-        if ( ++q != p )
-        {
-            tmp = *p;
-            memmove(q+1, q, (p-q)*sizeof(*p));
-            *q = tmp;
-        }
-    }
-}
-
-int xen_module_init(struct module *mod)
-{
-    sort_exception_table(mod->ex_table_start, mod->ex_table_end);
-    return 0;
-}
-
-void __init setup_arch(char **cmdline_p)
-{
-    int i,j;
-    unsigned long bootmap_size, start_pfn, lmax_low_pfn;
-    int mem_param;  /* user specified memory size in pages */
-    int boot_pfn;   /* low pages available for bootmem */
-    physdev_op_t op;
-
-    extern void hypervisor_callback(void);
-    extern void failsafe_callback(void);
-
-    extern unsigned long cpu0_pte_quicklist[];
-    extern unsigned long cpu0_pgd_quicklist[];
-
-    extern const struct exception_table_entry __start___ex_table[];
-    extern const struct exception_table_entry __stop___ex_table[];
-
-    extern char _stext;
-
-    /* Force a quick death if the kernel panics. */
-    extern int panic_timeout;
-    if ( panic_timeout == 0 )
-        panic_timeout = 1;
-
-    /* Ensure that the kernel exception-fixup table is sorted. */
-    sort_exception_table(__start___ex_table, __stop___ex_table);
-
-#ifndef CONFIG_HIGHIO
-    blk_nohighio = 1;
-#endif
-
-    HYPERVISOR_vm_assist(
-        VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
-    HYPERVISOR_vm_assist(
-        VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
-        
-    HYPERVISOR_set_callbacks(
-        __KERNEL_CS, (unsigned long)hypervisor_callback,
-        __KERNEL_CS, (unsigned long)failsafe_callback);
-
-    boot_cpu_data.pgd_quick = cpu0_pgd_quicklist;
-    boot_cpu_data.pte_quick = cpu0_pte_quicklist;
-
-    /* This must be initialized to UNNAMED_MAJOR for ipconfig to work
-       properly.  Setting ROOT_DEV to default to /dev/ram0 breaks initrd. */
-    ROOT_DEV = MKDEV(UNNAMED_MAJOR,0);
-    memset(&drive_info, 0, sizeof(drive_info));
-    memset(&screen_info, 0, sizeof(screen_info));
-    
-    /* This is drawn from a dump from vgacon:startup in standard Linux. */
-    screen_info.orig_video_mode = 3; 
-    screen_info.orig_video_isVGA = 1;
-    screen_info.orig_video_lines = 25;
-    screen_info.orig_video_cols = 80;
-    screen_info.orig_video_ega_bx = 3;
-    screen_info.orig_video_points = 16;
-
-    memset(&apm_info.bios, 0, sizeof(apm_info.bios));
-    aux_device_present = 0; 
-#ifdef CONFIG_BLK_DEV_RAM
-    rd_image_start = 0;
-    rd_prompt = 0;
-    rd_doload = 0;
-#endif
-
-    root_mountflags &= ~MS_RDONLY;
-    init_mm.start_code = (unsigned long) &_text;
-    init_mm.end_code = (unsigned long) &_etext;
-    init_mm.end_data = (unsigned long) &_edata;
-    init_mm.brk = (unsigned long) &_end;
-
-    /* The mem= kernel command line param overrides the detected amount
-     * of memory.   For xenolinux, if this override is larger than detected
-     * memory, then boot using only detected memory and make provisions to
-     * use all of the override value.   The hypervisor can give this
-     * domain more memory later on and it will be added to the free
-     * lists at that time.   See claim_new_pages() in
-     * arch/xen/drivers/balloon/balloon.c
-     */
-    mem_param = parse_mem_cmdline(cmdline_p);
-    if (mem_param < xen_start_info.nr_pages)
-        mem_param = xen_start_info.nr_pages;
-
-#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)    ((x) << PAGE_SHIFT)
-
-/*
- * 128MB for vmalloc(), iomap(), kmap(), and fixaddr mappings.
- */
-#define VMALLOC_RESERVE        (unsigned long)(128 << 20)
-#define MAXMEM         (unsigned 
long)(HYPERVISOR_VIRT_START-PAGE_OFFSET-VMALLOC_RESERVE)
-#define MAXMEM_PFN     PFN_DOWN(MAXMEM)
-#define MAX_NONPAE_PFN (1 << 20)
-
-    /*
-     * Determine low and high memory ranges:
-     */
-    lmax_low_pfn = max_pfn = mem_param;
-    if (lmax_low_pfn > MAXMEM_PFN) {
-        lmax_low_pfn = MAXMEM_PFN;
-#ifndef CONFIG_HIGHMEM
-        /* Maximum memory usable is what is directly addressable */
-        printk(KERN_WARNING "Warning only %ldMB will be used.\n",
-               MAXMEM>>20);
-        if (max_pfn > MAX_NONPAE_PFN)
-            printk(KERN_WARNING "Use a PAE enabled kernel.\n");
-        else
-            printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
-        max_pfn = lmax_low_pfn;
-#else /* !CONFIG_HIGHMEM */
-#ifndef CONFIG_X86_PAE
-        if (max_pfn > MAX_NONPAE_PFN) {
-            max_pfn = MAX_NONPAE_PFN;
-            printk(KERN_WARNING "Warning only 4GB will be used.\n");
-            printk(KERN_WARNING "Use a PAE enabled kernel.\n");
-        }
-#endif /* !CONFIG_X86_PAE */
-#endif /* !CONFIG_HIGHMEM */
-    }
-
-#ifdef CONFIG_HIGHMEM
-    highstart_pfn = highend_pfn = max_pfn;
-    if (max_pfn > MAXMEM_PFN) {
-        highstart_pfn = MAXMEM_PFN;
-        printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
-               pages_to_mb(highend_pfn - highstart_pfn));
-    }
-#endif
-
-    phys_to_machine_mapping = (unsigned int *)xen_start_info.mfn_list;
-    cur_pgd = init_mm.pgd = (pgd_t *)xen_start_info.pt_base;
-
-    start_pfn = (__pa(xen_start_info.pt_base) >> PAGE_SHIFT) + 
-        xen_start_info.nr_pt_frames;
-
-    /*
-     * Initialize the boot-time allocator, and free up all RAM. Then reserve 
-     * space for OS image, initrd, phys->machine table, bootstrap page table,
-     * and the bootmem bitmap. 
-     * NB. There is definitely enough room for the bootmem bitmap in the
-     * bootstrap page table. We are guaranteed to get >=512kB unused 'padding'
-     * for our own use after all bootstrap elements 
-     * (see asm-xen/xen-public/xen.h).
-     */
-    boot_pfn = min((int)xen_start_info.nr_pages,lmax_low_pfn);
-    bootmap_size = init_bootmem(start_pfn,boot_pfn);
-    free_bootmem(0, PFN_PHYS(boot_pfn));
-    reserve_bootmem(__pa(&_stext), 
-                    PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE-1 - 
-                    __pa(&_stext));
-
-    /* init_bootmem() set the global max_low_pfn to boot_pfn.  Now max_low_pfn 
-     * can be set to the override value.
-     */
-    max_low_pfn = lmax_low_pfn;
-
-#ifdef CONFIG_BLK_DEV_INITRD
-    if ( xen_start_info.mod_start != 0 )
-    {
-        if ( (__pa(xen_start_info.mod_start) + xen_start_info.mod_len) <= 
-             (max_low_pfn << PAGE_SHIFT) )
-        {
-            initrd_start = xen_start_info.mod_start;
-            initrd_end   = initrd_start + xen_start_info.mod_len;
-            initrd_below_start_ok = 1;
-        }
-        else
-        {
-            printk(KERN_ERR "initrd extends beyond end of memory "
-                   "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-                   __pa(xen_start_info.mod_start) + xen_start_info.mod_len,
-                   max_low_pfn << PAGE_SHIFT);
-            initrd_start = 0;
-        }
-    }
-#endif
-
-    paging_init();
-
-    /* Make sure we have a correctly sized P->M table. */
-    if ( max_pfn != xen_start_info.nr_pages )
-    {
-        phys_to_machine_mapping = alloc_bootmem_low_pages(
-            max_pfn * sizeof(unsigned long));
-        if ( max_pfn > xen_start_info.nr_pages )
-        {
-            memset(phys_to_machine_mapping, ~0,
-                   max_pfn * sizeof(unsigned long));
-            memcpy(phys_to_machine_mapping,
-                   (unsigned long *)xen_start_info.mfn_list,
-                   xen_start_info.nr_pages * sizeof(unsigned long));
-        }
-        else
-        {
-            memcpy(phys_to_machine_mapping,
-                   (unsigned long *)xen_start_info.mfn_list,
-                   max_pfn * sizeof(unsigned long));
-            if (HYPERVISOR_dom_mem_op(
-                MEMOP_decrease_reservation,
-                (unsigned long *)xen_start_info.mfn_list + max_pfn,
-                xen_start_info.nr_pages - max_pfn, 0) !=
-                (xen_start_info.nr_pages - max_pfn))
-                BUG();
-        }
-        free_bootmem(__pa(xen_start_info.mfn_list), 
-                     PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
-                                     sizeof(unsigned long))));
-    }
-
-    pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
-    for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
-    {  
-        pfn_to_mfn_frame_list[j] = 
-            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
-    }
-    HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
-       virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
-
-    op.cmd             = PHYSDEVOP_SET_IOPL;
-    op.u.set_iopl.iopl = current->thread.io_pl = 1;
-    HYPERVISOR_physdev_op(&op);
-
-    if (xen_start_info.flags & SIF_INITDOMAIN )
-    {
-        if( !(xen_start_info.flags & SIF_PRIVILEGED) )
-            panic("Xen granted us console access but not privileged status");
-
-#if defined(CONFIG_VT)
-#if defined(CONFIG_VGA_CONSOLE)
-        conswitchp = &vga_con;
-#elif defined(CONFIG_DUMMY_CONSOLE)
-        conswitchp = &dummy_con;
-#endif
-#endif
-    }
-}
-
-static int cachesize_override __initdata = -1;
-static int __init cachesize_setup(char *str)
-{
-    get_option (&str, &cachesize_override);
-    return 1;
-}
-__setup("cachesize=", cachesize_setup);
-
-static int __init highio_setup(char *str)
-{
-    printk("i386: disabling HIGHMEM block I/O\n");
-    blk_nohighio = 1;
-    return 1;
-}
-__setup("nohighio", highio_setup);
-
-static int __init get_model_name(struct cpuinfo_x86 *c)
-{
-    unsigned int *v;
-    char *p, *q;
-
-    if (cpuid_eax(0x80000000) < 0x80000004)
-        return 0;
-
-    v = (unsigned int *) c->x86_model_id;
-    cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
-    cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
-    cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
-    c->x86_model_id[48] = 0;
-
-    /* Intel chips right-justify this string for some dumb reason;
-       undo that brain damage */
-    p = q = &c->x86_model_id[0];
-    while ( *p == ' ' )
-        p++;
-    if ( p != q ) {
-        while ( *p )
-            *q++ = *p++;
-        while ( q <= &c->x86_model_id[48] )
-            *q++ = '\0';       /* Zero-pad the rest */
-    }
-
-    return 1;
-}
-
-
-static void __init display_cacheinfo(struct cpuinfo_x86 *c)
-{
-    unsigned int n, dummy, ecx, edx, l2size;
-
-    n = cpuid_eax(0x80000000);
-
-    if (n >= 0x80000005) {
-        cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
-        printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK 
(%d bytes/line)\n",
-               edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
-        c->x86_cache_size=(ecx>>24)+(edx>>24); 
-    }
-
-    if (n < 0x80000006)        /* Some chips just has a large L1. */
-        return;
-
-    ecx = cpuid_ecx(0x80000006);
-    l2size = ecx >> 16;
-
-    /* AMD errata T13 (order #21922) */
-    if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
-        if (c->x86_model == 3 && c->x86_mask == 0)     /* Duron Rev A0 */
-            l2size = 64;
-        if (c->x86_model == 4 &&
-            (c->x86_mask==0 || c->x86_mask==1))        /* Tbird rev A1/A2 */
-            l2size = 256;
-    }
-
-    /* Intel PIII Tualatin. This comes in two flavours.
-     * One has 256kb of cache, the other 512. We have no way
-     * to determine which, so we use a boottime override
-     * for the 512kb model, and assume 256 otherwise.
-     */
-    if ((c->x86_vendor == X86_VENDOR_INTEL) && (c->x86 == 6) &&
-        (c->x86_model == 11) && (l2size == 0))
-        l2size = 256;
-
-    if (c->x86_vendor == X86_VENDOR_CENTAUR) {
-       /* VIA C3 CPUs (670-68F) need further shifting. */
-       if ((c->x86 == 6) &&
-           ((c->x86_model == 7) || (c->x86_model == 8))) {
-               l2size >>= 8;
-       }
-
-       /* VIA also screwed up Nehemiah stepping 1, and made
-          it return '65KB' instead of '64KB'
-          - Note, it seems this may only be in engineering samples. */
-       if ((c->x86==6) && (c->x86_model==9) &&
-           (c->x86_mask==1) && (l2size==65))
-               l2size -= 1;
-    }
-
-    /* Allow user to override all this if necessary. */
-    if (cachesize_override != -1)
-        l2size = cachesize_override;
-
-    if ( l2size == 0 )
-        return;                /* Again, no L2 cache is possible */
-
-    c->x86_cache_size = l2size;
-
-    printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
-           l2size, ecx & 0xFF);
-}
-
-static void __init init_c3(struct cpuinfo_x86 *c)
-{
-    /* Test for Centaur Extended Feature Flags presence */
-    if (cpuid_eax(0xC0000000) >= 0xC0000001) {
-        /* store Centaur Extended Feature Flags as
-         * word 5 of the CPU capability bit array
-         */
-        c->x86_capability[5] = cpuid_edx(0xC0000001);
-    }
-   
-    switch (c->x86_model) {
-    case 9:    /* Nehemiah */
-    default:
-        get_model_name(c);
-        display_cacheinfo(c);
-        break;
-    }
-}
-
-static void __init init_centaur(struct cpuinfo_x86 *c)
-{
-    /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
-       3DNow is IDd by bit 31 in extended CPUID (1*3231) anyway */
-    clear_bit(0*32+31, &c->x86_capability);
-  
-    switch (c->x86) {
-    case 6:
-        init_c3(c);
-        break;
-    default:
-        panic("Unsupported Centaur CPU (%i)\n", c->x86);
-    }
-}
-
-static int __init init_amd(struct cpuinfo_x86 *c)
-{
-    int r;
-
-    /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
-       3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
-    clear_bit(0*32+31, &c->x86_capability);
-       
-    r = get_model_name(c);
-
-    switch(c->x86)
-    {
-    case 5: /* We don't like AMD K6 */
-        panic("Unsupported AMD processor\n");
-    case 6:    /* An Athlon/Duron. We can trust the BIOS probably */
-        break;
-    }
-
-    display_cacheinfo(c);
-    return r;
-}
-
-
-static void __init init_intel(struct cpuinfo_x86 *c)
-{
-    char *p = NULL;
-    unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
-
-    if (c->cpuid_level > 1) {
-        /* supports eax=2  call */
-        int i, j, n;
-        int regs[4];
-        unsigned char *dp = (unsigned char *)regs;
-
-        /* Number of times to iterate */
-        n = cpuid_eax(2) & 0xFF;
-
-        for ( i = 0 ; i < n ; i++ ) {
-            cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
-                       
-            /* If bit 31 is set, this is an unknown format */
-            for ( j = 0 ; j < 3 ; j++ ) {
-                if ( regs[j] < 0 ) regs[j] = 0;
-            }
-
-            /* Byte 0 is level count, not a descriptor */
-            for ( j = 1 ; j < 16 ; j++ ) {
-                unsigned char des = dp[j];
-                unsigned char dl, dh;
-                unsigned int cs;
-
-                dh = des >> 4;
-                dl = des & 0x0F;
-
-                               /* Black magic... */
-
-                switch ( dh )
-                {
-                case 0:
-                    switch ( dl ) {
-                    case 6:
-                        /* L1 I cache */
-                        l1i += 8;
-                        break;
-                    case 8:
-                        /* L1 I cache */
-                        l1i += 16;
-                        break;
-                    case 10:
-                        /* L1 D cache */
-                        l1d += 8;
-                        break;
-                    case 12:
-                        /* L1 D cache */
-                        l1d += 16;
-                        break;
-                    default:;
-                        /* TLB, or unknown */
-                    }
-                    break;
-                case 2:
-                    if ( dl ) {
-                        /* L3 cache */
-                        cs = (dl-1) << 9;
-                        l3 += cs;
-                    }
-                    break;
-                case 4:
-                    if ( c->x86 > 6 && dl ) {
-                        /* P4 family */
-                        /* L3 cache */
-                        cs = 128 << (dl-1);
-                        l3 += cs;
-                        break;
-                    }
-                    /* else same as 8 - fall through */
-                case 8:
-                    if ( dl ) {
-                        /* L2 cache */
-                        cs = 128 << (dl-1);
-                        l2 += cs;
-                    }
-                    break;
-                case 6:
-                    if (dl > 5) {
-                        /* L1 D cache */
-                        cs = 8<<(dl-6);
-                        l1d += cs;
-                    }
-                    break;
-                case 7:
-                    if ( dl >= 8 ) 
-                    {
-                        /* L2 cache */
-                        cs = 64<<(dl-8);
-                        l2 += cs;
-                    } else {
-                        /* L0 I cache, count as L1 */
-                        cs = dl ? (16 << (dl-1)) : 12;
-                        l1i += cs;
-                    }
-                    break;
-                default:
-                    /* TLB, or something else we don't know about */
-                    break;
-                }
-            }
-        }
-        if ( l1i || l1d )
-            printk(KERN_INFO "CPU: L1 I cache: %dK, L1 D cache: %dK\n",
-                   l1i, l1d);
-        if ( l2 )
-            printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
-        if ( l3 )
-            printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
-
-        /*
-         * This assumes the L3 cache is shared; it typically lives in
-         * the northbridge.  The L1 caches are included by the L2
-         * cache, and so should not be included for the purpose of
-         * SMP switching weights.
-         */
-        c->x86_cache_size = l2 ? l2 : (l1i+l1d);
-    }
-
-    /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it */
-    if ( c->x86 == 6 && c->x86_model < 3 && c->x86_mask < 3 )
-        clear_bit(X86_FEATURE_SEP, &c->x86_capability);
-       
-    /* Names for the Pentium II/Celeron processors 
-       detectable only by also checking the cache size.
-       Dixon is NOT a Celeron. */
-    if (c->x86 == 6) {
-        switch (c->x86_model) {
-        case 5:
-            if (l2 == 0)
-                p = "Celeron (Covington)";
-            if (l2 == 256)
-                p = "Mobile Pentium II (Dixon)";
-            break;
-                       
-        case 6:
-            if (l2 == 128)
-                p = "Celeron (Mendocino)";
-            break;
-                       
-        case 8:
-            if (l2 == 128)
-                p = "Celeron (Coppermine)";
-            break;
-        }
-    }
-
-    if ( p )
-        strcpy(c->x86_model_id, p);
-}
-
-void __init get_cpu_vendor(struct cpuinfo_x86 *c)
-{
-    char *v = c->x86_vendor_id;
-
-    if (!strcmp(v, "GenuineIntel"))
-        c->x86_vendor = X86_VENDOR_INTEL;
-    else if (!strcmp(v, "AuthenticAMD"))
-        c->x86_vendor = X86_VENDOR_AMD;
-    else if (!strcmp(v, "CentaurHauls"))
-        c->x86_vendor = X86_VENDOR_CENTAUR;
-    else
-        c->x86_vendor = X86_VENDOR_UNKNOWN;
-}
-
-struct cpu_model_info {
-    int vendor;
-    int family;
-    char *model_names[16];
-};
-
-/* Naming convention should be: <Name> [(<Codename>)] */
-/* This table only is used unless init_<vendor>() below doesn't set it; */
-/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used 
*/
-static struct cpu_model_info cpu_models[] __initdata = {
-    { X86_VENDOR_INTEL,        6,
-      { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", 
-        NULL, "Pentium II (Deschutes)", "Mobile Pentium II",
-        "Pentium III (Katmai)", "Pentium III (Coppermine)", NULL,
-        "Pentium III (Cascades)", NULL, NULL, NULL, NULL }},
-    { X86_VENDOR_AMD,  6, /* Is this this really necessary?? */
-      { "Athlon", "Athlon",
-        "Athlon", NULL, "Athlon", NULL,
-        NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL }}
-};
-
-/* Look up CPU names by table lookup. */
-static char __init *table_lookup_model(struct cpuinfo_x86 *c)
-{
-    struct cpu_model_info *info = cpu_models;
-    int i;
-
-    if ( c->x86_model >= 16 )
-        return NULL;   /* Range check */
-
-    for ( i = 0 ; i < sizeof(cpu_models)/sizeof(struct cpu_model_info) ; i++ ) 
{
-        if ( info->vendor == c->x86_vendor &&
-             info->family == c->x86 ) {
-            return info->model_names[c->x86_model];
-        }
-        info++;
-    }
-    return NULL;               /* Not found */
-}
-
-
-
-/* Standard macro to see if a specific flag is changeable */
-static inline int flag_is_changeable_p(u32 flag)
-{
-    u32 f1, f2;
-
-    asm("pushfl\n\t"
-        "pushfl\n\t"
-        "popl %0\n\t"
-        "movl %0,%1\n\t"
-        "xorl %2,%0\n\t"
-        "pushl %0\n\t"
-        "popfl\n\t"
-        "pushfl\n\t"
-        "popl %0\n\t"
-        "popfl\n\t"
-        : "=&r" (f1), "=&r" (f2)
-        : "ir" (flag));
-
-    return ((f1^f2) & flag) != 0;
-}
-
-
-/* Probe for the CPUID instruction */
-static int __init have_cpuid_p(void)
-{
-    return flag_is_changeable_p(X86_EFLAGS_ID);
-}
-
-
-
-#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-unsigned char eddnr;
-struct edd_info edd[EDDMAXNR];
-unsigned int edd_disk80_sig;
-/**
- * copy_edd() - Copy the BIOS EDD information
- *              from empty_zero_page into a safe place.
- *
- */
-static inline void copy_edd(void)
-{
-     eddnr = EDD_NR;
-     memcpy(edd, EDD_BUF, sizeof(edd));
-     edd_disk80_sig = DISK80_SIGNATURE_BUFFER;
-}
-#else
-static inline void copy_edd(void) {}
-#endif
-
-/*
- * This does the hard work of actually picking apart the CPU stuff...
- */
-void __init identify_cpu(struct cpuinfo_x86 *c)
-{
-    int junk, i;
-    u32 xlvl, tfms;
-
-    c->loops_per_jiffy = loops_per_jiffy;
-    c->x86_cache_size = -1;
-    c->x86_vendor = X86_VENDOR_UNKNOWN;
-    c->cpuid_level = -1;       /* CPUID not detected */
-    c->x86_model = c->x86_mask = 0;    /* So far unknown... */
-    c->x86_vendor_id[0] = '\0'; /* Unset */
-    c->x86_model_id[0] = '\0';  /* Unset */
-    memset(&c->x86_capability, 0, sizeof c->x86_capability);
-    c->hard_math = 1;
-
-    if ( !have_cpuid_p() ) {
-        panic("Processor must support CPUID\n");
-    } else {
-        /* CPU does have CPUID */
-
-        /* Get vendor name */
-        cpuid(0x00000000, &c->cpuid_level,
-              (int *)&c->x86_vendor_id[0],
-              (int *)&c->x86_vendor_id[8],
-              (int *)&c->x86_vendor_id[4]);
-               
-        get_cpu_vendor(c);
-        /* Initialize the standard set of capabilities */
-        /* Note that the vendor-specific code below might override */
-
-        /* Intel-defined flags: level 0x00000001 */
-        if ( c->cpuid_level >= 0x00000001 ) {
-                        u32 capability, excap;
-                        cpuid(0x00000001, &tfms, &junk, &excap, &capability);
-                        c->x86_capability[0] = capability;
-                        c->x86_capability[4] = excap;
-                        c->x86 = (tfms >> 8) & 15;
-                        c->x86_model = (tfms >> 4) & 15;
-                        if (c->x86 == 0xf) {
-                                c->x86 += (tfms >> 20) & 0xff;
-                                c->x86_model += ((tfms >> 16) & 0xF) << 4;
-                        }
-                        c->x86_mask = tfms & 15;
-        } else {
-            /* Have CPUID level 0 only - unheard of */
-            c->x86 = 4;
-        }
-
-        /* AMD-defined flags: level 0x80000001 */
-        xlvl = cpuid_eax(0x80000000);
-        if ( (xlvl & 0xffff0000) == 0x80000000 ) {
-            if ( xlvl >= 0x80000001 )
-                c->x86_capability[1] = cpuid_edx(0x80000001);
-            if ( xlvl >= 0x80000004 )
-                get_model_name(c); /* Default name */
-        }
-
-        /* Transmeta-defined flags: level 0x80860001 */
-        xlvl = cpuid_eax(0x80860000);
-        if ( (xlvl & 0xffff0000) == 0x80860000 ) {
-            if (  xlvl >= 0x80860001 )
-                c->x86_capability[2] = cpuid_edx(0x80860001);
-        }
-    }
-
-    printk(KERN_DEBUG "CPU: Before vendor init, caps: %08x %08x %08x, vendor = 
%d\n",
-           c->x86_capability[0],
-           c->x86_capability[1],
-           c->x86_capability[2],
-           c->x86_vendor);
-
-    /*
-     * Vendor-specific initialization.  In this section we
-     * canonicalize the feature flags, meaning if there are
-     * features a certain CPU supports which CPUID doesn't
-     * tell us, CPUID claiming incorrect flags, or other bugs,
-     * we handle them here.
-     *
-     * At the end of this section, c->x86_capability better
-     * indicate the features this CPU genuinely supports!
-     */
-    switch ( c->x86_vendor ) {
-    case X86_VENDOR_AMD:
-        init_amd(c);
-        break;
-
-    case X86_VENDOR_INTEL:
-        init_intel(c);
-        break;
-
-    case X86_VENDOR_CENTAUR:
-        init_centaur(c);
-        break;
-        
-    default:
-        printk("Unsupported CPU vendor (%d) -- please report!\n",
-               c->x86_vendor);
-    }
-       
-    printk(KERN_DEBUG "CPU: After vendor init, caps: %08x %08x %08x %08x\n",
-           c->x86_capability[0],
-           c->x86_capability[1],
-           c->x86_capability[2],
-           c->x86_capability[3]);
-
-
-    /* If the model name is still unset, do table lookup. */
-    if ( !c->x86_model_id[0] ) {
-        char *p;
-        p = table_lookup_model(c);
-        if ( p )
-            strcpy(c->x86_model_id, p);
-        else
-            /* Last resort... */
-            sprintf(c->x86_model_id, "%02x/%02x",
-                    c->x86_vendor, c->x86_model);
-    }
-
-    /* Now the feature flags better reflect actual CPU features! */
-
-    printk(KERN_DEBUG "CPU:     After generic, caps: %08x %08x %08x %08x\n",
-           c->x86_capability[0],
-           c->x86_capability[1],
-           c->x86_capability[2],
-           c->x86_capability[3]);
-
-    /*
-     * On SMP, boot_cpu_data holds the common feature set between
-     * all CPUs; so make sure that we indicate which features are
-     * common between the CPUs.  The first time this routine gets
-     * executed, c == &boot_cpu_data.
-     */
-    if ( c != &boot_cpu_data ) {
-        /* AND the already accumulated flags with these */
-        for ( i = 0 ; i < NCAPINTS ; i++ )
-            boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
-    }
-
-    printk(KERN_DEBUG "CPU:             Common caps: %08x %08x %08x %08x\n",
-           boot_cpu_data.x86_capability[0],
-           boot_cpu_data.x86_capability[1],
-           boot_cpu_data.x86_capability[2],
-           boot_cpu_data.x86_capability[3]);
-}
-
-
-/* These need to match <asm/processor.h> */
-static char *cpu_vendor_names[] __initdata = {
-    "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta" };
-
-
-void __init print_cpu_info(struct cpuinfo_x86 *c)
-{
-    char *vendor = NULL;
-
-    if (c->x86_vendor < sizeof(cpu_vendor_names)/sizeof(char *))
-        vendor = cpu_vendor_names[c->x86_vendor];
-    else if (c->cpuid_level >= 0)
-        vendor = c->x86_vendor_id;
-
-    if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor)))
-        printk("%s ", vendor);
-
-    if (!c->x86_model_id[0])
-        printk("%d86", c->x86);
-    else
-        printk("%s", c->x86_model_id);
-
-    if (c->x86_mask || c->cpuid_level >= 0) 
-        printk(" stepping %02x\n", c->x86_mask);
-    else
-        printk("\n");
-}
-
-/*
- *     Get CPU information for use by the procfs.
- */
-static int show_cpuinfo(struct seq_file *m, void *v)
-{
-    /* 
-     * These flag bits must match the definitions in <asm/cpufeature.h>.
-     * NULL means this bit is undefined or reserved; either way it doesn't
-     * have meaning as far as Linux is concerned.  Note that it's important
-     * to realize there is a difference between this table and CPUID -- if
-     * applications want to get the raw CPUID data, they should access
-     * /dev/cpu/<cpu_nr>/cpuid instead.
-        */
-    static char *x86_cap_flags[] = {
-        /* Intel-defined */
-        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
-
-        /* AMD-defined */
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL,
-        NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
-
-        /* Transmeta-defined */
-        "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-        /* Other (Linux-defined) */
-        "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", 
-       NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-        /* Intel-defined (#2) */
-        "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "tm2",
-        "est", NULL, "cid", NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-        /* VIA/Cyrix/Centaur-defined */
-        NULL, NULL, "xstore", NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-    };
-    struct cpuinfo_x86 *c = v;
-    int i, n = c - cpu_data;
-    int fpu_exception;
-
-#ifdef CONFIG_SMP
-    if (!(cpu_online_map & (1<<n)))
-        return 0;
-#endif
-    seq_printf(m, "processor\t: %d\n"
-               "vendor_id\t: %s\n"
-               "cpu family\t: %d\n"
-               "model\t\t: %d\n"
-               "model name\t: %s\n",
-               n,
-               c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
-               c->x86,
-               c->x86_model,
-               c->x86_model_id[0] ? c->x86_model_id : "unknown");
-
-    if (c->x86_mask || c->cpuid_level >= 0)
-        seq_printf(m, "stepping\t: %d\n", c->x86_mask);
-    else
-        seq_printf(m, "stepping\t: unknown\n");
-
-    if ( test_bit(X86_FEATURE_TSC, &c->x86_capability) ) {
-        seq_printf(m, "cpu MHz\t\t: %lu.%03lu\n",
-                   cpu_khz / 1000, (cpu_khz % 1000));
-    }
-
-    /* Cache size */
-    if (c->x86_cache_size >= 0)
-        seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
-       
-       /* We use exception 16 if we have hardware math and we've either seen 
it or the CPU claims it is internal */
-    fpu_exception = c->hard_math && (ignore_irq13 || cpu_has_fpu);
-    seq_printf(m, "fdiv_bug\t: %s\n"
-               "hlt_bug\t\t: %s\n"
-               "f00f_bug\t: %s\n"
-               "coma_bug\t: %s\n"
-               "fpu\t\t: %s\n"
-               "fpu_exception\t: %s\n"
-               "cpuid level\t: %d\n"
-               "wp\t\t: %s\n"
-               "flags\t\t:",
-               c->fdiv_bug ? "yes" : "no",
-               c->hlt_works_ok ? "no" : "yes",
-               c->f00f_bug ? "yes" : "no",
-               c->coma_bug ? "yes" : "no",
-               c->hard_math ? "yes" : "no",
-               fpu_exception ? "yes" : "no",
-               c->cpuid_level,
-               c->wp_works_ok ? "yes" : "no");
-
-    for ( i = 0 ; i < 32*NCAPINTS ; i++ )
-        if ( test_bit(i, &c->x86_capability) &&
-             x86_cap_flags[i] != NULL )
-            seq_printf(m, " %s", x86_cap_flags[i]);
-
-    seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n",
-               c->loops_per_jiffy/(500000/HZ),
-               (c->loops_per_jiffy/(5000/HZ)) % 100);
-    return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
-    return *pos < NR_CPUS ? cpu_data + *pos : NULL;
-}
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
-    ++*pos;
-    return c_start(m, pos);
-}
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-struct seq_operations cpuinfo_op = {
-    start:     c_start,
-    next:      c_next,
-    stop:      c_stop,
-    show:      show_cpuinfo,
-};
-
-unsigned long cpu_initialized __initdata = 0;
-
-/*
- * cpu_init() initializes state that is per-CPU. Some data is already
- * initialized (naturally) in the bootstrap process, such as the GDT
- * and IDT. We reload them nevertheless, this function acts as a
- * 'CPU state barrier', nothing should get across.
- */
-void __init cpu_init (void)
-{
-    int nr = smp_processor_id();
-
-    if (test_and_set_bit(nr, &cpu_initialized)) {
-        printk(KERN_WARNING "CPU#%d already initialized!\n", nr);
-        for (;;) __sti();
-    }
-    printk(KERN_INFO "Initializing CPU#%d\n", nr);
-
-    /*
-     * set up and load the per-CPU TSS and LDT
-     */
-    atomic_inc(&init_mm.mm_count);
-    current->active_mm = &init_mm;
-    if(current->mm)
-        BUG();
-    enter_lazy_tlb(&init_mm, current, nr);
-
-    HYPERVISOR_stack_switch(__KERNEL_DS, current->thread.esp0);
-
-    load_LDT(&init_mm.context);
-
-    /* Force FPU initialization. */
-    current->flags &= ~PF_USEDFPU;
-    current->used_math = 0;
-    stts();
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/signal.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/signal.c     Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,717 +0,0 @@
-/*
- *  linux/arch/i386/kernel/signal.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
- *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/stddef.h>
-#include <linux/tty.h>
-#include <linux/personality.h>
-#include <asm/ucontext.h>
-#include <asm/uaccess.h>
-#include <asm/i387.h>
-
-#define DEBUG_SIG 0
-
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
-
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
-       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
-               return -EFAULT;
-       if (from->si_code < 0)
-               return __copy_to_user(to, from, sizeof(siginfo_t));
-       else {
-               int err;
-
-               /* If you change siginfo_t structure, please be sure
-                  this code is fixed accordingly.
-                  It should never copy any pad contained in the structure
-                  to avoid security leaks, but must copy the generic
-                  3 ints plus the relevant union member.  */
-               err = __put_user(from->si_signo, &to->si_signo);
-               err |= __put_user(from->si_errno, &to->si_errno);
-               err |= __put_user((short)from->si_code, &to->si_code);
-               /* First 32bits of unions are always present.  */
-               err |= __put_user(from->si_pid, &to->si_pid);
-               switch (from->si_code >> 16) {
-               case __SI_FAULT >> 16:
-                       break;
-               case __SI_CHLD >> 16:
-                       err |= __put_user(from->si_utime, &to->si_utime);
-                       err |= __put_user(from->si_stime, &to->si_stime);
-                       err |= __put_user(from->si_status, &to->si_status);
-               default:
-                       err |= __put_user(from->si_uid, &to->si_uid);
-                       break;
-               /* case __SI_RT: This is not generated by the kernel as of now. 
 */
-               }
-               return err;
-       }
-}
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-asmlinkage int
-sys_sigsuspend(int history0, int history1, old_sigset_t mask)
-{
-       struct pt_regs * regs = (struct pt_regs *) &history0;
-       sigset_t saveset;
-
-       mask &= _BLOCKABLE;
-       spin_lock_irq(&current->sigmask_lock);
-       saveset = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending(current);
-       spin_unlock_irq(&current->sigmask_lock);
-
-       regs->eax = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(regs, &saveset))
-                       return -EINTR;
-       }
-}
-
-asmlinkage int
-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
-{
-       struct pt_regs * regs = (struct pt_regs *) &unewset;
-       sigset_t saveset, newset;
-
-       /* XXX: Don't preclude handling different sized sigset_t's.  */
-       if (sigsetsize != sizeof(sigset_t))
-               return -EINVAL;
-
-       if (copy_from_user(&newset, unewset, sizeof(newset)))
-               return -EFAULT;
-       sigdelsetmask(&newset, ~_BLOCKABLE);
-
-       spin_lock_irq(&current->sigmask_lock);
-       saveset = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending(current);
-       spin_unlock_irq(&current->sigmask_lock);
-
-       regs->eax = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(regs, &saveset))
-                       return -EINTR;
-       }
-}
-
-asmlinkage int 
-sys_sigaction(int sig, const struct old_sigaction *act,
-             struct old_sigaction *oact)
-{
-       struct k_sigaction new_ka, old_ka;
-       int ret;
-
-       if (act) {
-               old_sigset_t mask;
-               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
-                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
-                       return -EFAULT;
-               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-               __get_user(mask, &act->sa_mask);
-               siginitset(&new_ka.sa.sa_mask, mask);
-       }
-
-       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
-       if (!ret && oact) {
-               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
-                       return -EFAULT;
-               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
-       }
-
-       return ret;
-}
-
-asmlinkage int
-sys_sigaltstack(const stack_t *uss, stack_t *uoss)
-{
-       struct pt_regs *regs = (struct pt_regs *) &uss;
-       return do_sigaltstack(uss, uoss, regs->esp);
-}
-
-
-/*
- * Do a signal return; undo the signal stack.
- */
-
-struct sigframe
-{
-       char *pretcode;
-       int sig;
-       struct sigcontext sc;
-       struct _fpstate fpstate;
-       unsigned long extramask[_NSIG_WORDS-1];
-       char retcode[8];
-};
-
-struct rt_sigframe
-{
-       char *pretcode;
-       int sig;
-       struct siginfo *pinfo;
-       void *puc;
-       struct siginfo info;
-       struct ucontext uc;
-       struct _fpstate fpstate;
-       char retcode[8];
-};
-
-static int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *peax)
-{
-       unsigned int err = 0;
-
-#define COPY(x)                err |= __get_user(regs->x, &sc->x)
-
-#define COPY_SEG(seg)                                                  \
-       { unsigned short tmp;                                           \
-         err |= __get_user(tmp, &sc->seg);                             \
-         regs->x##seg = tmp; }
-
-#define COPY_SEG_STRICT(seg)                                           \
-       { unsigned short tmp;                                           \
-         err |= __get_user(tmp, &sc->seg);                             \
-         regs->x##seg = tmp|3; }
-
-#define GET_SEG(seg)                                                   \
-       { unsigned short tmp;                                           \
-         err |= __get_user(tmp, &sc->seg);                             \
-         loadsegment(seg,tmp); }
-
-       GET_SEG(gs);
-       GET_SEG(fs);
-       COPY_SEG(es);
-       COPY_SEG(ds);
-       COPY(edi);
-       COPY(esi);
-       COPY(ebp);
-       COPY(esp);
-       COPY(ebx);
-       COPY(edx);
-       COPY(ecx);
-       COPY(eip);
-       COPY_SEG_STRICT(cs);
-       COPY_SEG_STRICT(ss);
-       
-       {
-               unsigned int tmpflags;
-               err |= __get_user(tmpflags, &sc->eflags);
-               regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
-               regs->orig_eax = -1;            /* disable syscall checks */
-       }
-
-       {
-               struct _fpstate * buf;
-               err |= __get_user(buf, &sc->fpstate);
-               if (buf) {
-                       if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
-                               goto badframe;
-                       err |= restore_i387(buf);
-               }
-       }
-
-       err |= __get_user(*peax, &sc->eax);
-       return err;
-
-badframe:
-       return 1;
-}
-
-asmlinkage int sys_sigreturn(unsigned long __unused)
-{
-       struct pt_regs *regs = (struct pt_regs *) &__unused;
-       struct sigframe *frame = (struct sigframe *)(regs->esp - 8);
-       sigset_t set;
-       int eax;
-
-       if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-               goto badframe;
-       if (__get_user(set.sig[0], &frame->sc.oldmask)
-           || (_NSIG_WORDS > 1
-               && __copy_from_user(&set.sig[1], &frame->extramask,
-                                   sizeof(frame->extramask))))
-               goto badframe;
-
-       sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sigmask_lock);
-       current->blocked = set;
-       recalc_sigpending(current);
-       spin_unlock_irq(&current->sigmask_lock);
-       
-       if (restore_sigcontext(regs, &frame->sc, &eax))
-               goto badframe;
-       return eax;
-
-badframe:
-       force_sig(SIGSEGV, current);
-       return 0;
-}      
-
-asmlinkage int sys_rt_sigreturn(unsigned long __unused)
-{
-       struct pt_regs *regs = (struct pt_regs *) &__unused;
-       struct rt_sigframe *frame = (struct rt_sigframe *)(regs->esp - 4);
-       sigset_t set;
-       stack_t st;
-       int eax;
-
-       if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
-               goto badframe;
-       if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
-               goto badframe;
-
-       sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sigmask_lock);
-       current->blocked = set;
-       recalc_sigpending(current);
-       spin_unlock_irq(&current->sigmask_lock);
-       
-       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
-               goto badframe;
-
-       if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
-               goto badframe;
-       /* It is more difficult to avoid calling this function than to
-          call it and ignore errors.  */
-       do_sigaltstack(&st, NULL, regs->esp);
-
-       return eax;
-
-badframe:
-       force_sig(SIGSEGV, current);
-       return 0;
-}      
-
-/*
- * Set up a signal frame.
- */
-
-static int
-setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
-                struct pt_regs *regs, unsigned long mask)
-{
-       int tmp, err = 0;
-
-       tmp = 0;
-       __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
-       err |= __put_user(tmp, (unsigned int *)&sc->gs);
-       __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
-       err |= __put_user(tmp, (unsigned int *)&sc->fs);
-
-       err |= __put_user(regs->xes, (unsigned int *)&sc->es);
-       err |= __put_user(regs->xds, (unsigned int *)&sc->ds);
-       err |= __put_user(regs->edi, &sc->edi);
-       err |= __put_user(regs->esi, &sc->esi);
-       err |= __put_user(regs->ebp, &sc->ebp);
-       err |= __put_user(regs->esp, &sc->esp);
-       err |= __put_user(regs->ebx, &sc->ebx);
-       err |= __put_user(regs->edx, &sc->edx);
-       err |= __put_user(regs->ecx, &sc->ecx);
-       err |= __put_user(regs->eax, &sc->eax);
-       err |= __put_user(current->thread.trap_no, &sc->trapno);
-       err |= __put_user(current->thread.error_code, &sc->err);
-       err |= __put_user(regs->eip, &sc->eip);
-       err |= __put_user(regs->xcs, (unsigned int *)&sc->cs);
-       err |= __put_user(regs->eflags, &sc->eflags);
-       err |= __put_user(regs->esp, &sc->esp_at_signal);
-       err |= __put_user(regs->xss, (unsigned int *)&sc->ss);
-
-       tmp = save_i387(fpstate);
-       if (tmp < 0)
-         err = 1;
-       else
-         err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
-
-       /* non-iBCS2 extensions.. */
-       err |= __put_user(mask, &sc->oldmask);
-       err |= __put_user(current->thread.cr2, &sc->cr2);
-
-       return err;
-}
-
-/*
- * Determine which stack to use..
- */
-static inline void *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
-{
-       unsigned long esp;
-
-       /* Default to using normal stack */
-       esp = regs->esp;
-
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (sas_ss_flags(esp) == 0)
-                       esp = current->sas_ss_sp + current->sas_ss_size;
-       }
-
-       /* This is the legacy signal stack switching. */
-       else if ((regs->xss & 0xffff) != __USER_DS &&
-                !(ka->sa.sa_flags & SA_RESTORER) &&
-                ka->sa.sa_restorer) {
-               esp = (unsigned long) ka->sa.sa_restorer;
-       }
-
-       return (void *)((esp - frame_size) & -8ul);
-}
-
-static void setup_frame(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs)
-{
-       struct sigframe *frame;
-       int err = 0;
-
-       frame = get_sigframe(ka, regs, sizeof(*frame));
-
-       if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
-
-       err |= __put_user((current->exec_domain
-                          && current->exec_domain->signal_invmap
-                          && sig < 32
-                          ? current->exec_domain->signal_invmap[sig]
-                          : sig),
-                         &frame->sig);
-       if (err)
-               goto give_sigsegv;
-
-       err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
-       if (err)
-               goto give_sigsegv;
-
-       if (_NSIG_WORDS > 1) {
-               err |= __copy_to_user(frame->extramask, &set->sig[1],
-                                     sizeof(frame->extramask));
-       }
-       if (err)
-               goto give_sigsegv;
-
-       /* Set up to return from userspace.  If provided, use a stub
-          already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
-       } else {
-               err |= __put_user(frame->retcode, &frame->pretcode);
-               /* This is popl %eax ; movl $,%eax ; int $0x80 */
-               err |= __put_user(0xb858, (short *)(frame->retcode+0));
-               err |= __put_user(__NR_sigreturn, (int *)(frame->retcode+2));
-               err |= __put_user(0x80cd, (short *)(frame->retcode+6));
-       }
-
-       if (err)
-               goto give_sigsegv;
-
-       /* Set up registers for signal handler */
-       regs->esp = (unsigned long) frame;
-       regs->eip = (unsigned long) ka->sa.sa_handler;
-
-       set_fs(USER_DS);
-       regs->xds = __USER_DS;
-       regs->xes = __USER_DS;
-       regs->xss = __USER_DS;
-       regs->xcs = __USER_CS;
-       regs->eflags &= ~TF_MASK;
-
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-
-       return;
-
-give_sigsegv:
-       if (sig == SIGSEGV)
-               ka->sa.sa_handler = SIG_DFL;
-       force_sig(SIGSEGV, current);
-}
-
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs * regs)
-{
-       struct rt_sigframe *frame;
-       int err = 0;
-
-       frame = get_sigframe(ka, regs, sizeof(*frame));
-
-       if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
-
-       err |= __put_user((current->exec_domain
-                          && current->exec_domain->signal_invmap
-                          && sig < 32
-                          ? current->exec_domain->signal_invmap[sig]
-                          : sig),
-                         &frame->sig);
-       err |= __put_user(&frame->info, &frame->pinfo);
-       err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
-       if (err)
-               goto give_sigsegv;
-
-       /* Create the ucontext.  */
-       err |= __put_user(0, &frame->uc.uc_flags);
-       err |= __put_user(0, &frame->uc.uc_link);
-       err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-       err |= __put_user(sas_ss_flags(regs->esp),
-                         &frame->uc.uc_stack.ss_flags);
-       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-       err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
-                               regs, set->sig[0]);
-       err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
-       if (err)
-               goto give_sigsegv;
-
-       /* Set up to return from userspace.  If provided, use a stub
-          already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
-       } else {
-               err |= __put_user(frame->retcode, &frame->pretcode);
-               /* This is movl $,%eax ; int $0x80 */
-               err |= __put_user(0xb8, (char *)(frame->retcode+0));
-               err |= __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1));
-               err |= __put_user(0x80cd, (short *)(frame->retcode+5));
-       }
-
-       if (err)
-               goto give_sigsegv;
-
-       /* Set up registers for signal handler */
-       regs->esp = (unsigned long) frame;
-       regs->eip = (unsigned long) ka->sa.sa_handler;
-
-       set_fs(USER_DS);
-       regs->xds = __USER_DS;
-       regs->xes = __USER_DS;
-       regs->xss = __USER_DS;
-       regs->xcs = __USER_CS;
-       regs->eflags &= ~TF_MASK;
-
-#if DEBUG_SIG
-       printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
-               current->comm, current->pid, frame, regs->eip, frame->pretcode);
-#endif
-
-       return;
-
-give_sigsegv:
-       if (sig == SIGSEGV)
-               ka->sa.sa_handler = SIG_DFL;
-       force_sig(SIGSEGV, current);
-}
-
-/*
- * OK, we're invoking a handler
- */    
-
-static void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
-             siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
-{
-       /* Are we from a system call? */
-       if (regs->orig_eax >= 0) {
-               /* If so, check system call restarting.. */
-               switch (regs->eax) {
-                       case -ERESTARTNOHAND:
-                               regs->eax = -EINTR;
-                               break;
-
-                       case -ERESTARTSYS:
-                               if (!(ka->sa.sa_flags & SA_RESTART)) {
-                                       regs->eax = -EINTR;
-                                       break;
-                               }
-                       /* fallthrough */
-                       case -ERESTARTNOINTR:
-                               regs->eax = regs->orig_eax;
-                               regs->eip -= 2;
-               }
-       }
-
-       /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               setup_rt_frame(sig, ka, info, oldset, regs);
-       else
-               setup_frame(sig, ka, oldset, regs);
-
-       if (ka->sa.sa_flags & SA_ONESHOT)
-               ka->sa.sa_handler = SIG_DFL;
-
-       if (!(ka->sa.sa_flags & SA_NODEFER)) {
-               spin_lock_irq(&current->sigmask_lock);
-               sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-               sigaddset(&current->blocked,sig);
-               recalc_sigpending(current);
-               spin_unlock_irq(&current->sigmask_lock);
-       }
-}
-
-/*
- * Note that 'init' is a special process: it doesn't get signals it doesn't
- * want to handle. Thus you cannot kill init even with a SIGKILL even by
- * mistake.
- */
-int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
-{
-       siginfo_t info;
-       struct k_sigaction *ka;
-
-       /*
-        * We want the common case to go fast, which
-        * is why we may in certain cases get here from
-        * kernel mode. Just return without doing anything
-        * if so.
-        */
-       if ((regs->xcs & 2) != 2)
-               return 1;
-
-       if (!oldset)
-               oldset = &current->blocked;
-
-       for (;;) {
-               unsigned long signr;
-
-               spin_lock_irq(&current->sigmask_lock);
-               signr = dequeue_signal(&current->blocked, &info);
-               spin_unlock_irq(&current->sigmask_lock);
-
-               if (!signr)
-                       break;
-
-               if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
-                       /* Let the debugger run.  */
-                       current->exit_code = signr;
-                       current->state = TASK_STOPPED;
-                       notify_parent(current, SIGCHLD);
-                       schedule();
-
-                       /* We're back.  Did the debugger cancel the sig?  */
-                       if (!(signr = current->exit_code))
-                               continue;
-                       current->exit_code = 0;
-
-                       /* The debugger continued.  Ignore SIGSTOP.  */
-                       if (signr == SIGSTOP)
-                               continue;
-
-                       /* Update the siginfo structure.  Is this good?  */
-                       if (signr != info.si_signo) {
-                               info.si_signo = signr;
-                               info.si_errno = 0;
-                               info.si_code = SI_USER;
-                               info.si_pid = current->p_pptr->pid;
-                               info.si_uid = current->p_pptr->uid;
-                       }
-
-                       /* If the (new) signal is now blocked, requeue it.  */
-                       if (sigismember(&current->blocked, signr)) {
-                               send_sig_info(signr, &info, current);
-                               continue;
-                       }
-               }
-
-               ka = &current->sig->action[signr-1];
-               if (ka->sa.sa_handler == SIG_IGN) {
-                       if (signr != SIGCHLD)
-                               continue;
-                       /* Check for SIGCHLD: it's special.  */
-                       while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
-                               /* nothing */;
-                       continue;
-               }
-
-               if (ka->sa.sa_handler == SIG_DFL) {
-                       int exit_code = signr;
-
-                       /* Init gets no signals it doesn't want.  */
-                       if (current->pid == 1)
-                               continue;
-
-                       switch (signr) {
-                       case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
-                               continue;
-
-                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
-                               if (is_orphaned_pgrp(current->pgrp))
-                                       continue;
-                               /* FALLTHRU */
-
-                       case SIGSTOP: {
-                               struct signal_struct *sig;
-                               current->state = TASK_STOPPED;
-                               current->exit_code = signr;
-                               sig = current->p_pptr->sig;
-                               if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
& SA_NOCLDSTOP))
-                                       notify_parent(current, SIGCHLD);
-                               schedule();
-                               continue;
-                       }
-
-                       case SIGQUIT: case SIGILL: case SIGTRAP:
-                       case SIGABRT: case SIGFPE: case SIGSEGV:
-                       case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
-                               if (do_coredump(signr, regs))
-                                       exit_code |= 0x80;
-                               /* FALLTHRU */
-
-                       default:
-                               sig_exit(signr, exit_code, &info);
-                               /* NOTREACHED */
-                       }
-               }
-
-               /* Reenable any watchpoints before delivering the
-                * signal to user space. The processor register will
-                * have been cleared if the watchpoint triggered
-                * inside the kernel.
-                */
-                if ( current->thread.debugreg[7] != 0 )
-                    HYPERVISOR_set_debugreg(7, current->thread.debugreg[7]);
-
-               /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, ka, &info, oldset, regs);
-               return 1;
-       }
-
-       /* Did we come from a system call? */
-       if (regs->orig_eax >= 0) {
-               /* Restart the system call - no handlers present */
-               if (regs->eax == -ERESTARTNOHAND ||
-                   regs->eax == -ERESTARTSYS ||
-                   regs->eax == -ERESTARTNOINTR) {
-                       regs->eax = regs->orig_eax;
-                       regs->eip -= 2;
-               }
-       }
-       return 0;
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/kernel/time.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/time.c       Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,741 +0,0 @@
-/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2002-2003 - Keir Fraser - University of Cambridge
- ****************************************************************************
- *
- *        File: arch/xen/kernel/time.c
- *      Author: Rolf Neugebauer and Keir Fraser
- * 
- * Description: Interface with Xen to get correct notion of time
- */
-
-/*
- *  linux/arch/i386/kernel/time.c
- *
- *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
- *
- * This file contains the PC-specific time handling details:
- * reading the RTC at bootup, etc..
- * 1994-07-02    Alan Modra
- * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- * 1995-03-26    Markus Kuhn
- *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
- *      precision CMOS clock update
- * 1996-05-03    Ingo Molnar
- *      fixed time warps in do_[slow|fast]_gettimeoffset()
- * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
- *  "A Kernel Model for Precision Timekeeping" by Dave Mills
- * 1998-09-05    (Various)
- * More robust do_fast_gettimeoffset() algorithm implemented
- * (works with APM, Cyrix 6x86MX and Centaur C6),
- * monotonic gettimeofday() with fast_get_timeoffset(),
- * drift-proof precision TSC calibration on boot
- * (C. Scott Ananian <cananian@xxxxxxxxxxxxxxxxxxxx>, Andrew D.
- * Balsa <andrebalsa@xxxxxxxxxx>, Philip Gladstone <philip@xxxxxxxxxx>;
- * ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@xxxxxxxxxxxxx>).
- * 1998-12-16    Andrea Arcangeli
- * Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
- * because was not accounting lost_ticks.
- * 1998-12-24 Copyright (C) 1998  Andrea Arcangeli
- * Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
- * serialize accesses to xtime/lost_ticks).
- */
-
-#include <asm/smp.h>
-#include <asm/irq.h>
-#include <asm/msr.h>
-#include <asm/delay.h>
-#include <asm/mpspec.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-
-#include <asm/div64.h>
-#include <asm/hypervisor.h>
-#include <asm-xen/xen-public/dom0_ops.h>
-
-#include <linux/mc146818rtc.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/irq.h>
-#include <linux/sysctl.h>
-#include <linux/sysrq.h>
-
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
-extern rwlock_t xtime_lock;
-extern unsigned long wall_jiffies;
-
-unsigned long cpu_khz; /* get this from Xen, used elsewhere */
-
-static unsigned int rdtsc_bitshift;
-static u32 st_scale_f; /* convert ticks -> usecs */
-static u32 st_scale_i; /* convert ticks -> usecs */
-
-/* These are peridically updated in shared_info, and then copied here. */
-static u32 shadow_tsc_stamp;
-static u64 shadow_system_time;
-static u32 shadow_time_version;
-static struct timeval shadow_tv;
-
-/*
- * We use this to ensure that gettimeofday() is monotonically increasing. We
- * only break this guarantee if the wall clock jumps backwards "a long way".
- */
-static struct timeval last_seen_tv = {0,0};
-
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-/* Periodically propagate synchronised time base to the RTC and to Xen. */
-static long last_update_to_rtc, last_update_to_xen;
-#endif
-
-/* Periodically take synchronised time base from Xen, if we need it. */
-static long last_update_from_xen;   /* UTC seconds when last read Xen clock. */
-
-/* Keep track of last time we did processing/updating of jiffies and xtime. */
-static u64 processed_system_time;   /* System time (ns) at last processing. */
-
-#define NS_PER_TICK (1000000000ULL/HZ)
-
-#ifndef NSEC_PER_SEC
-#define NSEC_PER_SEC (1000000000L)
-#endif
-
-#define HANDLE_USEC_UNDERFLOW(_tv)         \
-    do {                                   \
-        while ( (_tv).tv_usec < 0 )        \
-        {                                  \
-            (_tv).tv_usec += 1000000;      \
-            (_tv).tv_sec--;                \
-        }                                  \
-    } while ( 0 )
-#define HANDLE_USEC_OVERFLOW(_tv)          \
-    do {                                   \
-        while ( (_tv).tv_usec >= 1000000 ) \
-        {                                  \
-            (_tv).tv_usec -= 1000000;      \
-            (_tv).tv_sec++;                \
-        }                                  \
-    } while ( 0 )
-static inline void __normalize_time(time_t *sec, s64 *nsec)
-{
-       while (*nsec >= NSEC_PER_SEC) {
-               (*nsec) -= NSEC_PER_SEC;
-               (*sec)++;
-       }
-       while (*nsec < 0) {
-               (*nsec) += NSEC_PER_SEC;
-               (*sec)--;
-       }
-}
-
-/* Dynamically-mapped IRQs. */
-static int time_irq, debug_irq;
-
-/* Does this guest OS track Xen time, or set its wall clock independently? */
-static int independent_wallclock = 0;
-static int __init __independent_wallclock(char *str)
-{
-    independent_wallclock = 1;
-    return 1;
-}
-__setup("independent_wallclock", __independent_wallclock);
-#define INDEPENDENT_WALLCLOCK() \
-    (independent_wallclock || (xen_start_info.flags & SIF_INITDOMAIN))
-
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you'll only notice that after reboot!
- */
-static int set_rtc_mmss(unsigned long nowtime)
-{
-    int retval = 0;
-    int real_seconds, real_minutes, cmos_minutes;
-    unsigned char save_control, save_freq_select;
-
-    /* gets recalled with irq locally disabled */
-    spin_lock(&rtc_lock);
-    save_control = CMOS_READ(RTC_CONTROL);
-    CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-    save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
-    CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-    cmos_minutes = CMOS_READ(RTC_MINUTES);
-    if ( !(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD )
-        BCD_TO_BIN(cmos_minutes);
-
-    /*
-     * since we're only adjusting minutes and seconds, don't interfere with
-     * hour overflow. This avoids messing with unknown time zones but requires
-     * your RTC not to be off by more than 15 minutes
-     */
-    real_seconds = nowtime % 60;
-    real_minutes = nowtime / 60;
-    if ( ((abs(real_minutes - cmos_minutes) + 15)/30) & 1 )
-        real_minutes += 30;  /* correct for half hour time zone */
-    real_minutes %= 60;
-
-    if ( abs(real_minutes - cmos_minutes) < 30 )
-    {
-        if ( !(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD )
-        {
-            BIN_TO_BCD(real_seconds);
-            BIN_TO_BCD(real_minutes);
-        }
-        CMOS_WRITE(real_seconds,RTC_SECONDS);
-        CMOS_WRITE(real_minutes,RTC_MINUTES);
-    }
-    else 
-    {
-        printk(KERN_WARNING
-               "set_rtc_mmss: can't update from %d to %d\n",
-               cmos_minutes, real_minutes);
-        retval = -1;
-    }
-
-    /* The following flags have to be released exactly in this order,
-     * otherwise the DS12887 (popular MC146818A clone with integrated
-     * battery and quartz) will not reset the oscillator and will not
-     * update precisely 500 ms later. You won't find this mentioned in
-     * the Dallas Semiconductor data sheets, but who believes data
-     * sheets anyway ...                           -- Markus Kuhn
-     */
-    CMOS_WRITE(save_control, RTC_CONTROL);
-    CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-    spin_unlock(&rtc_lock);
-
-    return retval;
-}
-#endif
-
-
-/*
- * Reads a consistent set of time-base values from Xen, into a shadow data
- * area. Must be called with the xtime_lock held for writing.
- */
-static void __get_time_values_from_xen(void)
-{
-       shared_info_t           *s = HYPERVISOR_shared_info;
-       struct vcpu_time_info   *src;
-       struct shadow_time_info *dst;
-
-       src = &s->vcpu_time[smp_processor_id()];
-       dst = &per_cpu(shadow_time, smp_processor_id());
-
-       do {
-               dst->version = src->time_version2;
-               rmb();
-               dst->tsc_timestamp     = src->tsc_timestamp;
-               dst->system_timestamp  = src->system_time;
-               dst->tsc_to_nsec_mul   = src->tsc_to_system_mul;
-               dst->tsc_shift         = src->tsc_shift;
-               rmb();
-       }
-       while (dst->version != src->time_version1);
-
-       dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
-
-       if ((shadow_tv.tv_sec != s->wc_sec) ||
-           (shadow_tv.tv_usec != s->wc_usec))
-               update_wallclock();
-}
-
-
-/*
- * Returns the system time elapsed, in ns, since the current shadow_timestamp
- * was calculated. Must be called with the xtime_lock held for reading.
- */
-static inline unsigned long __get_time_delta_usecs(void)
-{
-    s32      delta_tsc;
-    u32      low;
-    u64      delta, tsc;
-
-    rdtscll(tsc);
-    low = (u32)(tsc >> rdtsc_bitshift);
-    delta_tsc = (s32)(low - shadow_tsc_stamp);
-    if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
-    delta = ((u64)delta_tsc * st_scale_f);
-    delta >>= 32;
-    delta += ((u64)delta_tsc * st_scale_i);
-
-    return (unsigned long)delta;
-}
-
-static inline int time_values_up_to_date()
-{
-       struct vcpu_time_info   *src;
-       struct shadow_time_info *dst;
-
-       src = &HYPERVISOR_shared_info->vcpu_time[smp_processor_id()];
-       dst = &per_cpu(shadow_time, smp_processor_id());
-
-       return (dst->version == src->time_version2);
-}
-
-
-/*
- * Returns the current time-of-day in UTC timeval format.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-    unsigned long flags, lost;
-    struct timeval _tv;
-    s64 nsec;
-
- again:
-    read_lock_irqsave(&xtime_lock, flags);
-
-    _tv.tv_usec = __get_time_delta_usecs();
-    if ( (lost = (jiffies - wall_jiffies)) != 0 )
-        _tv.tv_usec += lost * (1000000 / HZ);
-    _tv.tv_sec   = xtime.tv_sec;
-    _tv.tv_usec += xtime.tv_usec;
-
-    nsec = shadow_system_time - processed_system_time;
-    __normalize_time(&_tv.tv_sec, &nsec);
-    _tv.tv_usec += (long)nsec / 1000L;
-
-    if ( unlikely(!time_values_up_to_date()) )
-    {
-        /*
-         * We may have blocked for a long time, rendering our calculations
-         * invalid (e.g. the time delta may have overflowed). Detect that
-         * and recalculate with fresh values.
-         */
-        read_unlock_irqrestore(&xtime_lock, flags);
-        write_lock_irqsave(&xtime_lock, flags);
-        __get_time_values_from_xen();
-        write_unlock_irqrestore(&xtime_lock, flags);
-        goto again;
-    }
-
-    HANDLE_USEC_OVERFLOW(_tv);
-
-    /* Ensure that time-of-day is monotonically increasing. */
-    if ( (_tv.tv_sec < last_seen_tv.tv_sec) ||
-         ((_tv.tv_sec == last_seen_tv.tv_sec) &&
-          (_tv.tv_usec < last_seen_tv.tv_usec)) )
-        _tv = last_seen_tv;
-    last_seen_tv = _tv;
-
-    read_unlock_irqrestore(&xtime_lock, flags);
-
-    *tv = _tv;
-}
-
-
-/*
- * Sets the current time-of-day based on passed-in UTC timeval parameter.
- */
-void do_settimeofday(struct timeval *tv)
-{
-    struct timeval newtv;
-    s64            nsec;
-    suseconds_t    usec;
-    
-    if ( !INDEPENDENT_WALLCLOCK() )
-        return;
-    
-    write_lock_irq(&xtime_lock);
-    
-    /*
-     * Ensure we don't get blocked for a long time so that our time delta
-     * overflows. If that were to happen then our shadow time values would
-     * be stale, so we can retry with fresh ones.
-     */
- again:
-    usec = tv->tv_usec - __get_time_delta_usecs();
-
-    nsec = shadow_system_time - processed_system_time;
-    __normalize_time(&tv->tv_sec, &nsec);
-    usec -= (long)nsec / 1000L;
-
-    if ( unlikely(!TIME_VALUES_UP_TO_DATE) )
-    {
-        __get_time_values_from_xen();
-        goto again;
-    }
-    tv->tv_usec = usec;
-    
-    HANDLE_USEC_UNDERFLOW(*tv);
-    
-    newtv = *tv;
-    
-    tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
-    HANDLE_USEC_UNDERFLOW(*tv);
-
-    xtime = *tv;
-    time_adjust = 0;  /* stop active adjtime() */
-    time_status |= STA_UNSYNC;
-    time_maxerror = NTP_PHASE_LIMIT;
-    time_esterror = NTP_PHASE_LIMIT;
-
-    /* Reset all our running time counts. They make no sense now. */
-    last_seen_tv.tv_sec = 0;
-    last_update_from_xen = 0;
-
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-    if ( xen_start_info.flags & SIF_INITDOMAIN )
-    {
-        dom0_op_t op;
-        last_update_to_rtc = last_update_to_xen = 0;
-        op.cmd = DOM0_SETTIME;
-        op.u.settime.secs        = newtv.tv_sec;
-        op.u.settime.usecs       = newtv.tv_usec;
-        op.u.settime.system_time = shadow_system_time;
-        write_unlock_irq(&xtime_lock);
-        HYPERVISOR_dom0_op(&op);
-    }
-    else
-#endif
-    {
-        write_unlock_irq(&xtime_lock);
-    }
-}
-
-
-asmlinkage long sys_stime(int *tptr)
-{
-    int value;
-    struct timeval tv;
-
-    if ( !capable(CAP_SYS_TIME) )
-        return -EPERM;
-
-    if ( get_user(value, tptr) )
-        return -EFAULT;
-
-    tv.tv_sec  = value;
-    tv.tv_usec = 0;
-
-    do_settimeofday(&tv);
-
-    return 0;
-}
-
-
-/* Convert jiffies to system time. Call with xtime_lock held for reading. */
-static inline u64 __jiffies_to_st(unsigned long j) 
-{
-    return processed_system_time + ((j - jiffies) * NS_PER_TICK);
-}
-
-
-static inline void do_timer_interrupt(int irq, void *dev_id,
-                                      struct pt_regs *regs)
-{
-    s64 delta;
-    unsigned long ticks = 0;
-    long sec_diff;
-
-    do {
-        __get_time_values_from_xen();
-        
-        delta = (s64)(shadow_system_time + 
-                      ((s64)__get_time_delta_usecs() * 1000LL) -
-                      processed_system_time);
-    }
-    while ( !TIME_VALUES_UP_TO_DATE );
-
-    if ( unlikely(delta < 0) )
-    {
-        printk("Timer ISR: Time went backwards: %lld\n", delta);
-        return;
-    }
-
-    /* Process elapsed jiffies since last call. */
-    while ( delta >= NS_PER_TICK )
-    {
-        ticks++;
-        delta -= NS_PER_TICK;
-        processed_system_time += NS_PER_TICK;
-    }
-
-    if ( ticks != 0 )
-    {
-        do_timer_ticks(ticks);
-
-        if ( user_mode(regs) )
-            update_process_times_us(ticks, 0);
-        else
-            update_process_times_us(0, ticks);
-    }
-
-    /*
-     * Take synchronised time from Xen once a minute if we're not
-     * synchronised ourselves, and we haven't chosen to keep an independent
-     * time base.
-     */
-    if ( !INDEPENDENT_WALLCLOCK() &&
-         ((time_status & STA_UNSYNC) != 0) &&
-         (xtime.tv_sec > (last_update_from_xen + 60)) )
-    {
-        /* Adjust shadow timeval for jiffies that haven't updated xtime yet. */
-        shadow_tv.tv_usec -= (jiffies - wall_jiffies) * (1000000/HZ);
-        HANDLE_USEC_UNDERFLOW(shadow_tv);
-
-        /*
-         * Reset our running time counts if they are invalidated by a warp
-         * backwards of more than 500ms.
-         */
-        sec_diff = xtime.tv_sec - shadow_tv.tv_sec;
-        if ( unlikely(abs(sec_diff) > 1) ||
-             unlikely(((sec_diff * 1000000) + 
-                       xtime.tv_usec - shadow_tv.tv_usec) > 500000) )
-        {
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-            last_update_to_rtc = last_update_to_xen = 0;
-#endif
-            last_seen_tv.tv_sec = 0;
-        }
-
-        /* Update our unsynchronised xtime appropriately. */
-        xtime = shadow_tv;
-
-        last_update_from_xen = xtime.tv_sec;
-    }
-
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-    if ( (xen_start_info.flags & SIF_INITDOMAIN) &&
-         ((time_status & STA_UNSYNC) == 0) )
-    {
-        /* Send synchronised time to Xen approximately every minute. */
-        if ( xtime.tv_sec > (last_update_to_xen + 60) )
-        {
-            dom0_op_t op;
-            struct timeval tv = xtime;
-
-            tv.tv_usec += (jiffies - wall_jiffies) * (1000000/HZ);
-            HANDLE_USEC_OVERFLOW(tv);
-
-            op.cmd = DOM0_SETTIME;
-            op.u.settime.secs        = tv.tv_sec;
-            op.u.settime.usecs       = tv.tv_usec;
-            op.u.settime.system_time = shadow_system_time;
-            HYPERVISOR_dom0_op(&op);
-
-            last_update_to_xen = xtime.tv_sec;
-        }
-
-        /*
-         * If we have an externally synchronized Linux clock, then update CMOS
-         * clock accordingly every ~11 minutes. Set_rtc_mmss() has to be called
-         * as close as possible to 500 ms before the new second starts.
-         */
-        if ( (xtime.tv_sec > (last_update_to_rtc + 660)) &&
-             (xtime.tv_usec >= (500000 - ((unsigned) tick) / 2)) &&
-             (xtime.tv_usec <= (500000 + ((unsigned) tick) / 2)) )
-        {
-            if ( set_rtc_mmss(xtime.tv_sec) == 0 )
-                last_update_to_rtc = xtime.tv_sec;
-            else
-                last_update_to_rtc = xtime.tv_sec - 600;
-        }
-    }
-#endif
-}
-
-
-static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-    write_lock(&xtime_lock);
-    do_timer_interrupt(irq, NULL, regs);
-    write_unlock(&xtime_lock);
-}
-
-static struct irqaction irq_timer = {
-    timer_interrupt, 
-    SA_INTERRUPT, 
-    0, 
-    "timer", 
-    NULL, 
-    NULL
-};
-
-
-/*
- * This function works out when the the next timer function has to be
- * executed (by looking at the timer list) and sets the Xen one-shot
- * domain timer to the appropriate value. This is typically called in
- * cpu_idle() before the domain blocks.
- * 
- * The function returns a non-0 value on error conditions.
- * 
- * It must be called with interrupts disabled.
- */
-extern spinlock_t timerlist_lock;
-int set_timeout_timer(void)
-{
-    struct timer_list *timer;
-    u64 alarm = 0;
-    int ret = 0;
-
-    spin_lock(&timerlist_lock);
-
-    /*
-     * This is safe against long blocking (since calculations are not based on 
-     * TSC deltas). It is also safe against warped system time since
-     * suspend-resume is cooperative and we would first get locked out. It is 
-     * safe against normal updates of jiffies since interrupts are off.
-     */
-    if ( (timer = next_timer_event()) != NULL )
-        alarm = __jiffies_to_st(timer->expires);
-
-    /* Tasks on the timer task queue expect to be executed on the next tick. */
-    if ( TQ_ACTIVE(tq_timer) )
-        alarm = __jiffies_to_st(jiffies + 1);
-
-    /* Failure is pretty bad, but we'd best soldier on. */
-    if ( HYPERVISOR_set_timer_op(alarm) != 0 )
-        ret = -1;
-    
-    spin_unlock(&timerlist_lock);
-
-    return ret;
-}
-
-
-/* Time debugging. */
-static void dbg_time_int(int irq, void *dev_id, struct pt_regs *ptregs)
-{
-    unsigned long flags, j;
-    u64 s_now, j_st;
-    struct timeval s_tv, tv;
-
-    struct timer_list *timer;
-    u64 t_st;
-
-    read_lock_irqsave(&xtime_lock, flags);
-    s_tv.tv_sec  = shadow_tv.tv_sec;
-    s_tv.tv_usec = shadow_tv.tv_usec;
-    s_now        = shadow_system_time;
-    read_unlock_irqrestore(&xtime_lock, flags);
-
-    do_gettimeofday(&tv);
-
-    j = jiffies;
-    j_st = __jiffies_to_st(j);
-
-    timer = next_timer_event();
-    t_st = __jiffies_to_st(timer->expires);
-
-    printk(KERN_ALERT "time: shadow_st=0x%X:%08X\n",
-           (u32)(s_now>>32), (u32)s_now);
-    printk(KERN_ALERT "time: wct=%lds %ldus shadow_wct=%lds %ldus\n",
-           tv.tv_sec, tv.tv_usec, s_tv.tv_sec, s_tv.tv_usec);
-    printk(KERN_ALERT "time: jiffies=%lu(0x%X:%08X) timeout=%lu(0x%X:%08X)\n",
-           jiffies,(u32)(j_st>>32), (u32)j_st,
-           timer->expires,(u32)(t_st>>32), (u32)t_st);
-    printk(KERN_ALERT "time: processed_system_time=0x%X:%08X\n",
-           (u32)(processed_system_time>>32), (u32)processed_system_time);
-
-#ifdef CONFIG_MAGIC_SYSRQ
-    handle_sysrq('t',NULL,NULL,NULL);
-#endif
-}
-
-static struct irqaction dbg_time = {
-    dbg_time_int, 
-    SA_SHIRQ, 
-    0, 
-    "timer_dbg", 
-    &dbg_time_int,
-    NULL
-};
-
-void __init time_init(void)
-{
-    unsigned long long alarm;
-    u64 __cpu_khz, __cpu_ghz, cpu_freq, scale, scale2;
-    unsigned int cpu_ghz;
-
-    __cpu_khz = __cpu_ghz = cpu_freq = HYPERVISOR_shared_info->cpu_freq;
-    do_div(__cpu_khz, 1000UL);
-    cpu_khz = (u32)__cpu_khz;
-    do_div(__cpu_ghz, 1000000000UL);
-    cpu_ghz = (unsigned int)__cpu_ghz;
-
-    printk("Xen reported: %lu.%03lu MHz processor.\n", 
-           cpu_khz / 1000, cpu_khz % 1000);
-
-    xtime.tv_sec = HYPERVISOR_shared_info->wc_sec;
-    xtime.tv_usec = HYPERVISOR_shared_info->wc_usec;
-    processed_system_time = shadow_system_time;
-
-    for ( rdtsc_bitshift = 0; cpu_ghz != 0; rdtsc_bitshift++, cpu_ghz >>= 1 )
-        continue;
-
-    scale = 1000000LL << (32 + rdtsc_bitshift);
-    do_div(scale, (u32)cpu_freq);
-
-    if ( (cpu_freq >> 32) != 0 )
-    {
-        scale2 = 1000000LL << rdtsc_bitshift;
-        do_div(scale2, (u32)(cpu_freq>>32));
-        scale += scale2;
-    }
-
-    st_scale_f = scale & 0xffffffff;
-    st_scale_i = scale >> 32;
-
-    __get_time_values_from_xen();
-    processed_system_time = shadow_system_time;
-
-    time_irq  = bind_virq_to_irq(VIRQ_TIMER);
-    debug_irq = bind_virq_to_irq(VIRQ_DEBUG);
-
-    (void)setup_irq(time_irq, &irq_timer);
-    (void)setup_irq(debug_irq, &dbg_time);
-
-    rdtscll(alarm);
-}
-
-void time_suspend(void)
-{
-}
-
-void time_resume(void)
-{
-    unsigned long flags;
-    write_lock_irqsave(&xtime_lock, flags);
-    /* Get timebases for new environment. */ 
-    __get_time_values_from_xen();
-    /* Reset our own concept of passage of system time. */
-    processed_system_time = shadow_system_time;
-    /* Accept a warp in UTC (wall-clock) time. */
-    last_seen_tv.tv_sec = 0;
-    /* Make sure we resync UTC time with Xen on next timer interrupt. */
-    last_update_from_xen = 0;
-    write_unlock_irqrestore(&xtime_lock, flags);
-}
-
-/*
- * /proc/sys/xen: This really belongs in another file. It can stay here for
- * now however.
- */
-static ctl_table xen_subtable[] = {
-    {1, "independent_wallclock", &independent_wallclock,
-     sizeof(independent_wallclock), 0644, NULL, proc_dointvec},
-    {0}
-};
-static ctl_table xen_table[] = {
-    {123, "xen", NULL, 0, 0555, xen_subtable},
-    {0}
-};
-static int __init xen_sysctl_init(void)
-{
-    (void)register_sysctl_table(xen_table, 0);
-    return 0;
-}
-__initcall(xen_sysctl_init);
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/arch/xen/kernel/traps.c
--- a/linux-2.4-xen-sparse/arch/xen/kernel/traps.c      Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,619 +0,0 @@
-/*
- *  linux/arch/i386/traps.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  Pentium III FXSR, SSE support
- *     Gareth Hughes <gareth@xxxxxxxxxxx>, May 2000
- */
-
-/*
- * 'Traps.c' handles hardware traps and faults after we have saved some
- * state in 'asm.s'.
- */
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/highmem.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <asm/debugreg.h>
-#include <asm/desc.h>
-#include <asm/i387.h>
-
-#include <asm/smp.h>
-#include <asm/pgalloc.h>
-
-#include <asm/hypervisor.h>
-
-#include <linux/irq.h>
-#include <linux/module.h>
-
-asmlinkage int system_call(void);
-asmlinkage void lcall7(void);
-asmlinkage void lcall27(void);
-
-asmlinkage void divide_error(void);
-asmlinkage void debug(void);
-asmlinkage void int3(void);
-asmlinkage void overflow(void);
-asmlinkage void bounds(void);
-asmlinkage void invalid_op(void);
-asmlinkage void device_not_available(void);
-asmlinkage void double_fault(void);
-asmlinkage void coprocessor_segment_overrun(void);
-asmlinkage void invalid_TSS(void);
-asmlinkage void segment_not_present(void);
-asmlinkage void stack_segment(void);
-asmlinkage void general_protection(void);
-asmlinkage void page_fault(void);
-asmlinkage void coprocessor_error(void);
-asmlinkage void simd_coprocessor_error(void);
-asmlinkage void alignment_check(void);
-asmlinkage void fixup_4gb_segment(void);
-asmlinkage void machine_check(void);
-
-int kstack_depth_to_print = 24;
-
-
-/*
- * If the address is either in the .text section of the
- * kernel, or in the vmalloc'ed module regions, it *may* 
- * be the address of a calling routine
- */
-
-#ifdef CONFIG_MODULES
-
-extern struct module *module_list;
-extern struct module kernel_module;
-
-static inline int kernel_text_address(unsigned long addr)
-{
-       int retval = 0;
-       struct module *mod;
-
-       if (addr >= (unsigned long) &_stext &&
-           addr <= (unsigned long) &_etext)
-               return 1;
-
-       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
-               /* mod_bound tests for addr being inside the vmalloc'ed
-                * module area. Of course it'd be better to test only
-                * for the .text subset... */
-               if (mod_bound(addr, 0, mod)) {
-                       retval = 1;
-                       break;
-               }
-       }
-
-       return retval;
-}
-
-#else
-
-static inline int kernel_text_address(unsigned long addr)
-{
-       return (addr >= (unsigned long) &_stext &&
-               addr <= (unsigned long) &_etext);
-}
-
-#endif
-
-void show_trace(unsigned long * stack)
-{
-       int i;
-       unsigned long addr;
-
-       if (!stack)
-               stack = (unsigned long*)&stack;
-
-       printk("Call Trace: ");
-       i = 1;
-       while (((long) stack & (THREAD_SIZE-1)) != 0) {
-               addr = *stack++;
-               if (kernel_text_address(addr)) {
-                       if (i && ((i % 6) == 0))
-                               printk("\n   ");
-                       printk("[<%08lx>] ", addr);
-                       i++;
-               }
-       }
-       printk("\n");
-}
-
-void show_trace_task(struct task_struct *tsk)
-{
-       unsigned long esp = tsk->thread.esp;
-
-       /* User space on another CPU? */
-       if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
-               return;
-       show_trace((unsigned long *)esp);
-}
-
-void show_stack(unsigned long * esp)
-{
-       unsigned long *stack;
-       int i;
-
-       // debugging aid: "show_stack(NULL);" prints the
-       // back trace for this cpu.
-
-       if(esp==NULL)
-               esp=(unsigned long*)&esp;
-
-       stack = esp;
-       for(i=0; i < kstack_depth_to_print; i++) {
-               if (((long) stack & (THREAD_SIZE-1)) == 0)
-                       break;
-               if (i && ((i % 8) == 0))
-                       printk("\n       ");
-               printk("%08lx ", *stack++);
-       }
-       printk("\n");
-       show_trace(esp);
-}
-
-void show_registers(struct pt_regs *regs)
-{
-       int in_kernel = 1;
-       unsigned long esp;
-       unsigned short ss;
-
-       esp = (unsigned long) (&regs->esp);
-       ss = __KERNEL_DS;
-       if (regs->xcs & 2) {
-               in_kernel = 0;
-               esp = regs->esp;
-               ss = regs->xss & 0xffff;
-       }
-       printk(KERN_ALERT "CPU:    %d\n", smp_processor_id() );
-       printk(KERN_ALERT "EIP:    %04x:[<%08lx>]    %s\n",
-              0xffff & regs->xcs, regs->eip, print_tainted());
-       printk(KERN_ALERT "EFLAGS: %08lx\n",regs->eflags);
-       printk(KERN_ALERT "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
-               regs->eax, regs->ebx, regs->ecx, regs->edx);
-       printk(KERN_ALERT "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
-               regs->esi, regs->edi, regs->ebp, esp);
-       printk(KERN_ALERT "ds: %04x   es: %04x   ss: %04x\n",
-               regs->xds & 0xffff, regs->xes & 0xffff, ss);
-       printk(KERN_ALERT "Process %s (pid: %d, stackpage=%08lx)",
-               current->comm, current->pid, 4096+(unsigned long)current);
-       /*
-        * When in-kernel, we also print out the stack and code at the
-        * time of the fault..
-        */
-       if (in_kernel) {
-
-               printk(KERN_ALERT "\nStack: ");
-               show_stack((unsigned long*)esp);
-
-#if 0
-                {
-                        int i;
-                       printk(KERN_ALERT "\nCode: ");
-                       if(regs->eip < PAGE_OFFSET)
-                               goto bad;
-
-                       for(i=0;i<20;i++)
-                       {
-                               unsigned char c;
-                               if(__get_user(c, &((unsigned 
char*)regs->eip)[i])) {
-bad:
-                                       printk(KERN_ALERT " Bad EIP value.");
-                                       break;
-                               }
-                               printk("%02x ", c);
-                       }
-               }
-#endif
-       }
-       printk(KERN_ALERT "\n");
-}      
-
-spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
-
-void die(const char * str, struct pt_regs * regs, long err)
-{
-       console_verbose();
-       spin_lock_irq(&die_lock);
-       bust_spinlocks(1);
-       printk("%s: %04lx\n", str, err & 0xffff);
-       show_registers(regs);
-       bust_spinlocks(0);
-       spin_unlock_irq(&die_lock);
-       do_exit(SIGSEGV);
-}
-
-static inline void die_if_kernel(const char * str, struct pt_regs * regs, long 
err)
-{
-       if (!(2 & regs->xcs))
-               die(str, regs, err);
-}
-
-
-static void inline do_trap(int trapnr, int signr, char *str,
-                          struct pt_regs * regs, long error_code,
-                           siginfo_t *info)
-{
-       if (!(regs->xcs & 2))
-               goto kernel_trap;
-
-       /*trap_signal:*/ {
-               struct task_struct *tsk = current;
-               tsk->thread.error_code = error_code;
-               tsk->thread.trap_no = trapnr;
-               if (info)
-                       force_sig_info(signr, info, tsk);
-               else
-                       force_sig(signr, tsk);
-               return;
-       }
-
-       kernel_trap: {
-               unsigned long fixup = search_exception_table(regs->eip);
-               if (fixup)
-                       regs->eip = fixup;
-               else    
-                       die(str, regs, error_code);
-               return;
-       }
-}
-
-#define DO_ERROR(trapnr, signr, str, name) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-{ \
-       do_trap(trapnr, signr, str, regs, error_code, NULL); \
-}
-
-#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-{ \
-       siginfo_t info; \
-       info.si_signo = signr; \
-       info.si_errno = 0; \
-       info.si_code = sicode; \
-       info.si_addr = (void *)siaddr; \
-       do_trap(trapnr, signr, str, regs, error_code, &info); \
-}
-
-DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
-DO_ERROR( 3, SIGTRAP, "int3", int3)
-DO_ERROR( 4, SIGSEGV, "overflow", overflow)
-DO_ERROR( 5, SIGSEGV, "bounds", bounds)
-DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, 
regs->eip)
-DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
-DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
-DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", 
coprocessor_segment_overrun)
-DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
-DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
-DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
-DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
-DO_ERROR(18, SIGBUS, "machine check", machine_check)
-
-asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
-{
-       /*
-        * If we trapped on an LDT access then ensure that the default_ldt is
-        * loaded, if nothing else. We load default_ldt lazily because LDT
-        * switching costs time and many applications don't need it.
-        */
-       if ( unlikely((error_code & 6) == 4) )
-       {
-               unsigned long ldt;
-               __asm__ __volatile__ ( "sldt %0" : "=r" (ldt) );
-               if ( ldt == 0 )
-               {
-                    xen_set_ldt((unsigned long)&default_ldt[0], 5);
-                   return;
-               }
-       }
-
-       if (!(regs->xcs & 2))
-               goto gp_in_kernel;
-
-       current->thread.error_code = error_code;
-       current->thread.trap_no = 13;
-       force_sig(SIGSEGV, current);
-       return;
-
-gp_in_kernel:
-       {
-               unsigned long fixup;
-               fixup = search_exception_table(regs->eip);
-               if (fixup) {
-                       regs->eip = fixup;
-                       return;
-               }
-               die("general protection fault", regs, error_code);
-       }
-}
-
-
-asmlinkage void do_debug(struct pt_regs * regs, long error_code)
-{
-    unsigned int condition;
-    struct task_struct *tsk = current;
-    siginfo_t info;
-
-    condition = HYPERVISOR_get_debugreg(6);
-
-    /* Mask out spurious debug traps due to lazy DR7 setting */
-    if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
-        if (!tsk->thread.debugreg[7])
-            goto clear_dr7;
-    }
-
-    /* Save debug status register where ptrace can see it */
-    tsk->thread.debugreg[6] = condition;
-
-    /* Mask out spurious TF errors due to lazy TF clearing */
-    if (condition & DR_STEP) {
-        /*
-         * The TF error should be masked out only if the current
-         * process is not traced and if the TRAP flag has been set
-         * previously by a tracing process (condition detected by
-         * the PT_DTRACE flag); remember that the i386 TRAP flag
-         * can be modified by the process itself in user mode,
-         * allowing programs to debug themselves without the ptrace()
-         * interface.
-         */
-        if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
-            goto clear_TF;
-    }
-
-    /* Ok, finally something we can handle */
-    tsk->thread.trap_no = 1;
-    tsk->thread.error_code = error_code;
-    info.si_signo = SIGTRAP;
-    info.si_errno = 0;
-    info.si_code = TRAP_BRKPT;
-        
-    /* If this is a kernel mode trap, save the user PC on entry to 
-     * the kernel, that's what the debugger can make sense of.
-     */
-    info.si_addr = ((regs->xcs & 2) == 0) ? (void *)tsk->thread.eip : 
-                                            (void *)regs->eip;
-    force_sig_info(SIGTRAP, &info, tsk);
-
-    /* Disable additional traps. They'll be re-enabled when
-     * the signal is delivered.
-     */
- clear_dr7:
-    HYPERVISOR_set_debugreg(7, 0);
-    return;
-
- clear_TF:
-    regs->eflags &= ~TF_MASK;
-    return;
-}
-
-
-/*
- * Note that we play around with the 'TS' bit in an attempt to get
- * the correct behaviour even in the presence of the asynchronous
- * IRQ13 behaviour
- */
-void math_error(void *eip)
-{
-       struct task_struct * task;
-       siginfo_t info;
-       unsigned short cwd, swd;
-
-       /*
-        * Save the info for the exception handler and clear the error.
-        */
-       task = current;
-       save_init_fpu(task);
-       task->thread.trap_no = 16;
-       task->thread.error_code = 0;
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
-       info.si_addr = eip;
-       /*
-        * (~cwd & swd) will mask out exceptions that are not set to unmasked
-        * status.  0x3f is the exception bits in these regs, 0x200 is the
-        * C1 reg you need in case of a stack fault, 0x040 is the stack
-        * fault bit.  We should only be taking one exception at a time,
-        * so if this combination doesn't produce any single exception,
-        * then we have a bad program that isn't syncronizing its FPU usage
-        * and it will suffer the consequences since we won't be able to
-        * fully reproduce the context of the exception
-        */
-       cwd = get_fpu_cwd(task);
-       swd = get_fpu_swd(task);
-       switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
-               case 0x000:
-               default:
-                       break;
-               case 0x001: /* Invalid Op */
-               case 0x041: /* Stack Fault */
-               case 0x241: /* Stack Fault | Direction */
-                       info.si_code = FPE_FLTINV;
-                       break;
-               case 0x002: /* Denormalize */
-               case 0x010: /* Underflow */
-                       info.si_code = FPE_FLTUND;
-                       break;
-               case 0x004: /* Zero Divide */
-                       info.si_code = FPE_FLTDIV;
-                       break;
-               case 0x008: /* Overflow */
-                       info.si_code = FPE_FLTOVF;
-                       break;
-               case 0x020: /* Precision */
-                       info.si_code = FPE_FLTRES;
-                       break;
-       }
-       force_sig_info(SIGFPE, &info, task);
-}
-
-asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
-{
-       ignore_irq13 = 1;
-       math_error((void *)regs->eip);
-}
-
-void simd_math_error(void *eip)
-{
-       struct task_struct * task;
-       siginfo_t info;
-       unsigned short mxcsr;
-
-       /*
-        * Save the info for the exception handler and clear the error.
-        */
-       task = current;
-       save_init_fpu(task);
-       task->thread.trap_no = 19;
-       task->thread.error_code = 0;
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
-       info.si_addr = eip;
-       /*
-        * The SIMD FPU exceptions are handled a little differently, as there
-        * is only a single status/control register.  Thus, to determine which
-        * unmasked exception was caught we must mask the exception mask bits
-        * at 0x1f80, and then use these to mask the exception bits at 0x3f.
-        */
-       mxcsr = get_fpu_mxcsr(task);
-       switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
-               case 0x000:
-               default:
-                       break;
-               case 0x001: /* Invalid Op */
-                       info.si_code = FPE_FLTINV;
-                       break;
-               case 0x002: /* Denormalize */
-               case 0x010: /* Underflow */
-                       info.si_code = FPE_FLTUND;
-                       break;
-               case 0x004: /* Zero Divide */
-                       info.si_code = FPE_FLTDIV;
-                       break;
-               case 0x008: /* Overflow */
-                       info.si_code = FPE_FLTOVF;
-                       break;
-               case 0x020: /* Precision */
-                       info.si_code = FPE_FLTRES;
-                       break;
-       }
-       force_sig_info(SIGFPE, &info, task);
-}
-
-asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs,
-                                         long error_code)
-{
-       if (cpu_has_xmm) {
-               /* Handle SIMD FPU exceptions on PIII+ processors. */
-               ignore_irq13 = 1;
-               simd_math_error((void *)regs->eip);
-       } else {
-               die_if_kernel("cache flush denied", regs, error_code);
-               current->thread.trap_no = 19;
-               current->thread.error_code = error_code;
-               force_sig(SIGSEGV, current);
-       }
-}
-
-/*
- *  'math_state_restore()' saves the current math information in the
- * old math state array, and gets the new ones from the current task
- *
- * Careful.. There are problems with IBM-designed IRQ13 behaviour.
- * Don't touch unless you *really* know how it works.
- */
-asmlinkage void math_state_restore(struct pt_regs regs)
-{
-       /*
-        * A trap in kernel mode can be ignored. It'll be the fast XOR or
-        * copying libraries, which will correctly save/restore state and
-        * reset the TS bit in CR0.
-        */
-       if ( (regs.xcs & 2) == 0 )
-               return;
-
-       if (current->used_math) {
-               restore_fpu(current);
-       } else {
-               init_fpu();
-       }
-       current->flags |= PF_USEDFPU;   /* So we fnsave on switch_to() */
-}
-
-
-#define _set_gate(gate_addr,type,dpl,addr) \
-do { \
-  int __d0, __d1; \
-  __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
-       "movw %4,%%dx\n\t" \
-       "movl %%eax,%0\n\t" \
-       "movl %%edx,%1" \
-       :"=m" (*((long *) (gate_addr))), \
-        "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
-       :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
-        "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
-} while (0)
-
-static void __init set_call_gate(void *a, void *addr)
-{
-       _set_gate(a,12,3,addr);
-}
-
-
-/* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */
-static trap_info_t trap_table[] = {
-    {  0, 0, __KERNEL_CS, (unsigned long)divide_error                },
-    {  1, 0, __KERNEL_CS, (unsigned long)debug                       },
-    {  3, 3, __KERNEL_CS, (unsigned long)int3                        },
-    {  4, 3, __KERNEL_CS, (unsigned long)overflow                    },
-    {  5, 3, __KERNEL_CS, (unsigned long)bounds                      },
-    {  6, 0, __KERNEL_CS, (unsigned long)invalid_op                  },
-    {  7, 0, __KERNEL_CS, (unsigned long)device_not_available        },
-    {  8, 0, __KERNEL_CS, (unsigned long)double_fault                },
-    {  9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
-    { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS                 },
-    { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present         },
-    { 12, 0, __KERNEL_CS, (unsigned long)stack_segment               },
-    { 13, 0, __KERNEL_CS, (unsigned long)general_protection          },
-    { 14, 0, __KERNEL_CS, (unsigned long)page_fault                  },
-    { 15, 0, __KERNEL_CS, (unsigned long)fixup_4gb_segment           },
-    { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error           },
-    { 17, 0, __KERNEL_CS, (unsigned long)alignment_check             },
-    { 18, 0, __KERNEL_CS, (unsigned long)machine_check               },
-    { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error      },
-    { SYSCALL_VECTOR, 
-          3, __KERNEL_CS, (unsigned long)system_call                 },
-    {  0, 0,           0, 0                           }
-};
-
-
-void __init trap_init(void)
-{
-    HYPERVISOR_set_trap_table(trap_table);    
-
-    /*
-     * The default LDT is a single-entry callgate to lcall7 for iBCS and a
-     * callgate to lcall27 for Solaris/x86 binaries.
-     */
-    clear_page(&default_ldt[0]);
-    set_call_gate(&default_ldt[0],lcall7);
-    set_call_gate(&default_ldt[4],lcall27);
-    __make_page_readonly(&default_ldt[0]);
-
-    cpu_init();
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/lib/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/lib/Makefile        Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,15 +0,0 @@
-
-.S.o:
-       $(CC) $(AFLAGS) -c $< -o $*.o
-
-L_TARGET = lib.a
-
-obj-y = checksum.o old-checksum.o delay.o \
-       usercopy.o getuser.o \
-       memcpy.o strstr.o xen_proc.o
-
-obj-$(CONFIG_X86_USE_3DNOW) += mmx.o
-obj-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
-obj-$(CONFIG_DEBUG_IOVIRT)  += iodebug.o
-
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/lib/delay.c
--- a/linux-2.4-xen-sparse/arch/xen/lib/delay.c Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,52 +0,0 @@
-/*
- *     Precise Delay Loops for i386
- *
- *     Copyright (C) 1993 Linus Torvalds
- *     Copyright (C) 1997 Martin Mares <mj@xxxxxxxxxxxxxxxxxxxxxxxx>
- *
- *     The __delay function must _NOT_ be inlined as its execution time
- *     depends wildly on alignment on many x86 processors. The additional
- *     jump magic is needed to get the timing stable on all the CPU's
- *     we have to worry about.
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <asm/processor.h>
-#include <asm/delay.h>
-
-#ifdef CONFIG_SMP
-#include <asm/smp.h>
-#endif
-
-void __delay(unsigned long loops)
-{
-       unsigned long bclock, now;
-       
-       rdtscl(bclock);
-       do
-       {
-               rep_nop();
-               rdtscl(now);
-       } while ((now-bclock) < loops);
-}
-
-inline void __const_udelay(unsigned long xloops)
-{
-       int d0;
-       __asm__("mull %0"
-               :"=d" (xloops), "=&a" (d0)
-               :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy));
-        __delay(xloops * HZ);
-}
-
-void __udelay(unsigned long usecs)
-{
-       __const_udelay(usecs * 0x000010c6);  /* 2**32 / 1000000 */
-}
-
-void __ndelay(unsigned long nsecs)
-{
-       __const_udelay(nsecs * 0x00005);  /* 2**32 / 1000000000 (rounded up) */
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/mm/Makefile
--- a/linux-2.4-xen-sparse/arch/xen/mm/Makefile Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,16 +0,0 @@
-#
-# Makefile for the linux i386-specific parts of the memory manager.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-
-O_TARGET := mm.o
-
-obj-y   := init.o fault.o extable.o pageattr.o hypervisor.o ioremap.o
-
-export-objs := pageattr.o
-
-include $(TOPDIR)/Rules.make
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/mm/fault.c
--- a/linux-2.4-xen-sparse/arch/xen/mm/fault.c  Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,302 +0,0 @@
-/*
- *  linux/arch/i386/mm/fault.c
- *
- *  Copyright (C) 1995  Linus Torvalds
- */
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>             /* For unblank_screen() */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/hardirq.h>
-
-extern void die(const char *,struct pt_regs *,long);
-
-pgd_t *cur_pgd;
-
-extern spinlock_t timerlist_lock;
-
-/*
- * Unlock any spinlocks which will prevent us from getting the
- * message out (timerlist_lock is acquired through the
- * console unblank code)
- */
-void bust_spinlocks(int yes)
-{
-       spin_lock_init(&timerlist_lock);
-       if (yes) {
-               oops_in_progress = 1;
-       } else {
-               int loglevel_save = console_loglevel;
-#ifdef CONFIG_VT
-               unblank_screen();
-#endif
-               oops_in_progress = 0;
-               /*
-                * OK, the message is on the console.  Now we call printk()
-                * without oops_in_progress set so that printk will give klogd
-                * a poke.  Hold onto your hats...
-                */
-               console_loglevel = 15;          /* NMI oopser may have shut the 
console up */
-               printk(" ");
-               console_loglevel = loglevel_save;
-       }
-}
-
-/*
- * This routine handles page faults.  It determines the address,
- * and the problem, and then passes it off to one of the appropriate
- * routines.
- *
- * error_code:
- *     bit 0 == 0 means no page found, 1 means protection fault
- *     bit 1 == 0 means read, 1 means write
- *     bit 2 == 0 means kernel, 1 means user-mode
- */
-asmlinkage void do_page_fault(struct pt_regs *regs, 
-                              unsigned long error_code,
-                              unsigned long address)
-{
-       struct task_struct *tsk = current;
-       struct mm_struct *mm;
-       struct vm_area_struct * vma;
-       unsigned long page;
-       unsigned long fixup;
-       int write;
-       siginfo_t info;
-
-        /* Set the "privileged fault" bit to something sane. */
-        error_code &= 3;
-        error_code |= (regs->xcs & 2) << 1;
-
-       /*
-        * We fault-in kernel-space virtual memory on-demand. The
-        * 'reference' page table is init_mm.pgd.
-        *
-        * NOTE! We MUST NOT take any locks for this case. We may
-        * be in an interrupt or a critical region, and should
-        * only copy the information from the master page table,
-        * nothing more.
-        *
-        * This verifies that the fault happens in kernel space
-        * (error_code & 4) == 0, and that the fault was not a
-        * protection error (error_code & 1) == 0.
-        */
-       if (address >= TASK_SIZE && !(error_code & 5))
-               goto vmalloc_fault;
-
-       mm = tsk->mm;
-       info.si_code = SEGV_MAPERR;
-
-       /*
-        * If we're in an interrupt or have no user
-        * context, we must not take the fault..
-        */
-       if (in_interrupt() || !mm)
-               goto no_context;
-
-       down_read(&mm->mmap_sem);
-
-       vma = find_vma(mm, address);
-       if (!vma)
-               goto bad_area;
-       if (vma->vm_start <= address)
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN))
-               goto bad_area;
-       if (error_code & 4) {
-               /*
-                * accessing the stack below %esp is always a bug.
-                * The "+ 32" is there due to some instructions (like
-                * pusha) doing post-decrement on the stack and that
-                * doesn't show up until later..
-                */
-               if (address + 32 < regs->esp)
-                       goto bad_area;
-       }
-       if (expand_stack(vma, address))
-               goto bad_area;
-/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
-good_area:
-       info.si_code = SEGV_ACCERR;
-       write = 0;
-       switch (error_code & 3) {
-               default:        /* 3: write, present */
-                       /* fall through */
-               case 2:         /* write, not present */
-                       if (!(vma->vm_flags & VM_WRITE))
-                               goto bad_area;
-                       write++;
-                       break;
-               case 1:         /* read, present */
-                       goto bad_area;
-               case 0:         /* read, not present */
-                       if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
-                               goto bad_area;
-       }
-
- survive:
-       /*
-        * If for any reason at all we couldn't handle the fault,
-        * make sure we exit gracefully rather than endlessly redo
-        * the fault.
-        */
-       switch (handle_mm_fault(mm, vma, address, write)) {
-       case 1:
-               tsk->min_flt++;
-               break;
-       case 2:
-               tsk->maj_flt++;
-               break;
-       case 0:
-               goto do_sigbus;
-       default:
-               goto out_of_memory;
-       }
-
-       up_read(&mm->mmap_sem);
-       return;
-
-/*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
- */
-bad_area:
-       up_read(&mm->mmap_sem);
-
-       /* User mode accesses just cause a SIGSEGV */
-       if (error_code & 4) {
-               tsk->thread.cr2 = address;
-               /* Kernel addresses are always protection faults */
-               tsk->thread.error_code = error_code | (address >= TASK_SIZE);
-               tsk->thread.trap_no = 14;
-               info.si_signo = SIGSEGV;
-               info.si_errno = 0;
-               /* info.si_code has been set above */
-               info.si_addr = (void *)address;
-               force_sig_info(SIGSEGV, &info, tsk);
-               return;
-       }
-
-no_context:
-       /* Are we prepared to handle this kernel fault?  */
-       if ((fixup = search_exception_table(regs->eip)) != 0) {
-               regs->eip = fixup;
-               return;
-       }
-
-/*
- * Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice.
- */
-
-       bust_spinlocks(1);
-
-       if (address < PAGE_SIZE)
-               printk(KERN_ALERT "Unable to handle kernel NULL pointer 
dereference");
-       else
-               printk(KERN_ALERT "Unable to handle kernel paging request");
-       printk(" at virtual address %08lx\n",address);
-       printk(" printing eip:\n");
-       printk("%08lx\n", regs->eip);
-        page = ((unsigned long *) cur_pgd)[address >> 22];
-        printk(KERN_ALERT "*pde=%08lx(%08lx)\n", page, machine_to_phys(page));
-       if (page & 1) {
-               page &= PAGE_MASK;
-               address &= 0x003ff000;
-                page = machine_to_phys(page);
-               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
-                printk(KERN_ALERT "*pte=%08lx(%08lx)\n", page, 
-                       machine_to_phys(page));
-       }
-       die("Oops", regs, error_code);
-       bust_spinlocks(0);
-       do_exit(SIGKILL);
-
-/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
-out_of_memory:
-       if (tsk->pid == 1) {
-               yield();
-               goto survive;
-       }
-       up_read(&mm->mmap_sem);
-       printk("VM: killing process %s\n", tsk->comm);
-       if (error_code & 4)
-               do_exit(SIGKILL);
-       goto no_context;
-
-do_sigbus:
-       up_read(&mm->mmap_sem);
-
-       /*
-        * Send a sigbus, regardless of whether we were in kernel
-        * or user mode.
-        */
-       tsk->thread.cr2 = address;
-       tsk->thread.error_code = error_code;
-       tsk->thread.trap_no = 14;
-       info.si_signo = SIGBUS;
-       info.si_errno = 0;
-       info.si_code = BUS_ADRERR;
-       info.si_addr = (void *)address;
-       force_sig_info(SIGBUS, &info, tsk);
-
-       /* Kernel mode? Handle exceptions or die */
-       if (!(error_code & 4))
-               goto no_context;
-       return;
-
-vmalloc_fault:
-       {
-               /*
-                * Synchronize this task's top level page-table
-                * with the 'reference' page table.
-                *
-                * Do _not_ use "tsk" here. We might be inside
-                * an interrupt in the middle of a task switch..
-                */
-               int offset = __pgd_offset(address);
-               pgd_t *pgd, *pgd_k;
-               pmd_t *pmd, *pmd_k;
-               pte_t *pte_k;
-
-               pgd = offset + cur_pgd;
-               pgd_k = init_mm.pgd + offset;
-
-               if (!pgd_present(*pgd_k))
-                       goto no_context;
-               set_pgd(pgd, *pgd_k);
-               
-               pmd = pmd_offset(pgd, address);
-               pmd_k = pmd_offset(pgd_k, address);
-               if (!pmd_present(*pmd_k))
-                       goto no_context;
-               set_pmd(pmd, *pmd_k);
-
-               pte_k = pte_offset(pmd_k, address);
-               if (!pte_present(*pte_k))
-                       goto no_context;
-               return;
-       }
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/mm/init.c
--- a/linux-2.4-xen-sparse/arch/xen/mm/init.c   Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,482 +0,0 @@
-/*
- *  linux/arch/i386/mm/init.c
- *
- *  Copyright (C) 1995  Linus Torvalds
- *
- *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
- */
-
-#include <linux/config.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#ifdef CONFIG_BLK_DEV_INITRD
-#include <linux/blk.h>
-#endif
-#include <linux/highmem.h>
-#include <linux/pagemap.h>
-#include <linux/bootmem.h>
-#include <linux/slab.h>
-
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/dma.h>
-#include <asm/apic.h>
-#include <asm/tlb.h>
-
-/* XEN: We *cannot* use mmx_clear_page() this early. Force dumb memset(). */
-#undef clear_page
-#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
-
-mmu_gather_t mmu_gathers[NR_CPUS];
-unsigned long highstart_pfn, highend_pfn;
-static unsigned long totalram_pages;
-static unsigned long totalhigh_pages;
-
-int do_check_pgt_cache(int low, int high)
-{
-    int freed = 0;
-    if(pgtable_cache_size > high) {
-        do {
-            if (!QUICKLIST_EMPTY(pgd_quicklist)) {
-                free_pgd_slow(get_pgd_fast());
-                freed++;
-            }
-            if (!QUICKLIST_EMPTY(pte_quicklist)) {
-                pte_free_slow(pte_alloc_one_fast(NULL, 0));
-                freed++;
-            }
-        } while(pgtable_cache_size > low);
-    }
-    return freed;
-}
- 
-/*
- * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
- * physical space so we can cache the place of the first one and move
- * around without checking the pgd every time.
- */
-
-#if CONFIG_HIGHMEM
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
-
-#define kmap_get_fixmap_pte(vaddr) \
-    pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
-
-void __init kmap_init(void)
-{
-    unsigned long kmap_vstart;
-
-    /* cache the first kmap pte */
-    kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
-    kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
-
-    kmap_prot = PAGE_KERNEL;
-}
-#endif /* CONFIG_HIGHMEM */
-
-void show_mem(void)
-{
-    int i, total = 0, reserved = 0;
-    int shared = 0, cached = 0;
-    int highmem = 0;
-
-    printk("Mem-info:\n");
-    show_free_areas();
-    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
-    i = max_mapnr;
-    while (i-- > 0) {
-        total++;
-        if (PageHighMem(mem_map+i))
-            highmem++;
-        if (PageReserved(mem_map+i))
-            reserved++;
-        else if (PageSwapCache(mem_map+i))
-            cached++;
-        else if (page_count(mem_map+i))
-            shared += page_count(mem_map+i) - 1;
-    }
-    printk("%d pages of RAM\n", total);
-    printk("%d pages of HIGHMEM\n",highmem);
-    printk("%d reserved pages\n",reserved);
-    printk("%d pages shared\n",shared);
-    printk("%d pages swap cached\n",cached);
-    printk("%ld pages in page table cache\n",pgtable_cache_size);
-    show_buffers();
-}
-
-/* References to section boundaries */
-
-extern char _text, _etext, _edata, __bss_start, _end;
-extern char __init_begin, __init_end;
-
-static inline void set_pte_phys (unsigned long vaddr,
-                                 unsigned long phys, pgprot_t prot)
-{
-    pgd_t *pgd;
-    pmd_t *pmd;
-    pte_t *pte;
-
-    pgd = init_mm.pgd + __pgd_offset(vaddr);
-    if (pgd_none(*pgd)) {
-        printk("PAE BUG #00!\n");
-        return;
-    }
-    pmd = pmd_offset(pgd, vaddr);
-    if (pmd_none(*pmd)) {
-        printk("PAE BUG #01!\n");
-        return;
-    }
-    pte = pte_offset(pmd, vaddr);
-
-    set_pte(pte, (pte_t) { phys | pgprot_val(prot) });
-
-    /*
-     * It's enough to flush this one mapping.
-     * (PGE mappings get flushed as well)
-     */
-    __flush_tlb_one(vaddr);
-}
-
-void __set_fixmap(enum fixed_addresses idx, unsigned long phys, 
-                  pgprot_t flags)
-{
-    unsigned long address = __fix_to_virt(idx);
-
-    if (idx >= __end_of_fixed_addresses) {
-        printk("Invalid __set_fixmap\n");
-        return;
-    }
-    set_pte_phys(address, phys, flags);
-}
-
-void clear_fixmap(enum fixed_addresses idx)
-{
-    set_pte_phys(__fix_to_virt(idx), 0, __pgprot(0));
-}
-
-static void __init fixrange_init (unsigned long start, 
-                                  unsigned long end, pgd_t *pgd_base)
-{
-    pgd_t *pgd, *kpgd;
-    pmd_t *pmd, *kpmd;
-    pte_t *pte, *kpte;
-    int i, j;
-    unsigned long vaddr;
-
-    vaddr = start;
-    i = __pgd_offset(vaddr);
-    j = __pmd_offset(vaddr);
-    pgd = pgd_base + i;
-
-    for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
-#if CONFIG_X86_PAE
-        if (pgd_none(*pgd)) {
-            pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-            set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
-            if (pmd != pmd_offset(pgd, 0))
-                printk("PAE BUG #02!\n");
-        }
-        pmd = pmd_offset(pgd, vaddr);
-#else
-        pmd = (pmd_t *)pgd;
-#endif
-        for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
-            if (pmd_none(*pmd)) {
-                pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-                clear_page(pte);
-                kpgd = pgd_offset_k((unsigned long)pte);
-                kpmd = pmd_offset(kpgd, (unsigned long)pte);
-                kpte = pte_offset(kpmd, (unsigned long)pte);
-                set_pte(kpte, pte_wrprotect(*kpte));
-                set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
-            }
-            vaddr += PMD_SIZE;
-        }
-        j = 0;
-    }
-}
-
-
-static void __init pagetable_init (void)
-{
-    unsigned long vaddr, end, ram_end;
-    pgd_t *kpgd, *pgd, *pgd_base;
-    int i, j, k;
-    pmd_t *kpmd, *pmd;
-    pte_t *kpte, *pte, *pte_base;
-
-    ram_end = end = (unsigned long)__va(max_low_pfn * PAGE_SIZE);
-    if ( xen_start_info.nr_pages < max_low_pfn )
-        ram_end = (unsigned long)__va(xen_start_info.nr_pages * PAGE_SIZE);
-
-    pgd_base = init_mm.pgd;
-    i = __pgd_offset(PAGE_OFFSET);
-    pgd = pgd_base + i;
-
-    for (; i < PTRS_PER_PGD; pgd++, i++) {
-        vaddr = i*PGDIR_SIZE;
-        if (vaddr >= end)
-            break;
-        pmd = (pmd_t *)pgd;
-        for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
-            vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
-            if (vaddr >= end)
-                break;
-
-            /* Filled in for us already? */
-            if ( pmd_val(*pmd) & _PAGE_PRESENT )
-                continue;
-
-            pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-            clear_page(pte_base);
-
-            for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
-                vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
-                if (vaddr >= ram_end)
-                    break;
-                *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL);
-            }
-            kpgd = pgd_offset_k((unsigned long)pte_base);
-            kpmd = pmd_offset(kpgd, (unsigned long)pte_base);
-            kpte = pte_offset(kpmd, (unsigned long)pte_base);
-            set_pte(kpte, pte_wrprotect(*kpte));
-            set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
-        }
-    }
-
-    /*
-     * Fixed mappings, only the page table structure has to be
-     * created - mappings will be set by set_fixmap():
-     */
-    vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-    fixrange_init(vaddr, HYPERVISOR_VIRT_START, init_mm.pgd);
-
-#if CONFIG_HIGHMEM
-    /*
-     * Permanent kmaps:
-     */
-    vaddr = PKMAP_BASE;
-    fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, init_mm.pgd);
-
-    pgd = init_mm.pgd + __pgd_offset(vaddr);
-    pmd = pmd_offset(pgd, vaddr);
-    pte = pte_offset(pmd, vaddr);
-    pkmap_page_table = pte;
-#endif
-}
-
-static void __init zone_sizes_init(void)
-{
-    unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-    unsigned int max_dma, high, low;
-
-    max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-    low = max_low_pfn;
-    high = highend_pfn;
-
-    if (low < max_dma)
-        zones_size[ZONE_DMA] = low;
-    else {
-        zones_size[ZONE_DMA] = max_dma;
-        zones_size[ZONE_NORMAL] = low - max_dma;
-#ifdef CONFIG_HIGHMEM
-        zones_size[ZONE_HIGHMEM] = high - low;
-#endif
-    }
-    free_area_init(zones_size);
-}
-
-void __init paging_init(void)
-{
-    pagetable_init();
-
-    zone_sizes_init();
-
-    /* Switch to the real shared_info page, and clear the dummy page. */
-    set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info);
-    HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-    memset(empty_zero_page, 0, sizeof(empty_zero_page));
-
-#ifdef CONFIG_HIGHMEM
-    kmap_init();
-#endif
-}
-
-static inline int page_is_ram (unsigned long pagenr)
-{
-    return 1;
-}
-
-#ifdef CONFIG_HIGHMEM
-void __init one_highpage_init(struct page *page, int free_page)
-{
-    ClearPageReserved(page);
-    set_bit(PG_highmem, &page->flags);
-    atomic_set(&page->count, 1);
-    if ( free_page )
-        __free_page(page);
-    totalhigh_pages++;
-}
-#endif /* CONFIG_HIGHMEM */
-
-static void __init set_max_mapnr_init(void)
-{
-#ifdef CONFIG_HIGHMEM
-    highmem_start_page = mem_map + highstart_pfn;
-    max_mapnr = num_physpages = highend_pfn;
-    num_mappedpages = max_low_pfn;
-#else
-    max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
-#endif
-}
-
-static int __init free_pages_init(void)
-{
-#ifdef CONFIG_HIGHMEM
-    int bad_ppro = 0;
-#endif
-    int reservedpages, pfn;
-
-    /* add only boot_pfn pages of low memory to free list.
-     * max_low_pfn may be sized for
-     * pages yet to be allocated from the hypervisor, or it may be set
-     * to override the xen_start_info amount of memory
-     */
-    int boot_pfn = min(xen_start_info.nr_pages,max_low_pfn);
-
-    /* this will put all low memory onto the freelists */
-    totalram_pages += free_all_bootmem();
-    /* XEN: init and count low-mem pages outside initial allocation. */
-    for (pfn = boot_pfn; pfn < max_low_pfn; pfn++) {
-        ClearPageReserved(&mem_map[pfn]);
-        atomic_set(&mem_map[pfn].count, 1);
-        totalram_pages++;
-    }
-
-    reservedpages = 0;
-    for (pfn = 0; pfn < boot_pfn ; pfn++) {
-        /*
-         * Only count reserved RAM pages
-         */
-        if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
-            reservedpages++;
-    }
-#ifdef CONFIG_HIGHMEM
-    for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
-        one_highpage_init((struct page *) (mem_map + pfn),
-                          (pfn < xen_start_info.nr_pages));
-    totalram_pages += totalhigh_pages;
-#endif
-    return reservedpages;
-}
-
-void __init mem_init(void)
-{
-    int codesize, reservedpages, datasize, initsize;
-
-    if (!mem_map)
-        BUG();
-
-#ifdef CONFIG_HIGHMEM
-    /* check that fixmap and pkmap do not overlap */
-    if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
-       printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n");
-       printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
-              PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START);
-       BUG();
-    }
-#endif
-
-    set_max_mapnr_init();
-
-    high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-
-    /* clear the zero-page */
-    memset(empty_zero_page, 0, PAGE_SIZE);
-
-    reservedpages = free_pages_init();
-
-    codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-    datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-    initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-    printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk 
reserved, %dk data, %dk init, %ldk highmem)\n",
-           (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-           max_mapnr << (PAGE_SHIFT-10),
-           codesize >> 10,
-           reservedpages << (PAGE_SHIFT-10),
-           datasize >> 10,
-           initsize >> 10,
-           (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
-        );
-
-    boot_cpu_data.wp_works_ok = 1;
-}
-
-void free_initmem(void)
-{
-    unsigned long addr;
-
-    addr = (unsigned long)(&__init_begin);
-    for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
-        ClearPageReserved(virt_to_page(addr));
-        set_page_count(virt_to_page(addr), 1);
-        free_page(addr);
-        totalram_pages++;
-    }
-    printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", 
(&__init_end - &__init_begin) >> 10);
-}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-void free_initrd_mem(unsigned long start, unsigned long end)
-{
-    if (start < end)
-        printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) 
>> 10);
-    for (; start < end; start += PAGE_SIZE) {
-        ClearPageReserved(virt_to_page(start));
-        set_page_count(virt_to_page(start), 1);
-        free_page(start);
-        totalram_pages++;
-    }
-}
-#endif
-
-void si_meminfo(struct sysinfo *val)
-{
-    val->totalram = max_pfn;
-    val->sharedram = 0;
-    val->freeram = nr_free_pages();
-    val->bufferram = atomic_read(&buffermem_pages);
-    val->totalhigh = max_pfn-max_low_pfn;
-    val->freehigh = nr_free_highpages();
-    val->mem_unit = PAGE_SIZE;
-    return;
-}
-
-#if defined(CONFIG_X86_PAE)
-struct kmem_cache_s *pae_pgd_cachep;
-void __init pgtable_cache_init(void)
-{
-    /*
-     * PAE pgds must be 16-byte aligned:
-        */
-    pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
-                                       SLAB_HWCACHE_ALIGN | 
SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
-    if (!pae_pgd_cachep)
-        panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
-}
-#endif /* CONFIG_X86_PAE */
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/mm/ioremap.c
--- a/linux-2.4-xen-sparse/arch/xen/mm/ioremap.c        Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,266 +0,0 @@
-/*
- * arch/xen/mm/ioremap.c
- *
- * Re-map IO memory to kernel address space so that we can access it.
- *
- * (C) Copyright 1995 1996 Linus Torvalds
- *
- * Modifications for Xenolinux (c) 2003-2004 Keir Fraser
- */
-
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/vmalloc.h>
-#include <asm/io.h>
-#include <asm/pgalloc.h>
-#include <asm/uaccess.h>
-#include <asm/tlb.h>
-#include <asm/mmu.h>
-
-#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
-
-/* These hacky macros avoid phys->machine translations. */
-#define __direct_pte(x) ((pte_t) { (x) } )
-#define __direct_mk_pte(page_nr,pgprot) \
-  __direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
-#define direct_mk_pte_phys(physpage, pgprot) \
-  __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
-
-static inline void direct_remap_area_pte(pte_t *pte, 
-                                        unsigned long address, 
-                                        unsigned long size,
-                                       mmu_update_t **v)
-{
-    unsigned long end;
-
-    address &= ~PMD_MASK;
-    end = address + size;
-    if (end > PMD_SIZE)
-        end = PMD_SIZE;
-    if (address >= end)
-        BUG();
-
-    do {
-        (*v)->ptr = virt_to_machine(pte);
-        (*v)++;
-        address += PAGE_SIZE;
-        pte++;
-    } while (address && (address < end));
-}
-
-static inline int direct_remap_area_pmd(struct mm_struct *mm,
-                                        pmd_t *pmd, 
-                                        unsigned long address, 
-                                        unsigned long size,
-                                       mmu_update_t **v)
-{
-    unsigned long end;
-
-    address &= ~PGDIR_MASK;
-    end = address + size;
-    if (end > PGDIR_SIZE)
-        end = PGDIR_SIZE;
-    if (address >= end)
-        BUG();
-    do {
-        pte_t *pte = pte_alloc(mm, pmd, address);
-        if (!pte)
-            return -ENOMEM;
-        direct_remap_area_pte(pte, address, end - address, v);
-
-        address = (address + PMD_SIZE) & PMD_MASK;
-        pmd++;
-    } while (address && (address < end));
-    return 0;
-}
- 
-int __direct_remap_area_pages(struct mm_struct *mm,
-                             unsigned long address, 
-                             unsigned long size, 
-                             mmu_update_t *v)
-{
-    pgd_t * dir;
-    unsigned long end = address + size;
-
-    dir = pgd_offset(mm, address);
-    flush_cache_all();
-    if (address >= end)
-        BUG();
-    spin_lock(&mm->page_table_lock);
-    do {
-        pmd_t *pmd = pmd_alloc(mm, dir, address);
-        if (!pmd)
-           return -ENOMEM;
-        direct_remap_area_pmd(mm, pmd, address, end - address, &v);
-        address = (address + PGDIR_SIZE) & PGDIR_MASK;
-        dir++;
-
-    } while (address && (address < end));
-    spin_unlock(&mm->page_table_lock);
-    flush_tlb_all();
-    return 0;
-}
-
-
-int direct_remap_area_pages(struct mm_struct *mm,
-                            unsigned long address, 
-                            unsigned long machine_addr,
-                            unsigned long size, 
-                            pgprot_t prot,
-                            domid_t  domid)
-{
-    int i;
-    unsigned long start_address;
-#define MAX_DIRECTMAP_MMU_QUEUE 130
-    mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u;
-
-    start_address = address;
-
-    for( i = 0; i < size; i += PAGE_SIZE )
-    {
-       if ( (v - u) == MAX_DIRECTMAP_MMU_QUEUE )
-       {
-           /* Fill in the PTE pointers. */
-           __direct_remap_area_pages( mm,
-                                      start_address, 
-                                      address-start_address, 
-                                      u);
-           
-           if ( HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0 )
-               return -EFAULT;     
-           v = u;
-           start_address = address;
-       }
-
-       /*
-         * Fill in the machine address: PTE ptr is done later by
-         * __direct_remap_area_pages(). 
-         */
-        v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
-
-        machine_addr += PAGE_SIZE;
-        address += PAGE_SIZE; 
-        v++;
-    }
-
-    if ( v != u )
-    {
-       /* get the ptep's filled in */
-       __direct_remap_area_pages(mm,
-                                  start_address, 
-                                  address-start_address, 
-                                  u);   
-       if ( unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0) )
-           return -EFAULT;         
-    }
-    
-    return 0;
-}
-
-
-#endif /* CONFIG_XEN_PRIVILEGED_GUEST */
-
-
-/*
- * Remap an arbitrary machine address space into the kernel virtual
- * address space. Needed when a privileged instance of Xenolinux wants
- * to access space outside its world directly.
- *
- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
- * have to convert them into an offset in a page-aligned mapping, but the
- * caller shouldn't need to know that small detail.
- */
-void * __ioremap(unsigned long machine_addr, 
-                 unsigned long size, 
-                 unsigned long flags)
-{
-#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
-    void * addr;
-    struct vm_struct * area;
-    unsigned long offset, last_addr;
-    pgprot_t prot;
-
-    /* Don't allow wraparound or zero size */
-    last_addr = machine_addr + size - 1;
-    if (!size || last_addr < machine_addr)
-        return NULL;
-
-    /* Mappings have to be page-aligned */
-    offset = machine_addr & ~PAGE_MASK;
-    machine_addr &= PAGE_MASK;
-    size = PAGE_ALIGN(last_addr+1) - machine_addr;
-
-    /* Ok, go for it */
-    area = get_vm_area(size, VM_IOREMAP);
-    if (!area)
-        return NULL;
-    addr = area->addr;
-    prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | 
-                    _PAGE_ACCESSED | flags);
-    if (direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(addr), 
-                                machine_addr, size, prot, 0)) {
-        vfree(addr);
-        return NULL;
-    }
-    return (void *) (offset + (char *)addr);
-#else
-    return NULL;
-#endif
-}
-
-void iounmap(void *addr)
-{
-    vfree((void *)((unsigned long)addr & PAGE_MASK));
-}
-
-/* implementation of boot time ioremap for purpose of provising access
-to the vga console for privileged domains. Unlike boot time ioremap on 
-other architectures, ours is permanent and not reclaimed when then vmalloc
-infrastructure is started */
-
-void __init *bt_ioremap(unsigned long machine_addr, unsigned long size)
-{
-        unsigned long offset, last_addr;
-        unsigned int nrpages;
-        enum fixed_addresses idx;
-
-        /* Don't allow wraparound or zero size */
-        last_addr = machine_addr + size - 1;
-        if (!size || last_addr < machine_addr)
-                return NULL;
-
-        /*
-         * Mappings have to be page-aligned
-         */
-        offset = machine_addr & ~PAGE_MASK;
-        machine_addr &= PAGE_MASK;
-        size = PAGE_ALIGN(last_addr) - machine_addr;
-
-        /*
-         * Mappings have to fit in the FIX_BTMAP area.
-         */
-        nrpages = size >> PAGE_SHIFT;
-        if (nrpages > NR_FIX_BTMAPS)
-                return NULL;
-
-        /*
-         * Ok, go for it..
-         */
-        idx = FIX_BTMAP_BEGIN;
-        while (nrpages > 0) {
-                __set_fixmap(idx, machine_addr, PAGE_KERNEL);
-                machine_addr += PAGE_SIZE;
-                --idx;
-                --nrpages;
-        }
-
-       flush_tlb_all();
-
-        return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
-}
-
-
-#if 0 /* We don't support these functions. They shouldn't be required. */
-void __init bt_iounmap(void *addr, unsigned long size) {}
-#endif
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/arch/xen/vmlinux.lds
--- a/linux-2.4-xen-sparse/arch/xen/vmlinux.lds Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,75 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@xxxxxxxxxxxxxxxxxxxxxxxx>;
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(_start)
-SECTIONS
-{
-  . = 0xC0000000 + 0x100000;
-  _text = .;                   /* Text and read-only data */
-  .text : {
-       *(.text)
-       *(.fixup)
-       *(.gnu.warning)
-       } = 0x9090
-
-  _etext = .;                  /* End of text section */
-
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
-
-  . = ALIGN(16);               /* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  __start___ksymtab = .;       /* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  .data : {                    /* Data */
-       *(.data)
-       CONSTRUCTORS
-       }
-
-  _edata = .;                  /* End of data section */
-
-  . = ALIGN(8192);             /* init_task */
-  .data.init_task : { *(.data.init_task) }
-
-  . = ALIGN(4096);             /* Init code and data */
-  __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
-  . = ALIGN(16);
-  __setup_start = .;
-  .setup.init : { *(.setup.init) }
-  __setup_end = .;
-  __initcall_start = .;
-  .initcall.init : { *(.initcall.init) }
-  __initcall_end = .;
-  . = ALIGN(4096);
-  __init_end = .;
-
-  . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
-
-  . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
-  __bss_start = .;             /* BSS */
-  .bss : {
-       *(.bss)
-       }
-  _end = . ;
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-}
diff -r 0ba10f7fef51 -r 4e0c94871be2 
linux-2.4-xen-sparse/drivers/block/ll_rw_blk.c
--- a/linux-2.4-xen-sparse/drivers/block/ll_rw_blk.c    Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,1663 +0,0 @@
-/*
- *  linux/drivers/block/ll_rw_blk.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- * Copyright (C) 1994,      Karl Keyte: Added support for disk statistics
- * Elevator latency, (C) 2000  Andrea Arcangeli <andrea@xxxxxxx> SuSE
- * Queue request tables / lock, selectable elevator, Jens Axboe <axboe@xxxxxxx>
- * kernel-doc documentation started by NeilBrown <neilb@xxxxxxxxxxxxxxx> -  
July2000
- */
-
-/*
- * This handles all read/write requests to block devices
- */
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/config.h>
-#include <linux/locks.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/completion.h>
-#include <linux/bootmem.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include <linux/highmem.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-/*
- * MAC Floppy IWM hooks
- */
-
-#ifdef CONFIG_MAC_FLOPPY_IWM
-extern int mac_floppy_init(void);
-#endif
-
-/*
- * For the allocated request tables
- */
-static kmem_cache_t *request_cachep;
-
-/*
- * The "disk" task queue is used to start the actual requests
- * after a plug
- */
-DECLARE_TASK_QUEUE(tq_disk);
-
-/*
- * Protect the request list against multiple users..
- *
- * With this spinlock the Linux block IO subsystem is 100% SMP threaded
- * from the IRQ event side, and almost 100% SMP threaded from the syscall
- * side (we still have protect against block device array operations, and
- * the do_request() side is casually still unsafe. The kernel lock protects
- * this part currently.).
- *
- * there is a fair chance that things will work just OK if these functions
- * are called with no global kernel lock held ...
- */
-spinlock_t io_request_lock = SPIN_LOCK_UNLOCKED;
-
-/* This specifies how many sectors to read ahead on the disk. */
-
-int read_ahead[MAX_BLKDEV];
-
-/* blk_dev_struct is:
- *     *request_fn
- *     *current_request
- */
-struct blk_dev_struct blk_dev[MAX_BLKDEV]; /* initialized by blk_dev_init() */
-
-/*
- * blk_size contains the size of all block-devices in units of 1024 byte
- * sectors:
- *
- * blk_size[MAJOR][MINOR]
- *
- * if (!blk_size[MAJOR]) then no minor size checking is done.
- */
-int * blk_size[MAX_BLKDEV];
-
-/*
- * blksize_size contains the size of all block-devices:
- *
- * blksize_size[MAJOR][MINOR]
- *
- * if (!blksize_size[MAJOR]) then 1024 bytes is assumed.
- */
-int * blksize_size[MAX_BLKDEV];
-
-/*
- * hardsect_size contains the size of the hardware sector of a device.
- *
- * hardsect_size[MAJOR][MINOR]
- *
- * if (!hardsect_size[MAJOR])
- *             then 512 bytes is assumed.
- * else
- *             sector_size is hardsect_size[MAJOR][MINOR]
- * This is currently set by some scsi devices and read by the msdos fs driver.
- * Other uses may appear later.
- */
-int * hardsect_size[MAX_BLKDEV];
-
-/*
- * The following tunes the read-ahead algorithm in mm/filemap.c
- */
-int * max_readahead[MAX_BLKDEV];
-
-/*
- * Max number of sectors per request
- */
-int * max_sectors[MAX_BLKDEV];
-
-unsigned long blk_max_low_pfn, blk_max_pfn;
-int blk_nohighio = 0;
-
-int block_dump = 0;
-
-static struct timer_list writeback_timer;
-
-static inline int get_max_sectors(kdev_t dev)
-{
-       if (!max_sectors[MAJOR(dev)])
-               return MAX_SECTORS;
-       return max_sectors[MAJOR(dev)][MINOR(dev)];
-}
-
-static inline request_queue_t *__blk_get_queue(kdev_t dev)
-{
-       struct blk_dev_struct *bdev = blk_dev + MAJOR(dev);
-
-       if (bdev->queue)
-               return bdev->queue(dev);
-       else
-               return &blk_dev[MAJOR(dev)].request_queue;
-}
-
-request_queue_t *blk_get_queue(kdev_t dev)
-{
-       return __blk_get_queue(dev);
-}
-
-static int __blk_cleanup_queue(struct request_list *list)
-{
-       struct list_head *head = &list->free;
-       struct request *rq;
-       int i = 0;
-
-       while (!list_empty(head)) {
-               rq = list_entry(head->next, struct request, queue);
-               list_del(&rq->queue);
-               kmem_cache_free(request_cachep, rq);
-               i++;
-       };
-
-       if (i != list->count)
-               printk("request list leak!\n");
-
-       list->count = 0;
-       return i;
-}
-
-/**
- * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed
- * @q:    the request queue to be released
- *
- * Description:
- *     blk_cleanup_queue is the pair to blk_init_queue().  It should
- *     be called when a request queue is being released; typically
- *     when a block device is being de-registered.  Currently, its
- *     primary task it to free all the &struct request structures that
- *     were allocated to the queue.
- * Caveat: 
- *     Hopefully the low level driver will have finished any
- *     outstanding requests first...
- **/
-void blk_cleanup_queue(request_queue_t * q)
-{
-       int count = q->nr_requests;
-
-       count -= __blk_cleanup_queue(&q->rq);
-
-       if (count)
-               printk("blk_cleanup_queue: leaked requests (%d)\n", count);
-       if (atomic_read(&q->nr_sectors))
-               printk("blk_cleanup_queue: leaked sectors (%d)\n", 
atomic_read(&q->nr_sectors));
-
-       memset(q, 0, sizeof(*q));
-}
-
-/**
- * blk_queue_headactive - indicate whether head of request queue may be active
- * @q:       The queue which this applies to.
- * @active:  A flag indication where the head of the queue is active.
- *
- * Description:
- *    The driver for a block device may choose to leave the currently active
- *    request on the request queue, removing it only when it has completed.
- *    The queue handling routines assume this by default for safety reasons
- *    and will not involve the head of the request queue in any merging or
- *    reordering of requests when the queue is unplugged (and thus may be
- *    working on this particular request).
- *
- *    If a driver removes requests from the queue before processing them, then
- *    it may indicate that it does so, there by allowing the head of the queue
- *    to be involved in merging and reordering.  This is done be calling
- *    blk_queue_headactive() with an @active flag of %0.
- *
- *    If a driver processes several requests at once, it must remove them (or
- *    at least all but one of them) from the request queue.
- *
- *    When a queue is plugged the head will be assumed to be inactive.
- **/
- 
-void blk_queue_headactive(request_queue_t * q, int active)
-{
-       q->head_active = active;
-}
-
-/**
- * blk_queue_throttle_sectors - indicates you will call sector throttling funcs
- * @q:       The queue which this applies to.
- * @active:  A flag indication if you want sector throttling on
- *
- * Description:
- * The sector throttling code allows us to put a limit on the number of
- * sectors pending io to the disk at a given time, sending @active nonzero
- * indicates you will call blk_started_sectors and blk_finished_sectors in
- * addition to calling blk_started_io and blk_finished_io in order to
- * keep track of the number of sectors in flight.
- **/
- 
-void blk_queue_throttle_sectors(request_queue_t * q, int active)
-{
-       q->can_throttle = active;
-}
-
-/**
- * blk_queue_make_request - define an alternate make_request function for a 
device
- * @q:  the request queue for the device to be affected
- * @mfn: the alternate make_request function
- *
- * Description:
- *    The normal way for &struct buffer_heads to be passed to a device
- *    driver is for them to be collected into requests on a request
- *    queue, and then to allow the device driver to select requests
- *    off that queue when it is ready.  This works well for many block
- *    devices. However some block devices (typically virtual devices
- *    such as md or lvm) do not benefit from the processing on the
- *    request queue, and are served best by having the requests passed
- *    directly to them.  This can be achieved by providing a function
- *    to blk_queue_make_request().
- *
- * Caveat:
- *    The driver that does this *must* be able to deal appropriately
- *    with buffers in "highmemory", either by calling bh_kmap() to get
- *    a kernel mapping, to by calling create_bounce() to create a
- *    buffer in normal memory.
- **/
-
-void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
-{
-       q->make_request_fn = mfn;
-}
-
-/**
- * blk_queue_bounce_limit - set bounce buffer limit for queue
- * @q:  the request queue for the device
- * @dma_addr:   bus address limit
- *
- * Description:
- *    Different hardware can have different requirements as to what pages
- *    it can do I/O directly to. A low level driver can call
- *    blk_queue_bounce_limit to have lower memory pages allocated as bounce
- *    buffers for doing I/O to pages residing above @page. By default
- *    the block layer sets this to the highest numbered "low" memory page.
- **/
-void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr)
-{
-       unsigned long bounce_pfn = dma_addr >> PAGE_SHIFT;
-       unsigned long mb = dma_addr >> 20;
-       static request_queue_t *old_q;
-
-       /*
-        * keep this for debugging for now...
-        */
-       if (dma_addr != BLK_BOUNCE_HIGH && q != old_q) {
-               old_q = q;
-               printk("blk: queue %p, ", q);
-               if (dma_addr == BLK_BOUNCE_ANY)
-                       printk("no I/O memory limit\n");
-               else
-                       printk("I/O limit %luMb (mask 0x%Lx)\n", mb,
-                              (long long) dma_addr);
-       }
-
-       q->bounce_pfn = bounce_pfn;
-}
-
-
-/*
- * can we merge the two segments, or do we need to start a new one?
- */
-static inline int __blk_seg_merge_ok(struct buffer_head *bh, struct 
buffer_head *nxt)
-{
-       /*
-        * if bh and nxt are contigous and don't cross a 4g boundary, it's ok
-        */
-       if (BH_CONTIG(bh, nxt) && BH_PHYS_4G(bh, nxt))
-               return 1;
-
-       return 0;
-}
-
-int blk_seg_merge_ok(struct buffer_head *bh, struct buffer_head *nxt)
-{
-       return __blk_seg_merge_ok(bh, nxt);
-}
-
-static inline int ll_new_segment(request_queue_t *q, struct request *req, int 
max_segments)
-{
-       if (req->nr_segments < max_segments) {
-               req->nr_segments++;
-               return 1;
-       }
-       return 0;
-}
-
-static int ll_back_merge_fn(request_queue_t *q, struct request *req, 
-                           struct buffer_head *bh, int max_segments)
-{
-       if (__blk_seg_merge_ok(req->bhtail, bh))
-               return 1;
-
-       return ll_new_segment(q, req, max_segments);
-}
-
-static int ll_front_merge_fn(request_queue_t *q, struct request *req, 
-                            struct buffer_head *bh, int max_segments)
-{
-       if (__blk_seg_merge_ok(bh, req->bh))
-               return 1;
-
-       return ll_new_segment(q, req, max_segments);
-}
-
-static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
-                               struct request *next, int max_segments)
-{
-       int total_segments = req->nr_segments + next->nr_segments;
-
-       if (__blk_seg_merge_ok(req->bhtail, next->bh))
-               total_segments--;
-
-       if (total_segments > max_segments)
-               return 0;
-
-       req->nr_segments = total_segments;
-       return 1;
-}
-
-/*
- * "plug" the device if there are no outstanding requests: this will
- * force the transfer to start only after we have put all the requests
- * on the list.
- *
- * This is called with interrupts off and no requests on the queue.
- * (and with the request spinlock acquired)
- */
-static void generic_plug_device(request_queue_t *q, kdev_t dev)
-{
-       /*
-        * no need to replug device
-        */
-       if (!list_empty(&q->queue_head) || q->plugged)
-               return;
-
-       q->plugged = 1;
-       queue_task(&q->plug_tq, &tq_disk);
-}
-
-/*
- * remove the plug and let it rip..
- */
-static inline void __generic_unplug_device(request_queue_t *q)
-{
-       if (q->plugged) {
-               q->plugged = 0;
-               if (!list_empty(&q->queue_head))
-                       q->request_fn(q);
-       }
-}
-
-void generic_unplug_device(void *data)
-{
-       request_queue_t *q = (request_queue_t *) data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&io_request_lock, flags);
-       __generic_unplug_device(q);
-       spin_unlock_irqrestore(&io_request_lock, flags);
-}
-
-/** blk_grow_request_list
- *  @q: The &request_queue_t
- *  @nr_requests: how many requests are desired
- *
- * More free requests are added to the queue's free lists, bringing
- * the total number of requests to @nr_requests.
- *
- * The requests are added equally to the request queue's read
- * and write freelists.
- *
- * This function can sleep.
- *
- * Returns the (new) number of requests which the queue has available.
- */
-int blk_grow_request_list(request_queue_t *q, int nr_requests, int 
max_queue_sectors)
-{
-       unsigned long flags;
-       /* Several broken drivers assume that this function doesn't sleep,
-        * this causes system hangs during boot.
-        * As a temporary fix, make the function non-blocking.
-        */
-       spin_lock_irqsave(&io_request_lock, flags);
-       while (q->nr_requests < nr_requests) {
-               struct request *rq;
-
-               rq = kmem_cache_alloc(request_cachep, SLAB_ATOMIC);
-               if (rq == NULL)
-                       break;
-               memset(rq, 0, sizeof(*rq));
-               rq->rq_status = RQ_INACTIVE;
-               list_add(&rq->queue, &q->rq.free);
-               q->rq.count++;
-
-               q->nr_requests++;
-       }
-
-       /*
-        * Wakeup waiters after both one quarter of the
-        * max-in-fligh queue and one quarter of the requests
-        * are available again.
-        */
-
-       q->batch_requests = q->nr_requests / 4;
-       if (q->batch_requests > 32)
-               q->batch_requests = 32;
-       q->batch_sectors = max_queue_sectors / 4;
- 
-       q->max_queue_sectors = max_queue_sectors;
- 
-       BUG_ON(!q->batch_sectors);
-       atomic_set(&q->nr_sectors, 0);
-
-       spin_unlock_irqrestore(&io_request_lock, flags);
-       return q->nr_requests;
-}
-
-static void blk_init_free_list(request_queue_t *q)
-{
-       struct sysinfo si;
-       int megs;               /* Total memory, in megabytes */
-       int nr_requests, max_queue_sectors = MAX_QUEUE_SECTORS;
-  
-       INIT_LIST_HEAD(&q->rq.free);
-       q->rq.count = 0;
-       q->rq.pending[READ] = q->rq.pending[WRITE] = 0;
-       q->nr_requests = 0;
-
-       si_meminfo(&si);
-       megs = si.totalram >> (20 - PAGE_SHIFT);
-       nr_requests = MAX_NR_REQUESTS;
-       if (megs < 30) {
-               nr_requests /= 2;
-               max_queue_sectors /= 2;
-       }
-       /* notice early if anybody screwed the defaults */
-       BUG_ON(!nr_requests);
-       BUG_ON(!max_queue_sectors);
- 
-       blk_grow_request_list(q, nr_requests, max_queue_sectors);
-
-       init_waitqueue_head(&q->wait_for_requests);
-
-       spin_lock_init(&q->queue_lock);
-}
-
-static int __make_request(request_queue_t * q, int rw, struct buffer_head * 
bh);
-
-/**
- * blk_init_queue  - prepare a request queue for use with a block device
- * @q:    The &request_queue_t to be initialised
- * @rfn:  The function to be called to process requests that have been
- *        placed on the queue.
- *
- * Description:
- *    If a block device wishes to use the standard request handling procedures,
- *    which sorts requests and coalesces adjacent requests, then it must
- *    call blk_init_queue().  The function @rfn will be called when there
- *    are requests on the queue that need to be processed.  If the device
- *    supports plugging, then @rfn may not be called immediately when requests
- *    are available on the queue, but may be called at some time later instead.
- *    Plugged queues are generally unplugged when a buffer belonging to one
- *    of the requests on the queue is needed, or due to memory pressure.
- *
- *    @rfn is not required, or even expected, to remove all requests off the
- *    queue, but only as many as it can handle at a time.  If it does leave
- *    requests on the queue, it is responsible for arranging that the requests
- *    get dealt with eventually.
- *
- *    A global spin lock $io_request_lock must be held while manipulating the
- *    requests on the request queue.
- *
- *    The request on the head of the queue is by default assumed to be
- *    potentially active, and it is not considered for re-ordering or merging
- *    whenever the given queue is unplugged. This behaviour can be changed with
- *    blk_queue_headactive().
- *
- * Note:
- *    blk_init_queue() must be paired with a blk_cleanup_queue() call
- *    when the block device is deactivated (such as at module unload).
- **/
-void blk_init_queue(request_queue_t * q, request_fn_proc * rfn)
-{
-       INIT_LIST_HEAD(&q->queue_head);
-       elevator_init(&q->elevator, ELEVATOR_LINUS);
-       blk_init_free_list(q);
-       q->request_fn           = rfn;
-       q->back_merge_fn        = ll_back_merge_fn;
-       q->front_merge_fn       = ll_front_merge_fn;
-       q->merge_requests_fn    = ll_merge_requests_fn;
-       q->make_request_fn      = __make_request;
-       q->plug_tq.sync         = 0;
-       q->plug_tq.routine      = &generic_unplug_device;
-       q->plug_tq.data         = q;
-       q->plugged              = 0;
-       q->can_throttle         = 0;
-
-       /*
-        * These booleans describe the queue properties.  We set the
-        * default (and most common) values here.  Other drivers can
-        * use the appropriate functions to alter the queue properties.
-        * as appropriate.
-        */
-       q->plug_device_fn       = generic_plug_device;
-       q->head_active          = 1;
-
-       blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
-}
-
-#define blkdev_free_rq(list) list_entry((list)->next, struct request, queue);
-/*
- * Get a free request. io_request_lock must be held and interrupts
- * disabled on the way in.  Returns NULL if there are no free requests.
- */
-static struct request *get_request(request_queue_t *q, int rw)
-{
-       struct request *rq = NULL;
-       struct request_list *rl = &q->rq;
-
-       if (blk_oversized_queue(q)) {
-               int rlim = q->nr_requests >> 5;
-
-               if (rlim < 4)
-                       rlim = 4;
-
-               /*
-                * if its a write, or we have more than a handful of reads
-                * pending, bail out
-                */
-               if ((rw == WRITE) || (rw == READ && rl->pending[READ] > rlim))
-                       return NULL;
-               if (blk_oversized_queue_reads(q))
-                       return NULL;
-       }
-       
-       if (!list_empty(&rl->free)) {
-               rq = blkdev_free_rq(&rl->free);
-               list_del(&rq->queue);
-               rl->count--;
-               rl->pending[rw]++;
-               rq->rq_status = RQ_ACTIVE;
-               rq->cmd = rw;
-               rq->special = NULL;
-               rq->q = q;
-       }
-
-       return rq;
-}
-
-/*
- * Here's the request allocation design, low latency version:
- *
- * 1: Blocking on request exhaustion is a key part of I/O throttling.
- * 
- * 2: We want to be `fair' to all requesters.  We must avoid starvation, and
- *    attempt to ensure that all requesters sleep for a similar duration.  
Hence
- *    no stealing requests when there are other processes waiting.
- *
- * There used to be more here, attempting to allow a process to send in a
- * number of requests once it has woken up.  But, there's no way to 
- * tell if a process has just been woken up, or if it is a new process
- * coming in to steal requests from the waiters.  So, we give up and force
- * everyone to wait fairly.
- * 
- * So here's what we do:
- * 
- *    a) A READA requester fails if free_requests < batch_requests
- * 
- *       We don't want READA requests to prevent sleepers from ever
- *       waking.  Note that READA is used extremely rarely - a few
- *       filesystems use it for directory readahead.
- * 
- *  When a process wants a new request:
- * 
- *    b) If free_requests == 0, the requester sleeps in FIFO manner, and
- *       the queue full condition is set.  The full condition is not
- *       cleared until there are no longer any waiters.  Once the full
- *       condition is set, all new io must wait, hopefully for a very
- *       short period of time.
- * 
- *  When a request is released:
- * 
- *    c) If free_requests < batch_requests, do nothing.
- * 
- *    d) If free_requests >= batch_requests, wake up a single waiter.
- *
- *   As each waiter gets a request, he wakes another waiter.  We do this
- *   to prevent a race where an unplug might get run before a request makes
- *   it's way onto the queue.  The result is a cascade of wakeups, so delaying
- *   the initial wakeup until we've got batch_requests available helps avoid
- *   wakeups where there aren't any requests available yet.
- */
-
-static struct request *__get_request_wait(request_queue_t *q, int rw)
-{
-       register struct request *rq;
-       DECLARE_WAITQUEUE(wait, current);
-
-       add_wait_queue_exclusive(&q->wait_for_requests, &wait);
-
-       do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               spin_lock_irq(&io_request_lock);
-               if (blk_oversized_queue(q) || q->rq.count == 0) {
-                       __generic_unplug_device(q);
-                       spin_unlock_irq(&io_request_lock);
-                       schedule();
-                       spin_lock_irq(&io_request_lock);
-               }
-               rq = get_request(q, rw);
-               spin_unlock_irq(&io_request_lock);
-       } while (rq == NULL);
-       remove_wait_queue(&q->wait_for_requests, &wait);
-       current->state = TASK_RUNNING;
-
-       return rq;
-}
-
-static void get_request_wait_wakeup(request_queue_t *q, int rw)
-{
-       /*
-        * avoid losing an unplug if a second __get_request_wait did the
-        * generic_unplug_device while our __get_request_wait was running
-        * w/o the queue_lock held and w/ our request out of the queue.
-        */     
-       if (waitqueue_active(&q->wait_for_requests))
-               wake_up(&q->wait_for_requests);
-}
-
-/* RO fail safe mechanism */
-
-static long ro_bits[MAX_BLKDEV][8];
-
-int is_read_only(kdev_t dev)
-{
-       int minor,major;
-
-       major = MAJOR(dev);
-       minor = MINOR(dev);
-       if (major < 0 || major >= MAX_BLKDEV) return 0;
-       return ro_bits[major][minor >> 5] & (1 << (minor & 31));
-}
-
-void set_device_ro(kdev_t dev,int flag)
-{
-       int minor,major;
-
-       major = MAJOR(dev);
-       minor = MINOR(dev);
-       if (major < 0 || major >= MAX_BLKDEV) return;
-       if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31);
-       else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
-}
-
-inline void drive_stat_acct (kdev_t dev, int rw,
-                               unsigned long nr_sectors, int new_io)
-{
-       unsigned int major = MAJOR(dev);
-       unsigned int index;
-
-       index = disk_index(dev);
-       if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
-               return;
-
-       kstat.dk_drive[major][index] += new_io;
-       if (rw == READ) {
-               kstat.dk_drive_rio[major][index] += new_io;
-               kstat.dk_drive_rblk[major][index] += nr_sectors;
-       } else if (rw == WRITE) {
-               kstat.dk_drive_wio[major][index] += new_io;
-               kstat.dk_drive_wblk[major][index] += nr_sectors;
-       } else
-               printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
-}
-
-#ifdef CONFIG_BLK_STATS
-/*
- * Return up to two hd_structs on which to do IO accounting for a given
- * request.
- *
- * On a partitioned device, we want to account both against the partition
- * and against the whole disk.
- */
-static void locate_hd_struct(struct request *req, 
-                            struct hd_struct **hd1,
-                            struct hd_struct **hd2)
-{
-       struct gendisk *gd;
-
-       *hd1 = NULL;
-       *hd2 = NULL;
-       
-       gd = get_gendisk(req->rq_dev);
-       if (gd && gd->part) {
-               /* Mask out the partition bits: account for the entire disk */
-               int devnr = MINOR(req->rq_dev) >> gd->minor_shift;
-               int whole_minor = devnr << gd->minor_shift;
-
-               *hd1 = &gd->part[whole_minor];
-               if (whole_minor != MINOR(req->rq_dev))
-                       *hd2= &gd->part[MINOR(req->rq_dev)];
-       }
-}
-
-/*
- * Round off the performance stats on an hd_struct.
- *
- * The average IO queue length and utilisation statistics are maintained
- * by observing the current state of the queue length and the amount of
- * time it has been in this state for.
- * Normally, that accounting is done on IO completion, but that can result
- * in more than a second's worth of IO being accounted for within any one
- * second, leading to >100% utilisation.  To deal with that, we do a
- * round-off before returning the results when reading /proc/partitions,
- * accounting immediately for all queue usage up to the current jiffies and
- * restarting the counters again.
- */
-void disk_round_stats(struct hd_struct *hd)
-{
-       unsigned long now = jiffies;
-       
-       hd->aveq += (hd->ios_in_flight * (jiffies - hd->last_queue_change));
-       hd->last_queue_change = now;
-
-       if (hd->ios_in_flight)
-               hd->io_ticks += (now - hd->last_idle_time);
-       hd->last_idle_time = now;       
-}
-
-static inline void down_ios(struct hd_struct *hd)
-{
-       disk_round_stats(hd);   
-       --hd->ios_in_flight;
-}
-
-static inline void up_ios(struct hd_struct *hd)
-{
-       disk_round_stats(hd);
-       ++hd->ios_in_flight;
-}
-
-static void account_io_start(struct hd_struct *hd, struct request *req,
-                            int merge, int sectors)
-{
-       switch (req->cmd) {
-       case READ:
-               if (merge)
-                       hd->rd_merges++;
-               hd->rd_sectors += sectors;
-               break;
-       case WRITE:
-               if (merge)
-                       hd->wr_merges++;
-               hd->wr_sectors += sectors;
-               break;
-       }
-       if (!merge)
-               up_ios(hd);
-}
-
-static void account_io_end(struct hd_struct *hd, struct request *req)
-{
-       unsigned long duration = jiffies - req->start_time;
-       switch (req->cmd) {
-       case READ:
-               hd->rd_ticks += duration;
-               hd->rd_ios++;
-               break;
-       case WRITE:
-               hd->wr_ticks += duration;
-               hd->wr_ios++;
-               break;
-       }
-       down_ios(hd);
-}
-
-void req_new_io(struct request *req, int merge, int sectors)
-{
-       struct hd_struct *hd1, *hd2;
-
-       locate_hd_struct(req, &hd1, &hd2);
-       if (hd1)
-               account_io_start(hd1, req, merge, sectors);
-       if (hd2)
-               account_io_start(hd2, req, merge, sectors);
-}
-
-void req_merged_io(struct request *req)
-{
-       struct hd_struct *hd1, *hd2;
-
-       locate_hd_struct(req, &hd1, &hd2);
-       if (hd1)
-               down_ios(hd1);
-       if (hd2)        
-               down_ios(hd2);
-}
-
-void req_finished_io(struct request *req)
-{
-       struct hd_struct *hd1, *hd2;
-
-       locate_hd_struct(req, &hd1, &hd2);
-       if (hd1)
-               account_io_end(hd1, req);
-       if (hd2)        
-               account_io_end(hd2, req);
-}
-EXPORT_SYMBOL(req_finished_io);
-#endif /* CONFIG_BLK_STATS */
-
-/*
- * add-request adds a request to the linked list.
- * io_request_lock is held and interrupts disabled, as we muck with the
- * request queue list.
- *
- * By this point, req->cmd is always either READ/WRITE, never READA,
- * which is important for drive_stat_acct() above.
- */
-static inline void add_request(request_queue_t * q, struct request * req,
-                              struct list_head *insert_here)
-{
-       drive_stat_acct(req->rq_dev, req->cmd, req->nr_sectors, 1);
-
-       if (!q->plugged && q->head_active && insert_here == &q->queue_head) {
-               spin_unlock_irq(&io_request_lock);
-               BUG();
-       }
-
-       /*
-        * elevator indicated where it wants this request to be
-        * inserted at elevator_merge time
-        */
-       list_add(&req->queue, insert_here);
-}
-
-/*
- * Must be called with io_request_lock held and interrupts disabled
- */
-void blkdev_release_request(struct request *req)
-{
-       request_queue_t *q = req->q;
-
-       req->rq_status = RQ_INACTIVE;
-       req->q = NULL;
-
-       /*
-        * Request may not have originated from ll_rw_blk. if not,
-        * assume it has free buffers and check waiters
-        */
-       if (q) {
-               struct request_list *rl = &q->rq;
-               int oversized_batch = 0;
-
-               if (q->can_throttle)
-                       oversized_batch = blk_oversized_queue_batch(q);
-               rl->count++;
-               /*
-                * paranoia check
-                */
-               if (req->cmd == READ || req->cmd == WRITE)
-                       rl->pending[req->cmd]--;
-               if (rl->pending[READ] > q->nr_requests)
-                       printk("blk: reads: %u\n", rl->pending[READ]);
-               if (rl->pending[WRITE] > q->nr_requests)
-                       printk("blk: writes: %u\n", rl->pending[WRITE]);
-               if (rl->pending[READ] + rl->pending[WRITE] > q->nr_requests)
-                       printk("blk: r/w: %u + %u > %u\n", rl->pending[READ], 
rl->pending[WRITE], q->nr_requests);
-               list_add(&req->queue, &rl->free);
-               if (rl->count >= q->batch_requests && !oversized_batch) {
-                       smp_mb();
-                       if (waitqueue_active(&q->wait_for_requests))
-                               wake_up(&q->wait_for_requests);
-               }
-       }
-}
-
-/*
- * Has to be called with the request spinlock acquired
- */
-static void attempt_merge(request_queue_t * q,
-                         struct request *req,
-                         int max_sectors,
-                         int max_segments)
-{
-       struct request *next;
-  
-       next = blkdev_next_request(req);
-       if (req->sector + req->nr_sectors != next->sector)
-               return;
-       if (req->cmd != next->cmd
-           || req->rq_dev != next->rq_dev
-           || req->nr_sectors + next->nr_sectors > max_sectors
-           || next->waiting)
-               return;
-       /*
-        * If we are not allowed to merge these requests, then
-        * return.  If we are allowed to merge, then the count
-        * will have been updated to the appropriate number,
-        * and we shouldn't do it here too.
-        */
-       if (!q->merge_requests_fn(q, req, next, max_segments))
-               return;
-
-       q->elevator.elevator_merge_req_fn(req, next);
-       
-       /* At this point we have either done a back merge
-        * or front merge. We need the smaller start_time of
-        * the merged requests to be the current request
-        * for accounting purposes.
-        */
-       if (time_after(req->start_time, next->start_time))
-               req->start_time = next->start_time;
-               
-       req->bhtail->b_reqnext = next->bh;
-       req->bhtail = next->bhtail;
-       req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
-       list_del(&next->queue);
-
-       /* One last thing: we have removed a request, so we now have one
-          less expected IO to complete for accounting purposes. */
-       req_merged_io(req);
-
-       blkdev_release_request(next);
-}
-
-static inline void attempt_back_merge(request_queue_t * q,
-                                     struct request *req,
-                                     int max_sectors,
-                                     int max_segments)
-{
-       if (&req->queue == q->queue_head.prev)
-               return;
-       attempt_merge(q, req, max_sectors, max_segments);
-}
-
-static inline void attempt_front_merge(request_queue_t * q,
-                                      struct list_head * head,
-                                      struct request *req,
-                                      int max_sectors,
-                                      int max_segments)
-{
-       struct list_head * prev;
-
-       prev = req->queue.prev;
-       if (head == prev)
-               return;
-       attempt_merge(q, blkdev_entry_to_request(prev), max_sectors, 
max_segments);
-}
-
-static int __make_request(request_queue_t * q, int rw,
-                                 struct buffer_head * bh)
-{
-       unsigned int sector, count, sync;
-       int max_segments = MAX_SEGMENTS;
-       struct request * req, *freereq = NULL;
-       int rw_ahead, max_sectors, el_ret;
-       struct list_head *head, *insert_here;
-       int latency;
-       elevator_t *elevator = &q->elevator;
-       int should_wake = 0;
-
-       count = bh->b_size >> 9;
-       sector = bh->b_rsector;
-       sync = test_and_clear_bit(BH_Sync, &bh->b_state);
-
-       rw_ahead = 0;   /* normal case; gets changed below for READA */
-       switch (rw) {
-               case READA:
-#if 0  /* bread() misinterprets failed READA attempts as IO errors on SMP */
-                       rw_ahead = 1;
-#endif
-                       rw = READ;      /* drop into READ */
-               case READ:
-               case WRITE:
-                       latency = elevator_request_latency(elevator, rw);
-                       break;
-               default:
-                       BUG();
-                       goto end_io;
-       }
-
-       /* We'd better have a real physical mapping!
-          Check this bit only if the buffer was dirty and just locked
-          down by us so at this point flushpage will block and
-          won't clear the mapped bit under us. */
-       if (!buffer_mapped(bh))
-               BUG();
-
-       /*
-        * Temporary solution - in 2.5 this will be done by the lowlevel
-        * driver. Create a bounce buffer if the buffer data points into
-        * high memory - keep the original buffer otherwise.
-        */
-       bh = blk_queue_bounce(q, rw, bh);
-
-/* look for a free request. */
-       /*
-        * Try to coalesce the new request with old requests
-        */
-       max_sectors = get_max_sectors(bh->b_rdev);
-
-       req = NULL;
-       head = &q->queue_head;
-       /*
-        * Now we acquire the request spinlock, we have to be mega careful
-        * not to schedule or do something nonatomic
-        */
-       spin_lock_irq(&io_request_lock);
-
-again:
-       insert_here = head->prev;
-
-       if (list_empty(head)) {
-               q->plug_device_fn(q, bh->b_rdev); /* is atomic */
-               goto get_rq;
-       } else if (q->head_active && !q->plugged)
-               head = head->next;
-
-       el_ret = elevator->elevator_merge_fn(q, &req, head, bh, rw,max_sectors);
-       switch (el_ret) {
-
-               case ELEVATOR_BACK_MERGE:
-                       if (!q->back_merge_fn(q, req, bh, max_segments)) {
-                               insert_here = &req->queue;
-                               break;
-                       }
-                       req->bhtail->b_reqnext = bh;
-                       req->bhtail = bh;
-                       req->nr_sectors = req->hard_nr_sectors += count;
-                       blk_started_io(count);
-                       blk_started_sectors(req, count);
-                       drive_stat_acct(req->rq_dev, req->cmd, count, 0);
-                       req_new_io(req, 1, count);
-                       attempt_back_merge(q, req, max_sectors, max_segments);
-                       goto out;
-
-               case ELEVATOR_FRONT_MERGE:
-                       if (!q->front_merge_fn(q, req, bh, max_segments)) {
-                               insert_here = req->queue.prev;
-                               break;
-                       }
-                       bh->b_reqnext = req->bh;
-                       req->bh = bh;
-                       /*
-                        * may not be valid, but queues not having bounce
-                        * enabled for highmem pages must not look at
-                        * ->buffer anyway
-                        */
-                       req->buffer = bh->b_data;
-                       req->current_nr_sectors = req->hard_cur_sectors = count;
-                       req->sector = req->hard_sector = sector;
-                       req->nr_sectors = req->hard_nr_sectors += count;
-                       blk_started_io(count);
-                       blk_started_sectors(req, count);
-                       drive_stat_acct(req->rq_dev, req->cmd, count, 0);
-                       req_new_io(req, 1, count);
-                       attempt_front_merge(q, head, req, max_sectors, 
max_segments);
-                       goto out;
-
-               /*
-                * elevator says don't/can't merge. get new request
-                */
-               case ELEVATOR_NO_MERGE:
-                       /*
-                        * use elevator hints as to where to insert the
-                        * request. if no hints, just add it to the back
-                        * of the queue
-                        */
-                       if (req)
-                               insert_here = &req->queue;
-                       break;
-
-               default:
-                       printk("elevator returned crap (%d)\n", el_ret);
-                       BUG();
-       }
-               
-get_rq:
-       if (freereq) {
-               req = freereq;
-               freereq = NULL;
-       } else {
-               /*
-                * See description above __get_request_wait()
-                */
-               if (rw_ahead) {
-                       if (q->rq.count < q->batch_requests || 
blk_oversized_queue_batch(q)) {
-                               spin_unlock_irq(&io_request_lock);
-                               goto end_io;
-                       }
-                       req = get_request(q, rw);
-                       if (req == NULL)
-                               BUG();
-               } else {
-                       req = get_request(q, rw);
-                       if (req == NULL) {
-                               spin_unlock_irq(&io_request_lock);
-                               freereq = __get_request_wait(q, rw);
-                               head = &q->queue_head;
-                               spin_lock_irq(&io_request_lock);
-                               should_wake = 1;
-                               goto again;
-                       }
-               }
-       }
-
-/* fill up the request-info, and add it to the queue */
-       req->elevator_sequence = latency;
-       req->cmd = rw;
-       req->errors = 0;
-       req->hard_sector = req->sector = sector;
-       req->hard_nr_sectors = req->nr_sectors = count;
-       req->current_nr_sectors = req->hard_cur_sectors = count;
-       req->nr_segments = 1; /* Always 1 for a new request. */
-       req->nr_hw_segments = 1; /* Always 1 for a new request. */
-       req->buffer = bh->b_data;
-       req->waiting = NULL;
-       req->bh = bh;
-       req->bhtail = bh;
-       req->rq_dev = bh->b_rdev;
-       req->start_time = jiffies;
-       req_new_io(req, 0, count);
-       blk_started_io(count);
-       blk_started_sectors(req, count);
-       add_request(q, req, insert_here);
-out:
-       if (freereq)
-               blkdev_release_request(freereq);
-       if (should_wake)
-               get_request_wait_wakeup(q, rw);
-       if (sync)
-               __generic_unplug_device(q);
-       spin_unlock_irq(&io_request_lock);
-       return 0;
-end_io:
-       bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
-       return 0;
-}
-
-/**
- * generic_make_request: hand a buffer head to it's device driver for I/O
- * @rw:  READ, WRITE, or READA - what sort of I/O is desired.
- * @bh:  The buffer head describing the location in memory and on the device.
- *
- * generic_make_request() is used to make I/O requests of block
- * devices. It is passed a &struct buffer_head and a &rw value.  The
- * %READ and %WRITE options are (hopefully) obvious in meaning.  The
- * %READA value means that a read is required, but that the driver is
- * free to fail the request if, for example, it cannot get needed
- * resources immediately.
- *
- * generic_make_request() does not return any status.  The
- * success/failure status of the request, along with notification of
- * completion, is delivered asynchronously through the bh->b_end_io
- * function described (one day) else where.
- *
- * The caller of generic_make_request must make sure that b_page,
- * b_addr, b_size are set to describe the memory buffer, that b_rdev
- * and b_rsector are set to describe the device address, and the
- * b_end_io and optionally b_private are set to describe how
- * completion notification should be signaled.  BH_Mapped should also
- * be set (to confirm that b_dev and b_blocknr are valid).
- *
- * generic_make_request and the drivers it calls may use b_reqnext,
- * and may change b_rdev and b_rsector.  So the values of these fields
- * should NOT be depended on after the call to generic_make_request.
- * Because of this, the caller should record the device address
- * information in b_dev and b_blocknr.
- *
- * Apart from those fields mentioned above, no other fields, and in
- * particular, no other flags, are changed by generic_make_request or
- * any lower level drivers.
- * */
-void generic_make_request (int rw, struct buffer_head * bh)
-{
-       int major = MAJOR(bh->b_rdev);
-       int minorsize = 0;
-       request_queue_t *q;
-
-       if (!bh->b_end_io)
-               BUG();
-
-       /* Test device size, when known. */
-       if (blk_size[major])
-               minorsize = blk_size[major][MINOR(bh->b_rdev)];
-       if (minorsize) {
-               unsigned long maxsector = (minorsize << 1) + 1;
-               unsigned long sector = bh->b_rsector;
-               unsigned int count = bh->b_size >> 9;
-
-               if (maxsector < count || maxsector - count < sector) {
-                       /* Yecch */
-                       bh->b_state &= ~(1 << BH_Dirty);
-
-                       /* This may well happen - the kernel calls bread()
-                          without checking the size of the device, e.g.,
-                          when mounting a device. */
-                       printk(KERN_INFO
-                              "attempt to access beyond end of device\n");
-                       printk(KERN_INFO "%s: rw=%d, want=%ld, limit=%d\n",
-                              kdevname(bh->b_rdev), rw,
-                              (sector + count)>>1, minorsize);
-
-                       bh->b_end_io(bh, 0);
-                       return;
-               }
-       }
-
-       /*
-        * Resolve the mapping until finished. (drivers are
-        * still free to implement/resolve their own stacking
-        * by explicitly returning 0)
-        */
-       /* NOTE: we don't repeat the blk_size check for each new device.
-        * Stacking drivers are expected to know what they are doing.
-        */
-       do {
-               q = __blk_get_queue(bh->b_rdev);
-               if (!q) {
-                       printk(KERN_ERR
-                              "generic_make_request: Trying to access "
-                              "nonexistent block-device %s (%ld)\n",
-                              kdevname(bh->b_rdev), bh->b_rsector);
-                       buffer_IO_error(bh);
-                       break;
-               }
-       } while (q->make_request_fn(q, rw, bh));
-}
-
-
-/**
- * submit_bh: submit a buffer_head to the block device later for I/O
- * @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
- * @bh: The &struct buffer_head which describes the I/O
- *
- * submit_bh() is very similar in purpose to generic_make_request(), and
- * uses that function to do most of the work.
- *
- * The extra functionality provided by submit_bh is to determine
- * b_rsector from b_blocknr and b_size, and to set b_rdev from b_dev.
- * This is is appropriate for IO requests that come from the buffer
- * cache and page cache which (currently) always use aligned blocks.
- */
-void submit_bh(int rw, struct buffer_head * bh)
-{
-       int count = bh->b_size >> 9;
-
-       if (!test_bit(BH_Lock, &bh->b_state))
-               BUG();
-
-       set_bit(BH_Req, &bh->b_state);
-       set_bit(BH_Launder, &bh->b_state);
-
-       /*
-        * First step, 'identity mapping' - RAID or LVM might
-        * further remap this.
-        */
-       bh->b_rdev = bh->b_dev;
-       bh->b_rsector = bh->b_blocknr * count;
-
-       get_bh(bh);
-       generic_make_request(rw, bh);
-
-       /* fix race condition with wait_on_buffer() */
-       smp_mb(); /* spin_unlock may have inclusive semantics */
-       if (waitqueue_active(&bh->b_wait))
-               wake_up(&bh->b_wait);
-
-       if (block_dump)
-               printk(KERN_DEBUG "%s: %s block %lu/%u on %s\n", current->comm, 
rw == WRITE ? "WRITE" : "READ", bh->b_rsector, count, kdevname(bh->b_rdev));
-
-       put_bh(bh);
-       switch (rw) {
-               case WRITE:
-                       kstat.pgpgout += count;
-                       break;
-               default:
-                       kstat.pgpgin += count;
-                       break;
-       }
-}
-
-/**
- * ll_rw_block: low-level access to block devices
- * @rw: whether to %READ or %WRITE or maybe %READA (readahead)
- * @nr: number of &struct buffer_heads in the array
- * @bhs: array of pointers to &struct buffer_head
- *
- * ll_rw_block() takes an array of pointers to &struct buffer_heads,
- * and requests an I/O operation on them, either a %READ or a %WRITE.
- * The third %READA option is described in the documentation for
- * generic_make_request() which ll_rw_block() calls.
- *
- * This function provides extra functionality that is not in
- * generic_make_request() that is relevant to buffers in the buffer
- * cache or page cache.  In particular it drops any buffer that it
- * cannot get a lock on (with the BH_Lock state bit), any buffer that
- * appears to be clean when doing a write request, and any buffer that
- * appears to be up-to-date when doing read request.  Further it marks
- * as clean buffers that are processed for writing (the buffer cache
- * wont assume that they are actually clean until the buffer gets
- * unlocked).
- *
- * ll_rw_block sets b_end_io to simple completion handler that marks
- * the buffer up-to-date (if approriate), unlocks the buffer and wakes
- * any waiters.  As client that needs a more interesting completion
- * routine should call submit_bh() (or generic_make_request())
- * directly.
- *
- * Caveat:
- *  All of the buffers must be for the same device, and must also be
- *  of the current approved size for the device.  */
-
-void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])
-{
-       unsigned int major;
-       int correct_size;
-       int i;
-
-       if (!nr)
-               return;
-
-       major = MAJOR(bhs[0]->b_dev);
-
-       /* Determine correct block size for this device. */
-       correct_size = get_hardsect_size(bhs[0]->b_dev);
-
-       /* Verify requested block sizes. */
-       for (i = 0; i < nr; i++) {
-               struct buffer_head *bh = bhs[i];
-               if (bh->b_size % correct_size) {
-                       printk(KERN_NOTICE "ll_rw_block: device %s: "
-                              "only %d-char blocks implemented (%u)\n",
-                              kdevname(bhs[0]->b_dev),
-                              correct_size, bh->b_size);
-                       goto sorry;
-               }
-       }
-
-       if ((rw & WRITE) && is_read_only(bhs[0]->b_dev)) {
-               printk(KERN_NOTICE "Can't write to read-only device %s\n",
-                      kdevname(bhs[0]->b_dev));
-               goto sorry;
-       }
-
-       for (i = 0; i < nr; i++) {
-               struct buffer_head *bh = bhs[i];
-
-               lock_buffer(bh);
-
-               /* We have the buffer lock */
-               atomic_inc(&bh->b_count);
-               bh->b_end_io = end_buffer_io_sync;
-
-               switch(rw) {
-               case WRITE:
-                       if (!atomic_set_buffer_clean(bh))
-                               /* Hmmph! Nothing to write */
-                               goto end_io;
-                       __mark_buffer_clean(bh);
-                       break;
-
-               case READA:
-               case READ:
-                       if (buffer_uptodate(bh))
-                               /* Hmmph! Already have it */
-                               goto end_io;
-                       break;
-               default:
-                       BUG();
-       end_io:
-                       bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
-                       continue;
-               }
-
-               submit_bh(rw, bh);
-       }
-       return;
-
-sorry:
-       /* Make sure we don't get infinite dirty retries.. */
-       for (i = 0; i < nr; i++)
-               mark_buffer_clean(bhs[i]);
-}
-
-#ifdef CONFIG_STRAM_SWAP
-extern int stram_device_init (void);
-#endif
-
-static void blk_writeback_timer(unsigned long data)
-{
-       wakeup_bdflush();
-       wakeup_kupdate();
-}
-
-/**
- * end_that_request_first - end I/O on one buffer.
- * @req:      the request being processed
- * @uptodate: 0 for I/O error
- * @name:     the name printed for an I/O error
- *
- * Description:
- *     Ends I/O on the first buffer attached to @req, and sets it up
- *     for the next buffer_head (if any) in the cluster.
- *     
- * Return:
- *     0 - we are done with this request, call end_that_request_last()
- *     1 - still buffers pending for this request
- *
- * Caveat: 
- *     Drivers implementing their own end_request handling must call
- *     blk_finished_io() appropriately.
- **/
-
-int end_that_request_first (struct request *req, int uptodate, char *name)
-{
-       struct buffer_head * bh;
-       int nsect;
-
-       req->errors = 0;
-       if (!uptodate)
-               printk("end_request: I/O error, dev %s (%s), sector %lu\n",
-                       kdevname(req->rq_dev), name, req->sector);
-
-       if ((bh = req->bh) != NULL) {
-               nsect = bh->b_size >> 9;
-               blk_finished_io(nsect);
-               blk_finished_sectors(req, nsect);
-               req->bh = bh->b_reqnext;
-               bh->b_reqnext = NULL;
-               bh->b_end_io(bh, uptodate);
-               if ((bh = req->bh) != NULL) {
-                       req->hard_sector += nsect;
-                       req->hard_nr_sectors -= nsect;
-                       req->sector = req->hard_sector;
-                       req->nr_sectors = req->hard_nr_sectors;
-
-                       req->current_nr_sectors = bh->b_size >> 9;
-                       req->hard_cur_sectors = req->current_nr_sectors;
-                       if (req->nr_sectors < req->current_nr_sectors) {
-                               req->nr_sectors = req->current_nr_sectors;
-                               printk("end_request: buffer-list destroyed\n");
-                       }
-                       req->buffer = bh->b_data;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-extern int laptop_mode;
-
-void end_that_request_last(struct request *req)
-{
-       struct completion *waiting = req->waiting;
-
-       /*
-        * schedule the writeout of pending dirty data when the disk is idle
-        */
-       if (laptop_mode && req->cmd == READ)
-               mod_timer(&writeback_timer, jiffies + 5 * HZ);
-
-       req_finished_io(req);
-       blkdev_release_request(req);
-       if (waiting)
-               complete(waiting);
-}
-
-int __init blk_dev_init(void)
-{
-       struct blk_dev_struct *dev;
-
-       request_cachep = kmem_cache_create("blkdev_requests",
-                                          sizeof(struct request),
-                                          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-
-       if (!request_cachep)
-               panic("Can't create request pool slab cache\n");
-
-       for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;)
-               dev->queue = NULL;
-
-       memset(ro_bits,0,sizeof(ro_bits));
-       memset(max_readahead, 0, sizeof(max_readahead));
-       memset(max_sectors, 0, sizeof(max_sectors));
-
-       blk_max_low_pfn = max_low_pfn - 1;
-       blk_max_pfn = max_pfn - 1;
-
-       init_timer(&writeback_timer);
-       writeback_timer.function = blk_writeback_timer;
-
-#ifdef CONFIG_AMIGA_Z2RAM
-       z2_init();
-#endif
-#ifdef CONFIG_STRAM_SWAP
-       stram_device_init();
-#endif
-#ifdef CONFIG_ISP16_CDI
-       isp16_init();
-#endif
-#ifdef CONFIG_BLK_DEV_PS2
-       ps2esdi_init();
-#endif
-#ifdef CONFIG_BLK_DEV_XD
-       xd_init();
-#endif
-#ifdef CONFIG_BLK_DEV_MFM
-       mfm_init();
-#endif
-#ifdef CONFIG_PARIDE
-       { extern void paride_init(void); paride_init(); };
-#endif
-#ifdef CONFIG_MAC_FLOPPY
-       swim3_init();
-#endif
-#ifdef CONFIG_BLK_DEV_SWIM_IOP
-       swimiop_init();
-#endif
-#ifdef CONFIG_AMIGA_FLOPPY
-       amiga_floppy_init();
-#endif
-#ifdef CONFIG_ATARI_FLOPPY
-       atari_floppy_init();
-#endif
-#ifdef CONFIG_BLK_DEV_FD
-       floppy_init();
-#else
-#if defined(__i386__) && !defined(CONFIG_XEN) /* Do we even need this? */
-       outb_p(0xc, 0x3f2);
-#endif
-#endif
-#ifdef CONFIG_CDU31A
-       cdu31a_init();
-#endif
-#ifdef CONFIG_ATARI_ACSI
-       acsi_init();
-#endif
-#ifdef CONFIG_MCD
-       mcd_init();
-#endif
-#ifdef CONFIG_MCDX
-       mcdx_init();
-#endif
-#ifdef CONFIG_SBPCD
-       sbpcd_init();
-#endif
-#ifdef CONFIG_AZTCD
-       aztcd_init();
-#endif
-#ifdef CONFIG_CDU535
-       sony535_init();
-#endif
-#ifdef CONFIG_GSCD
-       gscd_init();
-#endif
-#ifdef CONFIG_CM206
-       cm206_init();
-#endif
-#ifdef CONFIG_OPTCD
-       optcd_init();
-#endif
-#ifdef CONFIG_SJCD
-       sjcd_init();
-#endif
-#ifdef CONFIG_APBLOCK
-       ap_init();
-#endif
-#ifdef CONFIG_DDV
-       ddv_init();
-#endif
-#ifdef CONFIG_MDISK
-       mdisk_init();
-#endif
-#ifdef CONFIG_DASD
-       dasd_init();
-#endif
-#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_BLOCK)
-       tapeblock_init();
-#endif
-#ifdef CONFIG_BLK_DEV_XPRAM
-        xpram_init();
-#endif
-
-#ifdef CONFIG_SUN_JSFLASH
-       jsfd_init();
-#endif
-
-#if defined(CONFIG_XEN_BLKDEV_FRONTEND)
-    xlblk_init();
-#endif
-
-       return 0;
-};
-
-EXPORT_SYMBOL(io_request_lock);
-EXPORT_SYMBOL(end_that_request_first);
-EXPORT_SYMBOL(end_that_request_last);
-EXPORT_SYMBOL(blk_grow_request_list);
-EXPORT_SYMBOL(blk_init_queue);
-EXPORT_SYMBOL(blk_get_queue);
-EXPORT_SYMBOL(blk_cleanup_queue);
-EXPORT_SYMBOL(blk_queue_headactive);
-EXPORT_SYMBOL(blk_queue_throttle_sectors);
-EXPORT_SYMBOL(blk_queue_make_request);
-EXPORT_SYMBOL(generic_make_request);
-EXPORT_SYMBOL(blkdev_release_request);
-EXPORT_SYMBOL(generic_unplug_device);
-EXPORT_SYMBOL(blk_queue_bounce_limit);
-EXPORT_SYMBOL(blk_max_low_pfn);
-EXPORT_SYMBOL(blk_max_pfn);
-EXPORT_SYMBOL(blk_seg_merge_ok);
-EXPORT_SYMBOL(blk_nohighio);
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/drivers/char/Makefile
--- a/linux-2.4-xen-sparse/drivers/char/Makefile        Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,361 +0,0 @@
-#
-# Makefile for the kernel character device drivers.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now inherited from the
-# parent makes..
-#
-
-#
-# This file contains the font map for the default (hardware) font
-#
-FONTMAPFILE = cp437.uni
-
-O_TARGET := char.o
-
-obj-y   += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o
-
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs     :=     busmouse.o console.o keyboard.o sysrq.o \
-                       misc.o pty.o random.o selection.o serial.o \
-                       sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
-                       au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \
-                       scx200.o fetchop.o
-
-mod-subdirs    :=      joystick ftape drm drm-4.0 pcmcia
-
-list-multi     :=      
-
-KEYMAP   =defkeymap.o
-KEYBD    =pc_keyb.o
-CONSOLE  =console.o
-SERIAL   =serial.o
-
-ifeq ($(ARCH),xen)
-  ifneq ($(CONFIG_XEN_PHYSDEV_ACCESS),y)
-    KEYBD  =
-  endif
-endif
-
-ifeq ($(ARCH),s390)
-  KEYMAP   =
-  KEYBD    =
-  CONSOLE  =
-  SERIAL   =
-endif
-
-ifeq ($(ARCH),mips)
-  ifneq ($(CONFIG_PC_KEYB),y)
-    KEYBD    =
-  endif
-  ifeq ($(CONFIG_VR41XX_KIU),y)
-    KEYMAP   =
-    KEYBD    = vr41xx_keyb.o
-  endif
-endif
-
-ifeq ($(ARCH),s390x)
-  KEYMAP   =
-  KEYBD    =
-  CONSOLE  =
-  SERIAL   =
-endif
-
-ifeq ($(ARCH),m68k)
-   ifdef CONFIG_AMIGA
-      KEYBD = amikeyb.o
-   else
-      ifndef CONFIG_MAC
-        KEYBD =
-      endif
-   endif
-   SERIAL   =
-endif
-
-ifeq ($(ARCH),parisc)
-   ifdef CONFIG_GSC_PS2
-      KEYBD   = hp_psaux.o hp_keyb.o
-   else
-      KEYBD   =
-   endif
-   ifdef CONFIG_SERIAL_MUX
-      CONSOLE += mux.o
-   endif
-   ifdef CONFIG_PDC_CONSOLE
-      CONSOLE += pdc_console.o
-   endif
-endif
-
-ifdef CONFIG_Q40
-  KEYBD += q40_keyb.o
-  SERIAL = serial.o
-endif
-
-ifdef CONFIG_APOLLO
-  KEYBD += dn_keyb.o
-endif
-
-ifeq ($(ARCH),parisc)
-   ifdef CONFIG_GSC_PS2
-      KEYBD   = hp_psaux.o hp_keyb.o
-   else
-      KEYBD   =
-   endif
-   ifdef CONFIG_PDC_CONSOLE
-      CONSOLE += pdc_console.o
-   endif
-endif
-
-ifeq ($(ARCH),arm)
-  ifneq ($(CONFIG_PC_KEYMAP),y)
-    KEYMAP   =
-  endif
-  ifneq ($(CONFIG_PC_KEYB),y)
-    KEYBD    =
-  endif
-endif
-
-ifeq ($(ARCH),sh)
-  KEYMAP   =
-  KEYBD    =
-  CONSOLE  =
-  ifeq ($(CONFIG_SH_HP600),y)
-  KEYMAP   = defkeymap.o
-  KEYBD    = scan_keyb.o hp600_keyb.o
-  CONSOLE  = console.o
-  endif
-  ifeq ($(CONFIG_SH_DMIDA),y)
-  # DMIDA does not connect the HD64465 PS/2 keyboard port
-  # but we allow for USB keyboards to be plugged in.
-  KEYMAP   = defkeymap.o
-  KEYBD    = # hd64465_keyb.o pc_keyb.o
-  CONSOLE  = console.o
-  endif
-  ifeq ($(CONFIG_SH_EC3104),y)
-  KEYMAP   = defkeymap.o
-  KEYBD    = ec3104_keyb.o
-  CONSOLE  = console.o
-  endif
-  ifeq ($(CONFIG_SH_DREAMCAST),y)
-  KEYMAP   = defkeymap.o
-  KEYBD    =
-  CONSOLE  = console.o
-  endif
-endif
-
-ifeq ($(CONFIG_DECSTATION),y)
-  KEYMAP   =
-  KEYBD    =
-endif
-
-ifeq ($(CONFIG_BAGET_MIPS),y)
-  KEYBD    =
-  SERIAL   = vac-serial.o
-endif
-
-ifeq ($(CONFIG_NINO),y)
-  SERIAL   =
-endif
-
-ifneq ($(CONFIG_SUN_SERIAL),)
-  SERIAL   =
-endif
-
-ifeq ($(CONFIG_QTRONIX_KEYBOARD),y)
-  KEYBD    = qtronix.o
-  KEYMAP   = qtronixmap.o
-endif
-
-ifeq ($(CONFIG_DUMMY_KEYB),y)
-  KEYBD = dummy_keyb.o
-endif
-
-obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o 
$(CONSOLE) selection.o
-obj-$(CONFIG_SERIAL) += $(SERIAL)
-obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o
-obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o
-obj-$(CONFIG_SERIAL_21285) += serial_21285.o
-obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o
-obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o
-obj-$(CONFIG_TS_AU1X00_ADS7846) += au1000_ts.o
-obj-$(CONFIG_SERIAL_DEC) += decserial.o
-
-ifndef CONFIG_SUN_KEYBOARD
-  obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
-else
-  obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP)
-endif
-
-obj-$(CONFIG_HIL) += hp_keyb.o
-obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
-obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
-obj-$(CONFIG_ROCKETPORT) += rocket.o
-obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
-obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
-obj-$(CONFIG_DIGI) += pcxx.o
-obj-$(CONFIG_DIGIEPCA) += epca.o
-obj-$(CONFIG_CYCLADES) += cyclades.o
-obj-$(CONFIG_STALLION) += stallion.o
-obj-$(CONFIG_ISTALLION) += istallion.o
-obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o
-obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o
-obj-$(CONFIG_RISCOM8) += riscom8.o
-obj-$(CONFIG_ISI) += isicom.o
-obj-$(CONFIG_ESPSERIAL) += esp.o
-obj-$(CONFIG_SYNCLINK) += synclink.o
-obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
-obj-$(CONFIG_N_HDLC) += n_hdlc.o
-obj-$(CONFIG_SPECIALIX) += specialix.o
-obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
-obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o
-obj-$(CONFIG_SX) += sx.o generic_serial.o
-obj-$(CONFIG_RIO) += rio/rio.o generic_serial.o
-obj-$(CONFIG_SH_SCI) += sh-sci.o generic_serial.o
-obj-$(CONFIG_SERIAL167) += serial167.o
-obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o
-obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
-obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
-obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o
-obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o
-obj-$(CONFIG_TXX927_SERIAL) += serial_txx927.o
-obj-$(CONFIG_SERIAL_TXX9) += generic_serial.o serial_txx9.o
-obj-$(CONFIG_IP22_SERIAL) += sgiserial.o
-obj-$(CONFIG_AU1X00_UART) += au1x00-serial.o
-obj-$(CONFIG_SGI_L1_SERIAL) += sn_serial.o
-
-subdir-$(CONFIG_RIO) += rio
-subdir-$(CONFIG_INPUT) += joystick
-
-obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o
-obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o
-obj-$(CONFIG_PRINTER) += lp.o
-obj-$(CONFIG_TIPAR) += tipar.o
-obj-$(CONFIG_OBMOUSE) += obmouse.o
-
-ifeq ($(CONFIG_INPUT),y)
-obj-y += joystick/js.o
-endif
-
-obj-$(CONFIG_FETCHOP) += fetchop.o
-obj-$(CONFIG_BUSMOUSE) += busmouse.o
-obj-$(CONFIG_DTLK) += dtlk.o
-obj-$(CONFIG_R3964) += n_r3964.o
-obj-$(CONFIG_APPLICOM) += applicom.o
-obj-$(CONFIG_SONYPI) += sonypi.o
-obj-$(CONFIG_MS_BUSMOUSE) += msbusmouse.o
-obj-$(CONFIG_82C710_MOUSE) += qpmouse.o
-obj-$(CONFIG_AMIGAMOUSE) += amigamouse.o
-obj-$(CONFIG_ATARIMOUSE) += atarimouse.o
-obj-$(CONFIG_ADBMOUSE) += adbmouse.o
-obj-$(CONFIG_PC110_PAD) += pc110pad.o
-obj-$(CONFIG_MK712_MOUSE) += mk712.o
-obj-$(CONFIG_RTC) += rtc.o
-obj-$(CONFIG_GEN_RTC) += genrtc.o
-obj-$(CONFIG_EFI_RTC) += efirtc.o
-obj-$(CONFIG_SGI_DS1286) += ds1286.o
-obj-$(CONFIG_MIPS_RTC) += mips_rtc.o
-obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
-ifeq ($(CONFIG_PPC),)
-  obj-$(CONFIG_NVRAM) += nvram.o
-endif
-obj-$(CONFIG_TOSHIBA) += toshiba.o
-obj-$(CONFIG_I8K) += i8k.o
-obj-$(CONFIG_DS1620) += ds1620.o
-obj-$(CONFIG_DS1742) += ds1742.o
-obj-$(CONFIG_INTEL_RNG) += i810_rng.o
-obj-$(CONFIG_AMD_RNG) += amd768_rng.o
-obj-$(CONFIG_HW_RANDOM) += hw_random.o
-obj-$(CONFIG_AMD_PM768) += amd76x_pm.o
-obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
-
-obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
-obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o
-obj-$(CONFIG_AU1X00_USB_TTY) += au1000_usbtty.o
-obj-$(CONFIG_AU1X00_USB_RAW) += au1000_usbraw.o
-obj-$(CONFIG_COBALT_LCD) += lcd.o
-
-obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
-
-subdir-$(CONFIG_FTAPE) += ftape
-subdir-$(CONFIG_DRM_OLD) += drm-4.0
-subdir-$(CONFIG_DRM_NEW) += drm
-subdir-$(CONFIG_PCMCIA) += pcmcia
-subdir-$(CONFIG_AGP) += agp
-
-ifeq ($(CONFIG_FTAPE),y)
-obj-y       += ftape/ftape.o
-endif
-
-obj-$(CONFIG_H8) += h8.o
-obj-$(CONFIG_PPDEV) += ppdev.o
-obj-$(CONFIG_DZ) += dz.o
-obj-$(CONFIG_NWBUTTON) += nwbutton.o
-obj-$(CONFIG_NWFLASH) += nwflash.o
-obj-$(CONFIG_SCx200) += scx200.o
-obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
-
-# Only one watchdog can succeed. We probe the hardware watchdog
-# drivers first, then the softdog driver.  This means if your hardware
-# watchdog dies or is 'borrowed' for some reason the software watchdog
-# still gives you some cover.
-
-obj-$(CONFIG_PCWATCHDOG) += pcwd.o
-obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
-obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
-obj-$(CONFIG_IB700_WDT) += ib700wdt.o
-obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
-obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
-obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
-obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
-obj-$(CONFIG_WDT) += wdt.o
-obj-$(CONFIG_WDTPCI) += wdt_pci.o
-obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
-obj-$(CONFIG_977_WATCHDOG) += wdt977.o
-obj-$(CONFIG_I810_TCO) += i810-tco.o
-obj-$(CONFIG_MACHZ_WDT) += machzwd.o
-obj-$(CONFIG_SH_WDT) += shwdt.o
-obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
-obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
-obj-$(CONFIG_ALIM1535_WDT) += alim1535d_wdt.o
-obj-$(CONFIG_INDYDOG) += indydog.o
-obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
-obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
-obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
-obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
-obj-$(CONFIG_INDYDOG) += indydog.o
-obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
-
-subdir-$(CONFIG_MWAVE) += mwave
-ifeq ($(CONFIG_MWAVE),y)
-  obj-y += mwave/mwave.o
-endif
-
-subdir-$(CONFIG_IPMI_HANDLER) += ipmi
-ifeq ($(CONFIG_IPMI_HANDLER),y)
-  obj-y += ipmi/ipmi.o
-endif
-
-include $(TOPDIR)/Rules.make
-
-fastdep:
-
-conmakehash: conmakehash.c
-       $(HOSTCC) $(HOSTCFLAGS) -o conmakehash conmakehash.c
-
-consolemap_deftbl.c: $(FONTMAPFILE) conmakehash
-       ./conmakehash $(FONTMAPFILE) > consolemap_deftbl.c
-
-consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h
-
-.DELETE_ON_ERROR:
-
-defkeymap.c: defkeymap.map
-       set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
-
-qtronixmap.c: qtronixmap.map
-       set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/drivers/char/mem.c
--- a/linux-2.4-xen-sparse/drivers/char/mem.c   Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,812 +0,0 @@
-/*
- *  linux/drivers/char/mem.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  Added devfs support. 
- *    Jan-11-1998, C. Scott Ananian <cananian@xxxxxxxxxxxxxxxxxxxx>
- *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@xxxxxxx>
- *
- *  MODIFIED FOR XEN by Keir Fraser, 10th July 2003.
- *  Linux running on Xen has strange semantics for /dev/mem and /dev/kmem!!
- *   1. mmap will not work on /dev/kmem
- *   2. mmap on /dev/mem interprets the 'file offset' as a machine address
- *      rather than a physical address.
- *  I don't believe anyone sane mmaps /dev/kmem, but /dev/mem is mmapped
- *  to get at memory-mapped I/O spaces (eg. the VESA X server does this).
- *  For this to work at all we need to expect machine addresses.
- *  Reading/writing of /dev/kmem expects kernel virtual addresses, as usual.
- *  Reading/writing of /dev/mem expects 'physical addresses' as usual -- this
- *  is because /dev/mem can only read/write existing kernel mappings, which
- *  will be normal RAM, and we should present pseudo-physical layout for all
- *  except I/O (which is the sticky case that mmap is hacked to deal with).
- */
-
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/miscdevice.h>
-#include <linux/tpqic02.h>
-#include <linux/ftape.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mman.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/raw.h>
-#include <linux/tty.h>
-#include <linux/capability.h>
-#include <linux/ptrace.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgalloc.h>
-
-#ifdef CONFIG_I2C
-extern int i2c_init_all(void);
-#endif
-#ifdef CONFIG_FB
-extern void fbmem_init(void);
-#endif
-#ifdef CONFIG_PROM_CONSOLE
-extern void prom_con_init(void);
-#endif
-#ifdef CONFIG_MDA_CONSOLE
-extern void mda_console_init(void);
-#endif
-#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
-extern void tapechar_init(void);
-#endif
-     
-static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
-                           const char * buf, size_t count, loff_t *ppos)
-{
-       ssize_t written;
-
-       written = 0;
-#if defined(__sparc__) || defined(__mc68000__)
-       /* we don't have page 0 mapped on sparc and m68k.. */
-       if (realp < PAGE_SIZE) {
-               unsigned long sz = PAGE_SIZE-realp;
-               if (sz > count) sz = count; 
-               /* Hmm. Do something? */
-               buf+=sz;
-               p+=sz;
-               count-=sz;
-               written+=sz;
-       }
-#endif
-       if (copy_from_user(p, buf, count))
-               return -EFAULT;
-       written += count;
-       *ppos = realp + written;
-       return written;
-}
-
-
-/*
- * This funcion reads the *physical* memory. The f_pos points directly to the 
- * memory location. 
- */
-static ssize_t read_mem(struct file * file, char * buf,
-                       size_t count, loff_t *ppos)
-{
-       unsigned long p = *ppos;
-       unsigned long end_mem;
-       ssize_t read;
-       
-       end_mem = __pa(high_memory);
-       if (p >= end_mem)
-               return 0;
-       if (count > end_mem - p)
-               count = end_mem - p;
-       read = 0;
-#if defined(__sparc__) || defined(__mc68000__)
-       /* we don't have page 0 mapped on sparc and m68k.. */
-       if (p < PAGE_SIZE) {
-               unsigned long sz = PAGE_SIZE-p;
-               if (sz > count) 
-                       sz = count; 
-               if (sz > 0) {
-                       if (clear_user(buf, sz))
-                               return -EFAULT;
-                       buf += sz; 
-                       p += sz; 
-                       count -= sz; 
-                       read += sz; 
-               }
-       }
-#endif
-       if (copy_to_user(buf, __va(p), count))
-               return -EFAULT;
-       read += count;
-       *ppos = p + read;
-       return read;
-}
-
-static ssize_t write_mem(struct file * file, const char * buf, 
-                        size_t count, loff_t *ppos)
-{
-       unsigned long p = *ppos;
-       unsigned long end_mem;
-
-       end_mem = __pa(high_memory);
-       if (p >= end_mem)
-               return 0;
-       if (count > end_mem - p)
-               count = end_mem - p;
-       return do_write_mem(file, __va(p), p, buf, count, ppos);
-}
-
-#ifndef pgprot_noncached
-
-/*
- * This should probably be per-architecture in <asm/pgtable.h>
- */
-static inline pgprot_t pgprot_noncached(pgprot_t _prot)
-{
-       unsigned long prot = pgprot_val(_prot);
-
-#if defined(__i386__) || defined(__x86_64__)
-       /* On PPro and successors, PCD alone doesn't always mean 
-           uncached because of interactions with the MTRRs. PCD | PWT
-           means definitely uncached. */ 
-       if (boot_cpu_data.x86 > 3)
-               prot |= _PAGE_PCD | _PAGE_PWT;
-#elif defined(__powerpc__)
-       prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-#elif defined(__mc68000__)
-#ifdef SUN3_PAGE_NOCACHE
-       if (MMU_IS_SUN3)
-               prot |= SUN3_PAGE_NOCACHE;
-       else
-#endif
-       if (MMU_IS_851 || MMU_IS_030)
-               prot |= _PAGE_NOCACHE030;
-       /* Use no-cache mode, serialized */
-       else if (MMU_IS_040 || MMU_IS_060)
-               prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
-#endif
-
-       return __pgprot(prot);
-}
-
-#endif /* !pgprot_noncached */
-
-/*
- * Architectures vary in how they handle caching for addresses 
- * outside of main memory.
- */
-static inline int noncached_address(unsigned long addr)
-{
-#if defined(__i386__)
-       /* 
-        * On the PPro and successors, the MTRRs are used to set
-        * memory types for physical addresses outside main memory, 
-        * so blindly setting PCD or PWT on those pages is wrong.
-        * For Pentiums and earlier, the surround logic should disable 
-        * caching for the high addresses through the KEN pin, but
-        * we maintain the tradition of paranoia in this code.
-        */
-       return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
-                 test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) 
||
-                 test_bit(X86_FEATURE_CYRIX_ARR, 
&boot_cpu_data.x86_capability) ||
-                 test_bit(X86_FEATURE_CENTAUR_MCR, 
&boot_cpu_data.x86_capability) )
-         && addr >= __pa(high_memory);
-#else
-       return addr >= __pa(high_memory);
-#endif
-}
-
-#if !defined(CONFIG_XEN)
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
-{
-       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-
-       /*
-        * Accessing memory above the top the kernel knows about or
-        * through a file pointer that was marked O_SYNC will be
-        * done non-cached.
-        */
-       if (noncached_address(offset) || (file->f_flags & O_SYNC))
-               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-       /* Don't try to swap out physical pages.. */
-       vma->vm_flags |= VM_RESERVED;
-
-       /*
-        * Don't dump addresses that are not real memory to a core file.
-        */
-       if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
-               vma->vm_flags |= VM_IO;
-
-       if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
-                            vma->vm_page_prot))
-               return -EAGAIN;
-       return 0;
-}
-#elif !defined(CONFIG_XEN_PRIVILEGED_GUEST)
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
-{
-       return -ENXIO;
-}
-#else
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
-{
-       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-
-       if (!(xen_start_info.flags & SIF_PRIVILEGED))
-               return -ENXIO;
-
-       /* DONTCOPY is essential for Xen as copy_page_range is broken. */
-       vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-       if (direct_remap_area_pages(vma->vm_mm, vma->vm_start, offset, 
-                               vma->vm_end-vma->vm_start, vma->vm_page_prot,
-                               DOMID_IO))
-               return -EAGAIN;
-       return 0;
-}
-#endif /* CONFIG_XEN */
-
-/*
- * This function reads the *virtual* memory as seen by the kernel.
- */
-static ssize_t read_kmem(struct file *file, char *buf, 
-                        size_t count, loff_t *ppos)
-{
-       unsigned long p = *ppos;
-       ssize_t read = 0;
-       ssize_t virtr = 0;
-       char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
-               
-       if (p < (unsigned long) high_memory) {
-               read = count;
-               if (count > (unsigned long) high_memory - p)
-                       read = (unsigned long) high_memory - p;
-
-#if defined(__sparc__) || defined(__mc68000__)
-               /* we don't have page 0 mapped on sparc and m68k.. */
-               if (p < PAGE_SIZE && read > 0) {
-                       size_t tmp = PAGE_SIZE - p;
-                       if (tmp > read) tmp = read;
-                       if (clear_user(buf, tmp))
-                               return -EFAULT;
-                       buf += tmp;
-                       p += tmp;
-                       read -= tmp;
-                       count -= tmp;
-               }
-#endif
-               if (copy_to_user(buf, (char *)p, read))
-                       return -EFAULT;
-               p += read;
-               buf += read;
-               count -= read;
-       }
-
-       if (count > 0) {
-               kbuf = (char *)__get_free_page(GFP_KERNEL);
-               if (!kbuf)
-                       return -ENOMEM;
-               while (count > 0) {
-                       int len = count;
-
-                       if (len > PAGE_SIZE)
-                               len = PAGE_SIZE;
-                       len = vread(kbuf, (char *)p, len);
-                       if (!len)
-                               break;
-                       if (copy_to_user(buf, kbuf, len)) {
-                               free_page((unsigned long)kbuf);
-                               return -EFAULT;
-                       }
-                       count -= len;
-                       buf += len;
-                       virtr += len;
-                       p += len;
-               }
-               free_page((unsigned long)kbuf);
-       }
-       *ppos = p;
-       return virtr + read;
-}
-
-extern long vwrite(char *buf, char *addr, unsigned long count);
-
-/*
- * This function writes to the *virtual* memory as seen by the kernel.
- */
-static ssize_t write_kmem(struct file * file, const char * buf, 
-                         size_t count, loff_t *ppos)
-{
-       unsigned long p = *ppos;
-       ssize_t wrote = 0;
-       ssize_t virtr = 0;
-       char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
-
-       if (p < (unsigned long) high_memory) {
-               wrote = count;
-               if (count > (unsigned long) high_memory - p)
-                       wrote = (unsigned long) high_memory - p;
-
-               wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
-
-               p += wrote;
-               buf += wrote;
-               count -= wrote;
-       }
-
-       if (count > 0) {
-               kbuf = (char *)__get_free_page(GFP_KERNEL);
-               if (!kbuf)
-                       return -ENOMEM;
-               while (count > 0) {
-                       int len = count;
-
-                       if (len > PAGE_SIZE)
-                               len = PAGE_SIZE;
-                       if (len && copy_from_user(kbuf, buf, len)) {
-                               free_page((unsigned long)kbuf);
-                               return -EFAULT;
-                       }
-                       len = vwrite(kbuf, (char *)p, len);
-                       count -= len;
-                       buf += len;
-                       virtr += len;
-                       p += len;
-               }
-               free_page((unsigned long)kbuf);
-       }
-
-       *ppos = p;
-       return virtr + wrote;
-}
-
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
-static ssize_t read_port(struct file * file, char * buf,
-                        size_t count, loff_t *ppos)
-{
-       unsigned long i = *ppos;
-       char *tmp = buf;
-
-       if (verify_area(VERIFY_WRITE,buf,count))
-               return -EFAULT; 
-       while (count-- > 0 && i < 65536) {
-               if (__put_user(inb(i),tmp) < 0) 
-                       return -EFAULT;  
-               i++;
-               tmp++;
-       }
-       *ppos = i;
-       return tmp-buf;
-}
-
-static ssize_t write_port(struct file * file, const char * buf,
-                         size_t count, loff_t *ppos)
-{
-       unsigned long i = *ppos;
-       const char * tmp = buf;
-
-       if (verify_area(VERIFY_READ,buf,count))
-               return -EFAULT;
-       while (count-- > 0 && i < 65536) {
-               char c;
-               if (__get_user(c, tmp)) 
-                       return -EFAULT; 
-               outb(c,i);
-               i++;
-               tmp++;
-       }
-       *ppos = i;
-       return tmp-buf;
-}
-#endif
-
-static ssize_t read_null(struct file * file, char * buf,
-                        size_t count, loff_t *ppos)
-{
-       return 0;
-}
-
-static ssize_t write_null(struct file * file, const char * buf,
-                         size_t count, loff_t *ppos)
-{
-       return count;
-}
-
-/*
- * For fun, we are using the MMU for this.
- */
-static inline size_t read_zero_pagealigned(char * buf, size_t size)
-{
-       struct mm_struct *mm;
-       struct vm_area_struct * vma;
-       unsigned long addr=(unsigned long)buf;
-
-       mm = current->mm;
-       /* Oops, this was forgotten before. -ben */
-       down_read(&mm->mmap_sem);
-
-       /* For private mappings, just map in zero pages. */
-       for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
-               unsigned long count;
-
-               if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
-                       goto out_up;
-               if (vma->vm_flags & VM_SHARED)
-                       break;
-               count = vma->vm_end - addr;
-               if (count > size)
-                       count = size;
-
-               zap_page_range(mm, addr, count);
-               zeromap_page_range(addr, count, PAGE_COPY);
-
-               size -= count;
-               buf += count;
-               addr += count;
-               if (size == 0)
-                       goto out_up;
-       }
-
-       up_read(&mm->mmap_sem);
-       
-       /* The shared case is hard. Let's do the conventional zeroing. */ 
-       do {
-               unsigned long unwritten = clear_user(buf, PAGE_SIZE);
-               if (unwritten)
-                       return size + unwritten - PAGE_SIZE;
-               if (current->need_resched)
-                       schedule();
-               buf += PAGE_SIZE;
-               size -= PAGE_SIZE;
-       } while (size);
-
-       return size;
-out_up:
-       up_read(&mm->mmap_sem);
-       return size;
-}
-
-static ssize_t read_zero(struct file * file, char * buf, 
-                        size_t count, loff_t *ppos)
-{
-       unsigned long left, unwritten, written = 0;
-
-       if (!count)
-               return 0;
-
-       if (!access_ok(VERIFY_WRITE, buf, count))
-               return -EFAULT;
-
-       left = count;
-
-       /* do we want to be clever? Arbitrary cut-off */
-       if (count >= PAGE_SIZE*4) {
-               unsigned long partial;
-
-               /* How much left of the page? */
-               partial = (PAGE_SIZE-1) & -(unsigned long) buf;
-               unwritten = clear_user(buf, partial);
-               written = partial - unwritten;
-               if (unwritten)
-                       goto out;
-               left -= partial;
-               buf += partial;
-               unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
-               written += (left & PAGE_MASK) - unwritten;
-               if (unwritten)
-                       goto out;
-               buf += left & PAGE_MASK;
-               left &= ~PAGE_MASK;
-       }
-       unwritten = clear_user(buf, left);
-       written += left - unwritten;
-out:
-       return written ? written : -EFAULT;
-}
-
-static int mmap_zero(struct file * file, struct vm_area_struct * vma)
-{
-       if (vma->vm_flags & VM_SHARED)
-               return shmem_zero_setup(vma);
-       if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, 
vma->vm_page_prot))
-               return -EAGAIN;
-       return 0;
-}
-
-static ssize_t write_full(struct file * file, const char * buf,
-                         size_t count, loff_t *ppos)
-{
-       return -ENOSPC;
-}
-
-/*
- * Special lseek() function for /dev/null and /dev/zero.  Most notably, you
- * can fopen() both devices with "a" now.  This was previously impossible.
- * -- SRB.
- */
-
-static loff_t null_lseek(struct file * file, loff_t offset, int orig)
-{
-       return file->f_pos = 0;
-}
-
-/*
- * The memory devices use the full 32/64 bits of the offset, and so we cannot
- * check against negative addresses: they are ok. The return value is weird,
- * though, in that case (0).
- *
- * also note that seeking relative to the "end of file" isn't supported:
- * it has no meaning, so it returns -EINVAL.
- */
-static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
-{
-       loff_t ret;
-
-       switch (orig) {
-               case 0:
-                       file->f_pos = offset;
-                       ret = file->f_pos;
-                       force_successful_syscall_return();
-                       break;
-               case 1:
-                       file->f_pos += offset;
-                       ret = file->f_pos;
-                       force_successful_syscall_return();
-                       break;
-               default:
-                       ret = -EINVAL;
-       }
-       return ret;
-}
-
-static int open_port(struct inode * inode, struct file * filp)
-{
-       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
-}
-
-struct page *kmem_vm_nopage(struct vm_area_struct *vma, unsigned long address, 
int write)
-{
-       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-       unsigned long kaddr;
-       pgd_t *pgd;
-       pmd_t *pmd;
-       pte_t *ptep, pte;
-       struct page *page = NULL;
-
-       /* address is user VA; convert to kernel VA of desired page */
-       kaddr = (address - vma->vm_start) + offset;
-       kaddr = VMALLOC_VMADDR(kaddr);
-
-       spin_lock(&init_mm.page_table_lock);
-
-       /* Lookup page structure for kernel VA */
-       pgd = pgd_offset(&init_mm, kaddr);
-       if (pgd_none(*pgd) || pgd_bad(*pgd))
-               goto out;
-       pmd = pmd_offset(pgd, kaddr);
-       if (pmd_none(*pmd) || pmd_bad(*pmd))
-               goto out;
-       ptep = pte_offset(pmd, kaddr);
-       if (!ptep)
-               goto out;
-       pte = *ptep;
-       if (!pte_present(pte))
-               goto out;
-       if (write && !pte_write(pte))
-               goto out;
-       page = pte_page(pte);
-       if (!VALID_PAGE(page)) {
-               page = NULL;
-               goto out;
-       }
-
-       /* Increment reference count on page */
-       get_page(page);
-
-out:
-       spin_unlock(&init_mm.page_table_lock);
-
-       return page;
-}
-
-struct vm_operations_struct kmem_vm_ops = {
-       nopage:         kmem_vm_nopage,
-};
-
-static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
-{
-       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-       unsigned long size = vma->vm_end - vma->vm_start;
-
-       /*
-        * If the user is not attempting to mmap a high memory address then
-        * the standard mmap_mem mechanism will work.  High memory addresses
-        * need special handling, as remap_page_range expects a physically-
-        * contiguous range of kernel addresses (such as obtained in kmalloc).
-        */
-       if ((offset + size) < (unsigned long) high_memory)
-               return mmap_mem(file, vma);
-
-       /*
-        * Accessing memory above the top the kernel knows about or
-        * through a file pointer that was marked O_SYNC will be
-        * done non-cached.
-        */
-       if (noncached_address(offset) || (file->f_flags & O_SYNC))
-               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-       /* Don't do anything here; "nopage" will fill the holes */
-       vma->vm_ops = &kmem_vm_ops;
-
-       /* Don't try to swap out physical pages.. */
-       vma->vm_flags |= VM_RESERVED;
-
-       /*
-        * Don't dump addresses that are not real memory to a core file.
-        */
-       vma->vm_flags |= VM_IO;
-
-       return 0;
-}
-
-#define zero_lseek     null_lseek
-#define full_lseek      null_lseek
-#define write_zero     write_null
-#define read_full       read_zero
-#define open_mem       open_port
-#define open_kmem      open_mem
-
-static struct file_operations mem_fops = {
-       llseek:         memory_lseek,
-       read:           read_mem,
-       write:          write_mem,
-       mmap:           mmap_mem,
-       open:           open_mem,
-};
-
-static struct file_operations kmem_fops = {
-       llseek:         memory_lseek,
-       read:           read_kmem,
-       write:          write_kmem,
-#if !defined(CONFIG_XEN)
-       mmap:           mmap_kmem,
-#endif
-       open:           open_kmem,
-};
-
-static struct file_operations null_fops = {
-       llseek:         null_lseek,
-       read:           read_null,
-       write:          write_null,
-};
-
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
-static struct file_operations port_fops = {
-       llseek:         memory_lseek,
-       read:           read_port,
-       write:          write_port,
-       open:           open_port,
-};
-#endif
-
-static struct file_operations zero_fops = {
-       llseek:         zero_lseek,
-       read:           read_zero,
-       write:          write_zero,
-       mmap:           mmap_zero,
-};
-
-static struct file_operations full_fops = {
-       llseek:         full_lseek,
-       read:           read_full,
-       write:          write_full,
-};
-
-static int memory_open(struct inode * inode, struct file * filp)
-{
-       switch (MINOR(inode->i_rdev)) {
-               case 1:
-                       filp->f_op = &mem_fops;
-                       break;
-               case 2:
-                       filp->f_op = &kmem_fops;
-                       break;
-               case 3:
-                       filp->f_op = &null_fops;
-                       break;
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
-               case 4:
-                       filp->f_op = &port_fops;
-                       break;
-#endif
-               case 5:
-                       filp->f_op = &zero_fops;
-                       break;
-               case 7:
-                       filp->f_op = &full_fops;
-                       break;
-               case 8:
-                       filp->f_op = &random_fops;
-                       break;
-               case 9:
-                       filp->f_op = &urandom_fops;
-                       break;
-               default:
-                       return -ENXIO;
-       }
-       if (filp->f_op && filp->f_op->open)
-               return filp->f_op->open(inode,filp);
-       return 0;
-}
-
-void __init memory_devfs_register (void)
-{
-    /*  These are never unregistered  */
-    static const struct {
-       unsigned short minor;
-       char *name;
-       umode_t mode;
-       struct file_operations *fops;
-    } list[] = { /* list of minor devices */
-       {1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
-       {2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
-       {3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
-       {4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
-#endif
-       {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
-       {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
-       {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
-       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
-    };
-    int i;
-
-    for (i=0; i<(sizeof(list)/sizeof(*list)); i++)
-       devfs_register (NULL, list[i].name, DEVFS_FL_NONE,
-                       MEM_MAJOR, list[i].minor,
-                       list[i].mode | S_IFCHR,
-                       list[i].fops, NULL);
-}
-
-static struct file_operations memory_fops = {
-       open:           memory_open,    /* just a selector for the real open */
-};
-
-int __init chr_dev_init(void)
-{
-       if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))
-               printk("unable to get major %d for memory devs\n", MEM_MAJOR);
-       memory_devfs_register();
-       rand_initialize();
-#ifdef CONFIG_I2C
-       i2c_init_all();
-#endif
-#if defined (CONFIG_FB)
-       fbmem_init();
-#endif
-#if defined (CONFIG_PROM_CONSOLE)
-       prom_con_init();
-#endif
-#if defined (CONFIG_MDA_CONSOLE)
-       mda_console_init();
-#endif
-       tty_init();
-#ifdef CONFIG_M68K_PRINTER
-       lp_m68k_init();
-#endif
-       misc_init();
-#if CONFIG_QIC02_TAPE
-       qic02_tape_init();
-#endif
-#ifdef CONFIG_FTAPE
-       ftape_init();
-#endif
-#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
-       tapechar_init();
-#endif
-       return 0;
-}
-
-__initcall(chr_dev_init);
diff -r 0ba10f7fef51 -r 4e0c94871be2 linux-2.4-xen-sparse/drivers/char/tty_io.c
--- a/linux-2.4-xen-sparse/drivers/char/tty_io.c        Sat Oct  8 17:37:45 2005
+++ /dev/null   Sat Oct  8 20:28:24 2005
@@ -1,2891 +0,0 @@
-/*
- *  linux/drivers/char/tty_io.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-/*
- * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
- * or rs-channels. It also implements echoing, cooked mode etc.
- *
- * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
- *
- * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
- * tty_struct and tty_queue structures.  Previously there was an array
- * of 256 tty_struct's which was statically allocated, and the
- * tty_queue structures were allocated at boot time.  Both are now
- * dynamically allocated only when the tty is open.
- *
- * Also restructured routines so that there is more of a separation
- * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
- * the low-level tty routines (serial.c, pty.c, console.c).  This
- * makes for cleaner and more compact code.  -TYT, 9/17/92 
- *
- * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
- * which can be dynamically activated and de-activated by the line
- * discipline handling modules (like SLIP).
- *
- * NOTE: pay no attention to the line discipline code (yet); its
- * interface is still subject to change in this version...
- * -- TYT, 1/31/92
- *
- * Added functionality to the OPOST tty handling.  No delays, but all
- * other bits should be there.
- *     -- Nick Holloway <alfie@xxxxxxxxxxxxxxxxx>, 27th May 1993.
- *
- * Rewrote canonical mode and added more termios flags.
- *     -- julian@xxxxxxxxxxxxxxxxxxxxxx (J. Cowley), 13Jan94
- *
- * Reorganized FASYNC support so mouse code can share it.
- *     -- ctm@xxxxxxxx, 9Sep95
- *
- * New TIOCLINUX variants added.
- *     -- mj@xxxxxxxxxxxxxxxxx, 19-Nov-95
- * 
- * Restrict vt switching via ioctl()
- *      -- grif@xxxxxxxxxx, 5-Dec-95
- *
- * Move console and virtual terminal code to more appropriate files,
- * implement CONFIG_VT and generalize console device interface.
- *     -- Marko Kohtala <Marko.Kohtala@xxxxxx>, March 97
- *
- * Rewrote init_dev and release_dev to eliminate races.
- *     -- Bill Hawes <whawes@xxxxxxxx>, June 97
- *
- * Added devfs support.
- *      -- C. Scott Ananian <cananian@xxxxxxxxxxxxxxxxxxxx>, 13-Jan-1998
- *
- * Added support for a Unix98-style ptmx device.
- *      -- C. Scott Ananian <cananian@xxxxxxxxxxxxxxxxxxxx>, 14-Jan-1998
- *
- * Reduced memory usage for older ARM systems
- *      -- Russell King <rmk@xxxxxxxxxxxxxxxx>
- *
- * Move do_SAK() into process context.  Less stack use in devfs functions.
- * alloc_tty_struct() always uses kmalloc() -- Andrew Morton 
<andrewm@xxxxxxxxxx> 17Mar01
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/devpts_fs.h>
-#include <linux/file.h>
-#include <linux/console.h>
-#include <linux/timer.h>
-#include <linux/ctype.h>
-#include <linux/kd.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/smp_lock.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/devfs_fs_kernel.h>
-
-#include <linux/kmod.h>
-
-#ifdef CONFIG_XEN_CONSOLE
-extern void xen_console_init(void);
-#endif
-
-#ifdef CONFIG_VT
-extern void con_init_devfs (void);
-#endif
-
-extern void disable_early_printk(void);
-
-#define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
-#define TTY_DEV MKDEV(TTYAUX_MAJOR,0)
-#define SYSCONS_DEV MKDEV(TTYAUX_MAJOR,1)
-#define PTMX_DEV MKDEV(TTYAUX_MAJOR,2)
-
-#undef TTY_DEBUG_HANGUP
-
-#define TTY_PARANOIA_CHECK 1
-#define CHECK_TTY_COUNT 1
-
-struct termios tty_std_termios;                /* for the benefit of tty 
drivers  */
-struct tty_driver *tty_drivers;                /* linked list of tty drivers */
-
-#ifdef CONFIG_UNIX98_PTYS
-extern struct tty_driver ptm_driver[]; /* Unix98 pty masters; for /dev/ptmx */
-extern struct tty_driver pts_driver[]; /* Unix98 pty slaves;  for /dev/ptmx */
-#endif
-
-static void initialize_tty_struct(struct tty_struct *tty);
-
-static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
-static ssize_t tty_write(struct file *, const char *, size_t, loff_t *);
-static unsigned int tty_poll(struct file *, poll_table *);
-static int tty_open(struct inode *, struct file *);
-static int tty_release(struct inode *, struct file *);
-int tty_ioctl(struct inode * inode, struct file * file,
-             unsigned int cmd, unsigned long arg);
-static int tty_fasync(int fd, struct file * filp, int on);
-extern int vme_scc_init (void);
-extern long vme_scc_console_init(void);
-extern int serial167_init(void);
-extern long serial167_console_init(void);
-extern void console_8xx_init(void);
-extern void au1x00_serial_console_init(void);
-extern int rs_8xx_init(void);
-extern void mac_scc_console_init(void);
-extern void hwc_console_init(void);
-extern void hwc_tty_init(void);
-extern void con3215_init(void);
-extern void tty3215_init(void);
-extern void tub3270_con_init(void);
-extern void tub3270_init(void);
-extern void rs285_console_init(void);
-extern void sa1100_rs_console_init(void);
-extern void sgi_serial_console_init(void);
-extern void sn_sal_serial_console_init(void);
-extern void sci_console_init(void);
-extern void dec_serial_console_init(void);
-extern void tx3912_console_init(void);
-extern void tx3912_rs_init(void);
-extern void txx927_console_init(void);
-extern void txx9_rs_init(void);
-extern void txx9_serial_console_init(void);
-extern void sb1250_serial_console_init(void);
-extern void arc_console_init(void);
-extern int hvc_console_init(void);
-
-#ifndef MIN
-#define MIN(a,b)       ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a,b)       ((a) < (b) ? (b) : (a))
-#endif
-
-static struct tty_struct *alloc_tty_struct(void)
-{
-       struct tty_struct *tty;
-
-       tty = kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
-       if (tty)
-               memset(tty, 0, sizeof(struct tty_struct));
-       return tty;
-}
-
-static inline void free_tty_struct(struct tty_struct *tty)
-{
-       kfree(tty);
-}
-
-/*
- * This routine returns the name of tty.
- */
-static char *
-_tty_make_name(struct tty_struct *tty, const char *name, char *buf)
-{
-       int idx = (tty)?MINOR(tty->device) - tty->driver.minor_start:0;
-
-       if (!tty) /* Hmm.  NULL pointer.  That's fun. */
-               strcpy(buf, "NULL tty");
-       else
-               sprintf(buf, name,
-                       idx + tty->driver.name_base);
-               
-       return buf;
-}
-
-#define TTY_NUMBER(tty) (MINOR((tty)->device) - (tty)->driver.minor_start + \
-                        (tty)->driver.name_base)
-
-char *tty_name(struct tty_struct *tty, char *buf)
-{
-       return _tty_make_name(tty, (tty)?tty->driver.name:NULL, buf);
-}
-
-inline int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
-                             const char *routine)
-{
-#ifdef TTY_PARANOIA_CHECK
-       static const char badmagic[] = KERN_WARNING
-               "Warning: bad magic number for tty struct (%s) in %s\n";
-       static const char badtty[] = KERN_WARNING
-               "Warning: null TTY for (%s) in %s\