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 28bd01c9b59604dfccac2c306d479ce6b5ac0fe5
# Parent  eae5812f33f140ef14012776af502534b3655de3
# Parent  e13c994bdccbfea46fd702fac8ce844c6fc8496c
Merge

diff -r eae5812f33f1 -r 28bd01c9b596 Config.mk
--- a/Config.mk Fri Dec  2 18:12:11 2005
+++ b/Config.mk Fri Dec  2 18:52:25 2005
@@ -38,19 +38,32 @@
 EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
 endif
 
+test-gcc-flag = $(shell $(CC) -v --help 2>&1 | grep -q " $(1) " && echo $(1))
+
+HOSTCFLAGS += $(call test-gcc-flag,-Wdeclaration-after-statement)
+CFLAGS     += $(call test-gcc-flag,-Wdeclaration-after-statement)
+
 LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i)) 
 CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))
 
 # Choose the best mirror to download linux kernel
 KERNEL_REPO = http://www.kernel.org
 
-# ACM_USE_SECURITY_POLICY is set to security policy of Xen
+# If ACM_SECURITY = y, then the access control module is compiled
+# into Xen and the policy type can be set by the boot policy file
+#        y - Build the Xen ACM framework
+#        n - Do not build the Xen ACM framework
+ACM_SECURITY ?= n
+
+# If ACM_SECURITY = y and no boot policy file is installed,
+# then the ACM defaults to the security policy set by
+# ACM_DEFAULT_SECURITY_POLICY
 # Supported models are:
-#      ACM_NULL_POLICY (ACM will not be built with this policy)
+#      ACM_NULL_POLICY
 #      ACM_CHINESE_WALL_POLICY
 #      ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY
 #      ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
-ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY
+ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_POLICY
 
 # Optional components
 XENSTAT_XENTOP ?= y
diff -r eae5812f33f1 -r 28bd01c9b596 docs/misc/vtpm.txt
--- a/docs/misc/vtpm.txt        Fri Dec  2 18:12:11 2005
+++ b/docs/misc/vtpm.txt        Fri Dec  2 18:52:25 2005
@@ -73,7 +73,14 @@
 where the TPM backend has been compiled into - this has to be 
 domain 0  at the moment - and which TPM instance the user domain
 is supposed to talk to. Note that each running VM must use a 
-different instance and that using instance 0 is NOT allowed.
+different instance and that using instance 0 is NOT allowed. The
+instance parameter is taken as the desired instance number, but
+the actual instance number that is assigned to the virtual machine
+can be different. This is the case if for example that particular
+instance is already used by another virtual machine. The association
+of which TPM instance number is used by which virtual machine is
+kept in the file /etc/xen/vtpm.db. Associations are maintained by
+domain name and instance number.
 
 Note: If you do not want TPM functionality for your user domain simply
 leave out the 'vtpm' line in the configuration file.
diff -r eae5812f33f1 -r 28bd01c9b596 install.sh
--- a/install.sh        Fri Dec  2 18:12:11 2005
+++ b/install.sh        Fri Dec  2 18:52:25 2005
@@ -27,7 +27,10 @@
 cp -fdRL $src/etc/init.d/* $dst/etc/init.d/
 echo "All done."
 
-if [ -x /sbin/udev ] && [ ! -z `/sbin/udev -V` ] && [ `/sbin/udev -V` -ge 059 
]; then
+[ -x "$(which udevinfo)" ] && \
+  UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* 
\([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
+
+if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -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/
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c  Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c  Fri Dec  2 
18:52:25 2005
@@ -155,7 +155,7 @@
     unsigned int   l1i, l2i, port;
     irqreturn_t (*handler)(int, void *, struct pt_regs *);
     shared_info_t *s = HYPERVISOR_shared_info;
-    vcpu_info_t   *vcpu_info = &s->vcpu_data[smp_processor_id()];
+    vcpu_info_t   *vcpu_info = &s->vcpu_info[smp_processor_id()];
 
     vcpu_info->evtchn_upcall_mask = 1;
     vcpu_info->evtchn_upcall_pending = 0;
@@ -203,7 +203,7 @@
 void __init evtchn_init(void)
 {
     shared_info_t *s = HYPERVISOR_shared_info;
-    vcpu_info_t   *vcpu_info = &s->vcpu_data[smp_processor_id()];
+    vcpu_info_t   *vcpu_info = &s->vcpu_info[smp_processor_id()];
 
 #if 0
     int ret;
diff -r eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/arch/xen/Kconfig
--- a/linux-2.6-xen-sparse/arch/xen/Kconfig     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/Kconfig     Fri Dec  2 18:52:25 2005
@@ -70,57 +70,12 @@
          network devices to other guests via a high-performance shared-memory
          interface.
 
-config XEN_TPMDEV_FRONTEND
-        bool "TPM-device frontend driver"
-        default n
-       select TCG_TPM
-       select TCG_XEN
-        help
-          The TPM-device frontend driver.
-
-config XEN_TPMDEV_BACKEND
-        bool "TPM-device backend driver"
-        default n
-        help
-          The TPM-device backend driver
-
-config XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
-        bool "TPM backend closes upon vTPM failure"
-        depends on XEN_TPMDEV_BACKEND
-        default n
-        help
-          The TPM backend closes the channel if the vTPM in userspace indicates
-          a failure. The corresponding domain's channel will be closed.
-          Say Y if you want this feature.
-
-config XEN_BLKDEV_FRONTEND
-       tristate "Block-device frontend driver"
-       default y
-       help
-         The block-device frontend driver allows the kernel to access block
-         devices mounted within another guest OS. Unless you are building a
-         dedicated device-driver domain, or your master control domain
-         (domain 0), then you almost certainly want to say Y here.
-
-config XEN_NETDEV_FRONTEND
-       tristate "Network-device frontend driver"
-       default y
-       help
-         The network-device frontend driver allows the kernel to access
-         network interfaces within another guest OS. Unless you are building a
-         dedicated device-driver domain, or your master control domain
-         (domain 0), then you almost certainly want to say Y here.
-
-config XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER
+config XEN_NETDEV_PIPELINED_TRANSMITTER
        bool "Pipelined transmitter (DANGEROUS)"
-       depends on XEN_NETDEV_FRONTEND
-       default n
-       help
-         The driver will assume that the backend is pipelining packets for
-         transmission: whenever packets are pending in the remote backend,
-         the driver will not send asynchronous notifications when it queues
-         additional packets for transmission.
-         If the backend is a dumb domain, such as a transparent Ethernet
+       depends on XEN_NETDEV_BACKEND
+       default n
+       help
+         If the net backend is a dumb domain, such as a transparent Ethernet
          bridge with no local IP interface, it is safe to say Y here to get
          slightly lower network overhead.
          If the backend has a local IP interface; or may be doing smart things
@@ -128,6 +83,47 @@
          are unsure; or if you experience network hangs when this option is
          enabled; then you must say N here.
 
+config XEN_TPMDEV_FRONTEND
+        bool "TPM-device frontend driver"
+        default n
+       select TCG_TPM
+       select TCG_XEN
+        help
+          The TPM-device frontend driver.
+
+config XEN_TPMDEV_BACKEND
+        bool "TPM-device backend driver"
+        default n
+        help
+          The TPM-device backend driver
+
+config XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
+        bool "TPM backend closes upon vTPM failure"
+        depends on XEN_TPMDEV_BACKEND
+        default n
+        help
+          The TPM backend closes the channel if the vTPM in userspace indicates
+          a failure. The corresponding domain's channel will be closed.
+          Say Y if you want this feature.
+
+config XEN_BLKDEV_FRONTEND
+       tristate "Block-device frontend driver"
+       default y
+       help
+         The block-device frontend driver allows the kernel to access block
+         devices mounted within another guest OS. Unless you are building a
+         dedicated device-driver domain, or your master control domain
+         (domain 0), then you almost certainly want to say Y here.
+
+config XEN_NETDEV_FRONTEND
+       tristate "Network-device frontend driver"
+       default y
+       help
+         The network-device frontend driver allows the kernel to access
+         network interfaces within another guest OS. Unless you are building a
+         dedicated device-driver domain, or your master control domain
+         (domain 0), then you almost certainly want to say Y here.
+
 config XEN_BLKDEV_TAP
        bool "Block device tap driver"
        default n
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32       Fri Dec 
 2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32       Fri Dec 
 2 18:52:25 2005
@@ -15,11 +15,11 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_TPMDEV_FRONTEND is not set
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
 CONFIG_XEN_SCRUB_PAGES=y
@@ -35,7 +35,6 @@
 # CONFIG_CLEAN_COMPILE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
@@ -125,8 +124,6 @@
 # CONFIG_HPET_TIMER is not set
 # CONFIG_HPET_EMULATE_RTC is not set
 # CONFIG_SMP is not set
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
 # CONFIG_X86_REBOOTFIXUPS is not set
 CONFIG_MICROCODE=y
 CONFIG_X86_CPUID=y
@@ -141,7 +138,6 @@
 # CONFIG_HIGHMEM64G is not set
 CONFIG_HIGHMEM=y
 CONFIG_MTRR=y
-CONFIG_HAVE_DEC_LOCK=y
 # CONFIG_REGPARM is not set
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_X86_IO_APIC=y
@@ -1259,7 +1255,6 @@
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64       Fri Dec 
 2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64       Fri Dec 
 2 18:52:25 2005
@@ -15,11 +15,11 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_TPMDEV_FRONTEND is not set
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
 CONFIG_XEN_SCRUB_PAGES=y
@@ -90,7 +90,6 @@
 CONFIG_X86_GOOD_APIC=y
 # CONFIG_HPET_TIMER is not set
 # CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
 CONFIG_MICROCODE=y
 # CONFIG_X86_CPUID is not set
 CONFIG_SWIOTLB=y
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32       Fri Dec 
 2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32       Fri Dec 
 2 18:52:25 2005
@@ -16,7 +16,6 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
 CONFIG_XEN_SCRUB_PAGES=y
@@ -125,8 +124,6 @@
 CONFIG_SMP_ALTERNATIVES=y
 CONFIG_NR_CPUS=8
 # CONFIG_SCHED_SMT is not set
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
 # CONFIG_X86_REBOOTFIXUPS is not set
 CONFIG_X86_CPUID=y
 
@@ -550,7 +547,6 @@
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Fri Dec 
 2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Fri Dec 
 2 18:52:25 2005
@@ -16,7 +16,6 @@
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
 CONFIG_XEN_SCRUB_PAGES=y
@@ -92,7 +91,6 @@
 CONFIG_SMP=y
 CONFIG_NR_CPUS=8
 # CONFIG_SCHED_SMT is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_MICROCODE is not set
 CONFIG_X86_CPUID=y
 # CONFIG_NUMA is not set
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Fri Dec 
 2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Fri Dec 
 2 18:52:25 2005
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-xen0
-# Sat Oct 15 00:13:28 2005
+# Linux kernel version: 2.6.12.6-xen
+# Mon Nov 28 11:04:51 2005
 #
 CONFIG_XEN=y
 CONFIG_ARCH_XEN=y
@@ -15,11 +15,11 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_TPMDEV_FRONTEND is not set
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
 CONFIG_XEN_SCRUB_PAGES=y
@@ -132,10 +132,8 @@
 CONFIG_SMP_ALTERNATIVES=y
 CONFIG_NR_CPUS=8
 # CONFIG_SCHED_SMT is not set
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
 # CONFIG_X86_REBOOTFIXUPS is not set
-CONFIG_MICROCODE=m
+CONFIG_MICROCODE=y
 CONFIG_X86_CPUID=m
 CONFIG_SWIOTLB=y
 
@@ -434,71 +432,71 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
 #
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
 
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_IDE_SATA is not set
 # CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
 CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
+CONFIG_BLK_DEV_IDEFLOPPY=y
 CONFIG_BLK_DEV_IDESCSI=m
 # CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=m
+CONFIG_IDE_GENERIC=y
 CONFIG_BLK_DEV_CMD640=y
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=m
+CONFIG_BLK_DEV_GENERIC=y
 CONFIG_BLK_DEV_OPTI621=m
-CONFIG_BLK_DEV_RZ1000=m
+CONFIG_BLK_DEV_RZ1000=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_AEC62XX=m
-CONFIG_BLK_DEV_ALI15X3=m
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
-CONFIG_BLK_DEV_AMD74XX=m
-CONFIG_BLK_DEV_ATIIXP=m
-CONFIG_BLK_DEV_CMD64X=m
-CONFIG_BLK_DEV_TRIFLEX=m
-CONFIG_BLK_DEV_CY82C693=m
-CONFIG_BLK_DEV_CS5520=m
-CONFIG_BLK_DEV_CS5530=m
-CONFIG_BLK_DEV_HPT34X=m
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
 # CONFIG_HPT34X_AUTODMA is not set
-CONFIG_BLK_DEV_HPT366=m
+CONFIG_BLK_DEV_HPT366=y
 CONFIG_BLK_DEV_SC1200=m
-CONFIG_BLK_DEV_PIIX=m
+CONFIG_BLK_DEV_PIIX=y
 CONFIG_BLK_DEV_NS87415=m
-CONFIG_BLK_DEV_PDC202XX_OLD=m
+CONFIG_BLK_DEV_PDC202XX_OLD=y
 CONFIG_PDC202XX_BURST=y
-CONFIG_BLK_DEV_PDC202XX_NEW=m
+CONFIG_BLK_DEV_PDC202XX_NEW=y
 CONFIG_PDC202XX_FORCE=y
-CONFIG_BLK_DEV_SVWKS=m
-CONFIG_BLK_DEV_SIIMAGE=m
-CONFIG_BLK_DEV_SIS5513=m
-CONFIG_BLK_DEV_SLC90E66=m
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
 CONFIG_BLK_DEV_TRM290=m
-CONFIG_BLK_DEV_VIA82CXXX=m
+CONFIG_BLK_DEV_VIA82CXXX=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
@@ -654,10 +652,10 @@
 CONFIG_CD_NO_IDESCSI=y
 CONFIG_AZTCD=m
 CONFIG_GSCD=m
-CONFIG_SBPCD=m
+# CONFIG_SBPCD is not set
 CONFIG_MCDX=m
 CONFIG_OPTCD=m
-CONFIG_CM206=m
+# CONFIG_CM206 is not set
 CONFIG_SJCD=m
 CONFIG_ISP16_CDI=m
 CONFIG_CDU31A=m
@@ -1044,7 +1042,7 @@
 CONFIG_MKISS=m
 CONFIG_6PACK=m
 CONFIG_BPQETHER=m
-CONFIG_DMASCC=m
+# CONFIG_DMASCC is not set
 CONFIG_SCC=m
 # CONFIG_SCC_DELAY is not set
 # CONFIG_SCC_TRXECHO is not set
@@ -1204,7 +1202,7 @@
 CONFIG_WINBOND_840=m
 CONFIG_DM9102=m
 CONFIG_PCMCIA_XIRCOM=m
-CONFIG_PCMCIA_XIRTULIP=m
+# CONFIG_PCMCIA_XIRTULIP is not set
 CONFIG_AT1700=m
 CONFIG_DEPCA=m
 CONFIG_HP100=m
@@ -1473,7 +1471,7 @@
 #
 # ISDN feature submodules
 #
-CONFIG_ISDN_DRV_LOOP=m
+# CONFIG_ISDN_DRV_LOOP is not set
 # CONFIG_ISDN_DIVERSION is not set
 
 #
@@ -1554,8 +1552,7 @@
 CONFIG_ISDN_DRV_PCBIT=m
 CONFIG_ISDN_DRV_SC=m
 CONFIG_ISDN_DRV_ACT2000=m
-CONFIG_HYSDN=m
-CONFIG_HYSDN_CAPI=y
+# CONFIG_HYSDN is not set
 
 #
 # CAPI subsystem
@@ -1611,7 +1608,7 @@
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_PSAUX=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
@@ -1632,7 +1629,7 @@
 CONFIG_KEYBOARD_XTKBD=m
 CONFIG_KEYBOARD_NEWTON=m
 CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_SERIAL=m
 CONFIG_MOUSE_INPORT=m
 # CONFIG_MOUSE_ATIXL is not set
@@ -1791,31 +1788,7 @@
 #
 # Ftape, the floppy tape device driver
 #
-CONFIG_FTAPE=m
-CONFIG_ZFTAPE=m
-CONFIG_ZFT_DFLT_BLK_SZ=10240
-
-#
-# The compressor will be built as a module only!
-#
-CONFIG_ZFT_COMPRESSOR=m
-CONFIG_FT_NR_BUFFERS=3
-CONFIG_FT_PROC_FS=y
-CONFIG_FT_NORMAL_DEBUG=y
-# CONFIG_FT_FULL_DEBUG is not set
-# CONFIG_FT_NO_TRACE is not set
-# CONFIG_FT_NO_TRACE_AT_ALL is not set
-
-#
-# Hardware configuration
-#
-CONFIG_FT_STD_FDC=y
-# CONFIG_FT_MACH2 is not set
-# CONFIG_FT_PROBE_FC10 is not set
-# CONFIG_FT_ALT_FDC is not set
-CONFIG_FT_FDC_THR=8
-CONFIG_FT_FDC_MAX_RATE=2000
-CONFIG_FT_ALPHA_CLOCK=0
+# CONFIG_FTAPE is not set
 CONFIG_AGP=m
 CONFIG_AGP_ALI=m
 CONFIG_AGP_ATI=m
@@ -2474,8 +2447,8 @@
 #
 # USB HID Boot Protocol drivers
 #
-CONFIG_USB_KBD=y
-CONFIG_USB_MOUSE=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
 CONFIG_USB_AIPTEK=m
 CONFIG_USB_WACOM=m
 CONFIG_USB_KBTAB=m
@@ -2751,7 +2724,7 @@
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS_XATTR=y
@@ -2976,7 +2949,6 @@
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64        Fri Dec 
 2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64        Fri Dec 
 2 18:52:25 2005
@@ -15,11 +15,11 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_TPMDEV_FRONTEND is not set
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SHADOW_MODE is not set
 CONFIG_XEN_SCRUB_PAGES=y
@@ -95,7 +95,6 @@
 CONFIG_SMP=y
 CONFIG_NR_CPUS=8
 # CONFIG_SCHED_SMT is not set
-# CONFIG_PREEMPT is not set
 CONFIG_MICROCODE=y
 # CONFIG_X86_CPUID is not set
 # CONFIG_NUMA is not set
@@ -2202,7 +2201,7 @@
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
 CONFIG_DEVPTS_FS_SECURITY=y
 CONFIG_TMPFS=y
diff -r eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/arch/xen/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/xen/i386/Kconfig        Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/Kconfig        Fri Dec  2 18:52:25 2005
@@ -415,17 +415,17 @@
          cost of slightly increased overhead in some places. If unsure say
          N here.
 
-config PREEMPT
-       bool "Preemptible Kernel"
-       help
-         This option reduces the latency of the kernel when reacting to
-         real-time or interactive events by allowing a low priority process to
-         be preempted even if it is in kernel mode executing a system call.
-         This allows applications to run more reliably even when the system is
-         under load.
-
-         Say Y here if you are building a kernel for a desktop, embedded
-         or real-time system.  Say N if you are unsure.
+#config PREEMPT
+#      bool "Preemptible Kernel"
+#      help
+#        This option reduces the latency of the kernel when reacting to
+#        real-time or interactive events by allowing a low priority process to
+#        be preempted even if it is in kernel mode executing a system call.
+#        This allows applications to run more reliably even when the system is
+#        under load.
+#
+#        Say Y here if you are building a kernel for a desktop, embedded
+#        or real-time system.  Say N if you are unsure.
 
 config PREEMPT_BKL
        bool "Preempt The Big Kernel Lock"
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile        Fri Dec  2 
18:52:25 2005
@@ -11,7 +11,7 @@
 
 obj-y  := process.o signal.o entry.o traps.o \
                time.o ioport.o ldt.o setup.o \
-               pci-dma.o i386_ksyms.o irq.o quirks.o
+               pci-dma.o i386_ksyms.o irq.o quirks.o fixup.o
 
 c-obj-y        := semaphore.o vm86.o \
                ptrace.o sys_i386.o \
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Fri Dec  2 18:52:25 2005
@@ -81,7 +81,7 @@
 #define evtchn_upcall_pending          /* 0 */
 #define evtchn_upcall_mask             1
 
-#define sizeof_vcpu_shift              4
+#define sizeof_vcpu_shift              6
 
 #ifdef CONFIG_SMP
 #define preempt_disable(reg)   incl TI_preempt_count(reg)
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Fri Dec  2 18:52:25 2005
@@ -1752,7 +1752,7 @@
 #endif
 #endif
        } else {
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+#ifdef CONFIG_XEN_PHYSDEV_ACCESS
                extern const struct consw xennull_con;
                extern int console_use_vt;
 #if defined(CONFIG_VGA_CONSOLE)
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c   Fri Dec  2 18:52:25 2005
@@ -27,8 +27,6 @@
 #include <mach_apic.h>
 #endif
 #include <asm-xen/evtchn.h>
-
-#define xxprint(msg) HYPERVISOR_console_io(CONSOLEIO_write, strlen(msg), msg)
 
 /*
  *     Some notes on x86 processor bugs affecting SMP operation:
@@ -542,9 +540,7 @@
         */
        cpu_clear(smp_processor_id(), cpu_online_map);
        local_irq_disable();
-#if 1
-       xxprint("stop_this_cpu disable_local_APIC\n");
-#else
+#if 0
        disable_local_APIC();
 #endif
        if (cpu_data[smp_processor_id()].hlt_works_ok)
@@ -561,9 +557,7 @@
        smp_call_function(stop_this_cpu, NULL, 1, 0);
 
        local_irq_disable();
-#if 1
-       xxprint("smp_send_stop disable_local_APIC\n");
-#else
+#if 0
        disable_local_APIC();
 #endif
        local_irq_enable();
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c       Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c       Fri Dec  2 
18:52:25 2005
@@ -24,6 +24,7 @@
 #include <asm/io.h>
 #include <asm/pci.h>
 #include <asm/dma.h>
+#include <asm-xen/xen-public/memory.h>
 
 #define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
 
@@ -177,6 +178,8 @@
 void
 swiotlb_init(void)
 {
+       long ram_end;
+
        /* The user can forcibly enable swiotlb. */
        if (swiotlb_force)
                swiotlb = 1;
@@ -186,10 +189,8 @@
          * which we take to mean more than 2GB.
          */
        if (xen_start_info->flags & SIF_INITDOMAIN) {
-               dom0_op_t op;
-               op.cmd = DOM0_PHYSINFO;
-               if ((HYPERVISOR_dom0_op(&op) == 0) &&
-                   (op.u.physinfo.total_pages > 0x7ffff))
+               ram_end = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
+               if (ram_end > 0x7ffff)
                        swiotlb = 1;
        }
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Fri Dec  2 18:52:25 2005
@@ -204,7 +204,8 @@
 void init_cpu_khz(void)
 {
        u64 __cpu_khz = 1000000ULL << 32;
-       struct vcpu_time_info *info = &HYPERVISOR_shared_info->vcpu_time[0];
+       struct vcpu_time_info *info;
+       info = &HYPERVISOR_shared_info->vcpu_info[0].time;
        do_div(__cpu_khz, info->tsc_to_system_mul);
        if ( info->tsc_shift < 0 )
                cpu_khz = __cpu_khz << -info->tsc_shift;
@@ -284,7 +285,7 @@
        struct vcpu_time_info   *src;
        struct shadow_time_info *dst;
 
-       src = &s->vcpu_time[smp_processor_id()];
+       src = &s->vcpu_info[smp_processor_id()].time;
        dst = &per_cpu(shadow_time, smp_processor_id());
 
        do {
@@ -306,7 +307,7 @@
        struct vcpu_time_info   *src;
        struct shadow_time_info *dst;
 
-       src = &HYPERVISOR_shared_info->vcpu_time[cpu]; 
+       src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
        dst = &per_cpu(shadow_time, cpu); 
 
        return (dst->version == src->version);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c     Fri Dec  2 18:52:25 2005
@@ -291,7 +291,7 @@
        int write;
        siginfo_t info;
 
-       address = HYPERVISOR_shared_info->vcpu_data[
+       address = HYPERVISOR_shared_info->vcpu_info[
                smp_processor_id()].arch.cr2;
 
        /* Set the "privileged fault" bit to something sane. */
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Fri Dec  2 18:52:25 2005
@@ -708,7 +708,7 @@
                        panic("pgtable_cache_init(): cannot create pmd cache");
        }
        pgd_cache = kmem_cache_create("pgd",
-#if 0 /* How the heck _this_ works in native linux ??? */
+#ifndef CONFIG_XEN
                                PTRS_PER_PGD*sizeof(pgd_t),
                                PTRS_PER_PGD*sizeof(pgd_t),
 #else
@@ -717,7 +717,7 @@
 #endif
                                0,
                                pgd_ctor,
-                               pgd_dtor);
+                               PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
        if (!pgd_cache)
                panic("pgtable_cache_init(): Cannot create pgd cache");
 }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Fri Dec  2 18:52:25 2005
@@ -27,8 +27,7 @@
 #include <asm-xen/foreign_page.h>
 #include <asm/hypervisor.h>
 
-static void __pgd_pin(pgd_t *pgd);
-static void __pgd_unpin(pgd_t *pgd);
+static void pgd_test_and_unpin(pgd_t *pgd);
 
 void show_mem(void)
 {
@@ -278,75 +277,79 @@
 {
        unsigned long flags;
 
-#ifdef CONFIG_X86_PAE
-       /* Ensure pgd resides below 4GB. */
-       int rc = xen_create_contiguous_region((unsigned long)pgd, 0, 32);
-       BUG_ON(rc);
-#endif
-
-       if (!HAVE_SHARED_KERNEL_PMD)
+       if (PTRS_PER_PMD > 1) {
+               /* Ensure pgd resides below 4GB. */
+               int rc = xen_create_contiguous_region(
+                       (unsigned long)pgd, 0, 32);
+               BUG_ON(rc);
+               if (HAVE_SHARED_KERNEL_PMD)
+                       memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
+                              swapper_pg_dir + USER_PTRS_PER_PGD,
+                              (PTRS_PER_PGD - USER_PTRS_PER_PGD) * 
sizeof(pgd_t));
+       } else {
                spin_lock_irqsave(&pgd_lock, flags);
-
-       memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
-                       swapper_pg_dir + USER_PTRS_PER_PGD,
-                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-
-       if (HAVE_SHARED_KERNEL_PMD)
-               return;
-
-       pgd_list_add(pgd);
-       spin_unlock_irqrestore(&pgd_lock, flags);
-       memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
-}
-
+               memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
+                      swapper_pg_dir + USER_PTRS_PER_PGD,
+                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+               memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
+               pgd_list_add(pgd);
+               spin_unlock_irqrestore(&pgd_lock, flags);
+       }
+}
+
+/* never called when PTRS_PER_PMD > 1 */
 void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
 {
        unsigned long flags; /* can be called from interrupt context */
-
-       BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
-
-       if (HAVE_SHARED_KERNEL_PMD)
-               return;
 
        spin_lock_irqsave(&pgd_lock, flags);
        pgd_list_del(pgd);
        spin_unlock_irqrestore(&pgd_lock, flags);
+
+       pgd_test_and_unpin(pgd);
 }
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-       int i = 0;
+       int i;
        pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
 
-       BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
+       pgd_test_and_unpin(pgd);
 
        if (PTRS_PER_PMD == 1 || !pgd)
                return pgd;
 
-       if (!HAVE_SHARED_KERNEL_PMD) {
-               /* alloc and copy kernel pmd */
-               unsigned long flags;
-               pgd_t *copy_pgd = pgd_offset_k(PAGE_OFFSET);
-               pud_t *copy_pud = pud_offset(copy_pgd, PAGE_OFFSET);
-               pmd_t *copy_pmd = pmd_offset(copy_pud, PAGE_OFFSET);
-               pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-               if (0 == pmd)
-                       goto out_oom;
-
-               spin_lock_irqsave(&pgd_lock, flags);
-               memcpy(pmd, copy_pmd, PAGE_SIZE);
-               spin_unlock_irqrestore(&pgd_lock, flags);
-               make_lowmem_page_readonly(pmd);
-               set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
-       }
-
-       /* alloc user pmds */
        for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
                pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
                if (!pmd)
                        goto out_oom;
                set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
        }
+
+       if (!HAVE_SHARED_KERNEL_PMD) {
+               unsigned long flags;
+
+               for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
+                       pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
+                       if (!pmd)
+                               goto out_oom;
+                       set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
+               }
+
+               spin_lock_irqsave(&pgd_lock, flags);
+               for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
+                       unsigned long v = (unsigned long)i << PGDIR_SHIFT;
+                       pgd_t *kpgd = pgd_offset_k(v);
+                       pud_t *kpud = pud_offset(kpgd, v);
+                       pmd_t *kpmd = pmd_offset(kpud, v);
+                       pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
+                       memcpy(pmd, kpmd, PAGE_SIZE);
+                       make_lowmem_page_readonly(pmd);
+               }
+               pgd_list_add(pgd);
+               spin_unlock_irqrestore(&pgd_lock, flags);
+       }
+
        return pgd;
 
 out_oom:
@@ -360,21 +363,25 @@
 {
        int i;
 
-       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
-               __pgd_unpin(pgd);
+       pgd_test_and_unpin(pgd);
 
        /* in the PAE case user pgd entries are overwritten before usage */
        if (PTRS_PER_PMD > 1) {
                for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
                        pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-                       make_lowmem_page_writable(pmd);
                        kmem_cache_free(pmd_cache, pmd);
                }
                if (!HAVE_SHARED_KERNEL_PMD) {
-                       pmd_t *pmd = (void 
*)__va(pgd_val(pgd[USER_PTRS_PER_PGD])-1);
-                       make_lowmem_page_writable(pmd);
-                       memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
-                       kmem_cache_free(pmd_cache, pmd);
+                       unsigned long flags;
+                       spin_lock_irqsave(&pgd_lock, flags);
+                       pgd_list_del(pgd);
+                       spin_unlock_irqrestore(&pgd_lock, flags);
+                       for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
+                               pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
+                               make_lowmem_page_writable(pmd);
+                               memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
+                               kmem_cache_free(pmd_cache, pmd);
+                       }
                }
        }
        /* in the non-PAE case, free_pgtables() clears user pgd entries */
@@ -382,7 +389,6 @@
 }
 
 #ifndef CONFIG_XEN_SHADOW_MODE
-asmlinkage int xprintk(const char *fmt, ...);
 void make_lowmem_page_readonly(void *va)
 {
        pte_t *pte = virt_to_ptep(va);
@@ -513,6 +519,12 @@
        clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
 }
 
+static void pgd_test_and_unpin(pgd_t *pgd)
+{
+       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
+               __pgd_unpin(pgd);
+}
+
 void mm_pin(struct mm_struct *mm)
 {
        spin_lock(&mm->page_table_lock);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/kernel/Makefile     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/Makefile     Fri Dec  2 18:52:25 2005
@@ -11,8 +11,8 @@
 
 extra-y += vmlinux.lds
 
-obj-y   := evtchn.o fixup.o reboot.o gnttab.o devmem.o
+obj-y   := evtchn.o reboot.o gnttab.o
 
 obj-$(CONFIG_PROC_FS) += xen_proc.o
 obj-$(CONFIG_NET)     += skbuff.o
-obj-$(CONFIG_SMP)     += smp.o smpboot.o
+obj-$(CONFIG_SMP)     += smpboot.o
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Fri Dec  2 18:52:25 2005
@@ -154,7 +154,7 @@
        unsigned int   l1i, l2i, port;
        int            irq, cpu = smp_processor_id();
        shared_info_t *s = HYPERVISOR_shared_info;
-       vcpu_info_t   *vcpu_info = &s->vcpu_data[cpu];
+       vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
 
        vcpu_info->evtchn_upcall_pending = 0;
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c     Fri Dec  2 18:52:25 2005
@@ -229,20 +229,29 @@
 unsigned long
 gnttab_end_foreign_transfer_ref(grant_ref_t ref)
 {
-       unsigned long frame = 0;
+       unsigned long frame;
        u16           flags;
 
-       flags = shared[ref].flags;
-
        /*
-        * If a transfer is committed then wait for the frame address to
-        * appear. Otherwise invalidate the grant entry against future use.
-        */
-       if (likely(flags != GTF_accept_transfer) ||
-           (synch_cmpxchg(&shared[ref].flags, flags, 0) !=
-            GTF_accept_transfer))
-               while (unlikely((frame = shared[ref].frame) == 0))
-                       cpu_relax();
+         * If a transfer is not even yet started, try to reclaim the grant
+         * reference and return failure (== 0).
+         */
+       while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
+               if ( synch_cmpxchg(&shared[ref].flags, flags, 0) == flags )
+                       return 0;
+               cpu_relax();
+       }
+
+       /* If a transfer is in progress then wait until it is completed. */
+       while (!(flags & GTF_transfer_completed)) {
+               flags = shared[ref].flags;
+               cpu_relax();
+       }
+
+       /* Read the frame number /after/ reading completion status. */
+       rmb();
+       frame = shared[ref].frame;
+       BUG_ON(frame == 0);
 
        return frame;
 }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Fri Dec  2 18:52:25 2005
@@ -189,17 +189,16 @@
 #endif
 
        /* 
-       ** Only resume xenbus /after/ we've prepared our VCPUs; otherwise
-       ** the VCPU hotplug callback can race with our vcpu_prepare
-       */
+        * Only resume xenbus /after/ we've prepared our VCPUs; otherwise
+        * the VCPU hotplug callback can race with our vcpu_prepare
+        */
        xenbus_resume();
-
 
 #ifdef CONFIG_SMP
  out_reenable_cpus:
        for_each_cpu_mask(i, prev_online_cpus) {
                j = cpu_up(i);
-               if (j != 0) {
+               if ((j != 0) && !cpu_online(i)) {
                        printk(KERN_CRIT "Failed to bring cpu "
                               "%d back up (%d).\n",
                               i, j);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c    Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c    Fri Dec  2 18:52:25 2005
@@ -420,6 +420,12 @@
 {
 }
 
+int setup_profiling_timer(unsigned int multiplier)
+{
+       /* Dummy function. */
+       return 0;
+}
+
 /*
  * Local variables:
  *  c-file-style: "linux"
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig      Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig      Fri Dec  2 18:52:25 2005
@@ -224,21 +224,21 @@
 
          If you don't know what to do here, say N.
 
-config PREEMPT
-       bool "Preemptible Kernel"
-       ---help---
-         This option reduces the latency of the kernel when reacting to
-         real-time or interactive events by allowing a low priority process to
-         be preempted even if it is in kernel mode executing a system call.
-         This allows applications to run more reliably even when the system is
-         under load. On contrary it may also break your drivers and add
-         priority inheritance problems to your system. Don't select it if
-         you rely on a stable system or have slightly obscure hardware.
-         It's also not very well tested on x86-64 currently.
-         You have been warned.
-
-         Say Y here if you are feeling brave and building a kernel for a
-         desktop, embedded or real-time system.  Say N if you are unsure.
+#config PREEMPT
+#      bool "Preemptible Kernel"
+#      ---help---
+#        This option reduces the latency of the kernel when reacting to
+#        real-time or interactive events by allowing a low priority process to
+#        be preempted even if it is in kernel mode executing a system call.
+#        This allows applications to run more reliably even when the system is
+#        under load. On contrary it may also break your drivers and add
+#        priority inheritance problems to your system. Don't select it if
+#        you rely on a stable system or have slightly obscure hardware.
+#        It's also not very well tested on x86-64 currently.
+#        You have been warned.
+#
+#        Say Y here if you are feeling brave and building a kernel for a
+#        desktop, embedded or real-time system.  Say N if you are unsure.
 
 config SCHED_SMT
        bool "SMT (Hyperthreading) scheduler support"
@@ -288,10 +288,10 @@
 # actually 64 maximum, but you need to fix the APIC code first
 # to use clustered mode or whatever your big iron needs
 config NR_CPUS
-       int "Maximum number of CPUs (2-8)"
-       range 2 8
+       int "Maximum number of CPUs (2-255)"
+       range 2 255
        depends on SMP
-       default "8"
+       default "16"
        help
          This allows you to specify the maximum number of CPUs which this
          kernel will support.  The maximum supported value is 32 and the
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile        Fri Dec  2 
18:52:25 2005
@@ -20,6 +20,12 @@
 
 $(obj)/syscall32.o: $(src)/syscall32.c \
        $(foreach F,int80 sysenter syscall,$(obj)/vsyscall-$F.so)
+
+# syscall32.c currently contains inline asm which has .incbin directives.
+# This defeats ccache's signature checks, and also breaks distcc.
+# Make sure neither ccache nor distcc compiles this file.
+#
+$(obj)/syscall32.o: override CC := env CCACHE_DISABLE=1 DISTCC_HOSTS=localhost 
$(CC)
 
 # Teach kbuild about targets
 targets := $(foreach F,int80 sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c        Fri Dec  2 
18:52:25 2005
@@ -586,7 +586,7 @@
        free_bootmem(__pa(map), PAGE_SIZE);
 
        if (!found) {
-               HYPERVISOR_memory_op(XENMEM_maximum_ram_page, &gapstart);
+               gapstart = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
                gapstart = (gapstart << PAGE_SHIFT) + 1024*1024;
                printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit 
address range\n"
                       KERN_ERR "PCI: Unassigned devices with 32bit resource 
registers may break!\n");
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Fri Dec  2 18:52:25 2005
@@ -30,8 +30,6 @@
 #include <asm/apicdef.h>
 #ifdef CONFIG_XEN
 #include <asm-xen/evtchn.h>
-
-#define xxprint(msg) HYPERVISOR_console_io(CONSOLEIO_write, strlen(msg), msg)
 
 #else
 /*
@@ -379,8 +377,6 @@
        local_irq_disable();
 #ifndef CONFIG_XEN
        disable_local_APIC();
-#else
-       xxprint("stop_this_cpu disable_local_APIC\n");
 #endif
        local_irq_enable(); 
 }
@@ -409,9 +405,7 @@
                spin_unlock(&call_lock);
 
        local_irq_disable();
-#ifdef CONFIG_XEN
-       xxprint("stop_this_cpu disable_local_APIC\n");
-#else
+#ifndef CONFIG_XEN
        disable_local_APIC();
 #endif
        local_irq_enable();
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S   Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S   Fri Dec  2 
18:52:25 2005
@@ -5,7 +5,7 @@
 #define evtchn_upcall_pending          0
 #define evtchn_upcall_mask             1
 
-#define sizeof_vcpu_shift              5
+#define sizeof_vcpu_shift              6
 
 #ifdef CONFIG_SMP
 //#define preempt_disable(reg) incl threadinfo_preempt_count(reg)
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c   Fri Dec  2 18:52:25 2005
@@ -344,7 +344,7 @@
 #endif
 
        /* get the address */
-       address = HYPERVISOR_shared_info->vcpu_data[
+       address = HYPERVISOR_shared_info->vcpu_info[
                smp_processor_id()].arch.cr2;
 
        if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Fri Dec  2 18:52:25 2005
@@ -17,15 +17,6 @@
          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"
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Fri Dec  2 18:52:25 2005
@@ -22,7 +22,7 @@
 
 #include <asm/uaccess.h>
 #include <linux/list.h>
-#include <linux/tpmfe.h>
+#include <asm-xen/tpmfe.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include "tpm.h"
diff -r eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Fri Dec  2 18:52:25 2005
@@ -2,6 +2,7 @@
 obj-y  += net_driver_util.o
 obj-y  += util.o
 
+obj-y  += char/
 obj-y  += console/
 obj-y  += evtchn/
 obj-y  += balloon/
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Fri Dec  2 
18:52:25 2005
@@ -88,10 +88,10 @@
  * handle returned must be used to unmap the frame. This is needed to
  * drop the ref count on the frame.
  */
-static u16 pending_grant_handles[MMAP_PAGES];
+static grant_handle_t pending_grant_handles[MMAP_PAGES];
 #define pending_handle(_idx, _i) \
     (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
-#define BLKBACK_INVALID_HANDLE (0xFFFF)
+#define BLKBACK_INVALID_HANDLE (~0)
 
 #ifdef CONFIG_XEN_BLKDEV_TAP_BE
 /*
@@ -114,7 +114,7 @@
 {
        struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        unsigned int i, invcount = 0;
-       u16 handle;
+       grant_handle_t handle;
        int ret;
 
        for (i = 0; i < nr_pages; i++) {
@@ -335,7 +335,6 @@
 {
        extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
        int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
-       unsigned long fas = 0;
        int i, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
        pending_req_t *pending_req;
        struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
@@ -362,16 +361,17 @@
        preq.nr_sects      = 0;
 
        for (i = 0; i < nseg; i++) {
-               fas         = req->frame_and_sects[i];
-               seg[i].nsec = blkif_last_sect(fas) - blkif_first_sect(fas) + 1;
-
-               if (seg[i].nsec <= 0)
+               seg[i].nsec = req->seg[i].last_sect -
+                       req->seg[i].first_sect + 1;
+
+               if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
+                   (seg[i].nsec <= 0))
                        goto bad_descriptor;
                preq.nr_sects += seg[i].nsec;
 
                map[i].host_addr = MMAP_VADDR(pending_idx, i);
                map[i].dom = blkif->domid;
-               map[i].ref = blkif_gref_from_fas(fas);
+               map[i].ref = req->seg[i].gref;
                map[i].flags = GNTMAP_host_map;
                if ( operation == WRITE )
                        map[i].flags |= GNTMAP_readonly;
@@ -381,7 +381,7 @@
        BUG_ON(ret);
 
        for (i = 0; i < nseg; i++) {
-               if (likely(map[i].handle >= 0)) {
+               if (likely(map[i].status == 0)) {
                        pending_handle(pending_idx, i) = map[i].handle;
 #ifdef __ia64__
                        MMAP_VADDR(pending_idx,i) = gnttab_map_vaddr(map[i]);
@@ -390,9 +390,8 @@
                                pending_idx, i)) >> PAGE_SHIFT,
                                FOREIGN_FRAME(map[i].dev_bus_addr>>PAGE_SHIFT));
 #endif
-                       fas        = req->frame_and_sects[i];
-                       seg[i].buf = map[i].dev_bus_addr | 
-                               (blkif_first_sect(fas) << 9);
+                       seg[i].buf = map[i].dev_bus_addr |
+                               (req->seg[i].first_sect << 9);
                } else {
                        errors++;
                }
@@ -482,6 +481,7 @@
        blkif_response_t *resp;
        unsigned long     flags;
        blkif_back_ring_t *blk_ring = &blkif->blk_ring;
+       int notify;
 
        /* Place on the response ring for the relevant domain. */ 
        spin_lock_irqsave(&blkif->blk_ring_lock, flags);
@@ -489,13 +489,27 @@
        resp->id        = id;
        resp->operation = op;
        resp->status    = st;
-       wmb(); /* Ensure other side can see the response fields. */
        blk_ring->rsp_prod_pvt++;
-       RING_PUSH_RESPONSES(blk_ring);
+       RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
        spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
 
-       /* Kick the relevant domain. */
-       notify_remote_via_irq(blkif->irq);
+       /*
+         * Tail check for pending requests. Allows frontend to avoid
+         * notifications if requests are already in flight (lower overheads
+         * and promotes batching).
+         */
+       mb();
+       if (!__on_blkdev_list(blkif)) {
+               int more_to_do;
+               RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
+               if (more_to_do) {
+                       add_to_blkdev_list_tail(blkif);
+                       maybe_trigger_blkio_schedule();
+               }
+       }
+
+       if (notify)
+               notify_remote_via_irq(blkif->irq);
 }
 
 void blkif_deschedule(blkif_t *blkif)
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Fri Dec  2 18:52:25 2005
@@ -38,6 +38,8 @@
        struct block_device *bdev;
 }; 
 
+struct backend_info; 
+
 typedef struct blkif_st {
        /* Unique identifier for this interface. */
        domid_t           domid;
@@ -48,8 +50,10 @@
        /* Comms information. */
        blkif_back_ring_t blk_ring;
        struct vm_struct *blk_ring_area;
-       /* VBDs attached to this interface. */
+       /* The VBD attached to this interface. */
        struct vbd        vbd;
+       /* Back pointer to the backend_info. */
+       struct backend_info *be; 
        /* Private fields. */
        enum { DISCONNECTED, CONNECTED } status;
 #ifdef CONFIG_XEN_BLKDEV_TAP_BE
@@ -62,8 +66,8 @@
 
        struct work_struct free_work;
 
-       u16         shmem_handle;
-       grant_ref_t shmem_ref;
+       grant_handle_t shmem_handle;
+       grant_ref_t    shmem_ref;
 } blkif_t;
 
 blkif_t *alloc_blkif(domid_t domid);
@@ -78,8 +82,8 @@
        } while (0)
 
 /* Create a vbd. */
-int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, u32 pdevice,
-              int readonly);
+int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, unsigned major,
+              unsigned minor, int readonly);
 void vbd_free(struct vbd *vbd);
 
 unsigned long vbd_size(struct vbd *vbd);
@@ -103,6 +107,8 @@
 
 irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 
+void update_blkif_status(blkif_t *blkif); 
+
 #endif /* __BLKIF__BACKEND__COMMON_H__ */
 
 /*
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Fri Dec  2 
18:52:25 2005
@@ -43,9 +43,9 @@
        unlock_vm_area(blkif->blk_ring_area);
        BUG_ON(ret);
 
-       if (op.handle < 0) {
+       if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
-               return op.handle;
+               return op.status;
        }
 
        blkif->shmem_ref = shared_page;
@@ -107,12 +107,13 @@
        blkif->evtchn = op.u.bind_interdomain.local_port;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
-       SHARED_RING_INIT(sring);
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
        blkif->irq = bind_evtchn_to_irqhandler(
                blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
-       blkif->status = CONNECTED;
+
+       /* We're potentially connected now */
+       update_blkif_status(blkif); 
 
        return 0;
 }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Fri Dec  2 18:52:25 2005
@@ -9,10 +9,6 @@
 #include "common.h"
 #include <asm-xen/xenbus.h>
 
-static inline dev_t vbd_map_devnum(u32 cookie)
-{
-       return MKDEV(BLKIF_MAJOR(cookie), BLKIF_MINOR(cookie));
-}
 #define vbd_sz(_v)   ((_v)->bdev->bd_part ?                            \
        (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
 #define bdev_put(_b) blkdev_put(_b)
@@ -32,8 +28,8 @@
        return bdev_hardsect_size(vbd->bdev);
 }
 
-int vbd_create(blkif_t *blkif, blkif_vdev_t handle,
-              u32 pdevice, int readonly)
+int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major,
+              unsigned minor, int readonly)
 {
        struct vbd *vbd;
 
@@ -42,10 +38,10 @@
        vbd->readonly = readonly;
        vbd->type     = 0;
 
-       vbd->pdevice  = pdevice;
+       vbd->pdevice  = MKDEV(major, minor);
 
        vbd->bdev = open_by_devnum(
-               vbd_map_devnum(vbd->pdevice),
+               vbd->pdevice,
                vbd->readonly ? FMODE_READ : FMODE_WRITE);
        if (IS_ERR(vbd->bdev)) {
                DPRINTK("vbd_creat: device %08x doesn't exist.\n",
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Dec  2 18:52:25 2005
@@ -37,8 +37,9 @@
        blkif_t *blkif;
        struct xenbus_watch backend_watch;
 
-       long int pdev;
-       long int readonly;
+       unsigned major;
+       unsigned minor;
+       char *mode;
 };
 
 
@@ -49,6 +50,35 @@
                            unsigned int);
 
 
+void update_blkif_status(blkif_t *blkif)
+{ 
+       if(blkif->irq && blkif->vbd.bdev) {
+               blkif->status = CONNECTED; 
+               (void)blkif_be_int(0, blkif, NULL); 
+       }
+       maybe_connect(blkif->be); 
+}
+
+
+static ssize_t show_physical_device(struct device *_dev, char *buf)
+{
+       struct xenbus_device *dev = to_xenbus_device(_dev);
+       struct backend_info *be = dev->data;
+       return sprintf(buf, "%x:%x\n", be->major, be->minor);
+}
+DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH,
+           show_physical_device, NULL);
+
+
+static ssize_t show_mode(struct device *_dev, char *buf)
+{
+       struct xenbus_device *dev = to_xenbus_device(_dev);
+       struct backend_info *be = dev->data;
+       return sprintf(buf, "%s\n", be->mode);
+}
+DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL);
+
+
 static int blkback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->data;
@@ -61,9 +91,14 @@
                be->backend_watch.node = NULL;
        }
        if (be->blkif) {
+               be->blkif->status = DISCONNECTED; 
                blkif_put(be->blkif);
                be->blkif = NULL;
        }
+
+       device_remove_file(&dev->dev, &dev_attr_physical_device);
+       device_remove_file(&dev->dev, &dev_attr_mode);
+
        kfree(be);
        dev->data = NULL;
        return 0;
@@ -73,7 +108,7 @@
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
  * structures, and watch the store waiting for the hotplug scripts to tell us
- * the device's physical-device.  Switch to InitWait.
+ * the device's physical major and minor numbers.  Switch to InitWait.
  */
 static int blkback_probe(struct xenbus_device *dev,
                         const struct xenbus_device_id *id)
@@ -99,6 +134,9 @@
                goto fail;
        }
 
+       /* setup back pointer */
+       be->blkif->be = be; 
+
        err = xenbus_watch_path2(dev, dev->nodename, "physical-device",
                                 &be->backend_watch, backend_changed);
        if (err)
@@ -119,66 +157,74 @@
 
 /**
  * Callback received when the hotplug scripts have placed the physical-device
- * node.  Read it and the read-only node, and create a vbd.  If the frontend
- * is ready, connect.
+ * node.  Read it and the mode node, and create a vbd.  If the frontend is
+ * ready, connect.
  */
 static void backend_changed(struct xenbus_watch *watch,
                            const char **vec, unsigned int len)
 {
        int err;
-       char *p;
-       long pdev;
+       unsigned major;
+       unsigned minor;
        struct backend_info *be
                = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
        DPRINTK("");
 
-       err = xenbus_scanf(NULL, dev->nodename,
-                          "physical-device", "%li", &pdev);
+       err = xenbus_scanf(NULL, dev->nodename, "physical-device", "%x:%x",
+                          &major, &minor);
        if (XENBUS_EXIST_ERR(err)) {
                /* Since this watch will fire once immediately after it is
                   registered, we expect this.  Ignore it, and wait for the
                   hotplug scripts. */
                return;
        }
-       if (err != 1) {
+       if (err != 2) {
                xenbus_dev_fatal(dev, err, "reading physical-device");
                return;
        }
-       if (be->pdev && be->pdev != pdev) {
+
+       if (be->major && be->minor &&
+           (be->major != major || be->minor != minor)) {
                printk(KERN_WARNING
-                      "blkback: changing physical-device (from %ld to %ld) "
-                      "not supported.\n", be->pdev, pdev);
+                      "blkback: changing physical device (from %x:%x to "
+                      "%x:%x) not supported.\n", be->major, be->minor,
+                      major, minor);
                return;
        }
 
-       /* If there's a read-only node, we're read only. */
-       p = xenbus_read(NULL, dev->nodename, "read-only", NULL);
-       if (!IS_ERR(p)) {
-               be->readonly = 1;
-               kfree(p);
-       }
-
-       if (be->pdev == 0L) {
+       be->mode = xenbus_read(NULL, dev->nodename, "mode", NULL);
+       if (IS_ERR(be->mode)) {
+               err = PTR_ERR(be->mode);
+               be->mode = NULL;
+               xenbus_dev_fatal(dev, err, "reading mode");
+               return;
+       }
+
+       if (be->major == 0 && be->minor == 0) {
                /* Front end dir is a number, which is used as the handle. */
 
-               long handle;
-
-               p = strrchr(dev->otherend, '/') + 1;
-               handle = simple_strtoul(p, NULL, 0);
-
-               be->pdev = pdev;
-
-               err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
+               char *p = strrchr(dev->otherend, '/') + 1;
+               long handle = simple_strtoul(p, NULL, 0);
+
+               be->major = major;
+               be->minor = minor;
+
+               err = vbd_create(be->blkif, handle, major, minor,
+                                (NULL == strchr(be->mode, 'w')));
                if (err) {
-                       be->pdev = 0L;
-                       xenbus_dev_fatal(dev, err,
-                                        "creating vbd structure");
+                       be->major = 0;
+                       be->minor = 0;
+                       xenbus_dev_fatal(dev, err, "creating vbd structure");
                        return;
                }
 
-               maybe_connect(be);
+               device_create_file(&dev->dev, &dev_attr_physical_device);
+               device_create_file(&dev->dev, &dev_attr_mode);
+
+               /* We're potentially connected now */
+               update_blkif_status(be->blkif); 
        }
 }
 
@@ -204,7 +250,7 @@
                if (err) {
                        return;
                }
-               maybe_connect(be);
+               update_blkif_status(be->blkif); 
                break;
 
        case XenbusStateClosing:
@@ -230,9 +276,9 @@
 
 static void maybe_connect(struct backend_info *be)
 {
-       if (be->pdev != 0L && be->blkif->status == CONNECTED) {
+       if ((be->major != 0 || be->minor != 0) &&
+           be->blkif->status == CONNECTED)
                connect(be);
-       }
 }
 
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Fri Dec  2 
18:52:25 2005
@@ -32,7 +32,6 @@
  * IN THE SOFTWARE.
  */
 
-
 #if 1
 #define ASSERT(p)                                                         \
        if (!(p)) { printk("Assertion '%s' failed, line %d, file %s", #p , \
@@ -40,7 +39,6 @@
 #else
 #define ASSERT(_p)
 #endif
-
 
 #include <linux/version.h>
 #include "block.h"
@@ -54,15 +52,13 @@
 #include <asm-xen/gnttab.h>
 #include <asm/hypervisor.h>
 
-
 #define BLKIF_STATE_DISCONNECTED 0
 #define BLKIF_STATE_CONNECTED    1
 #define BLKIF_STATE_SUSPENDED    2
 
 #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
-    (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
+    (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE)
 #define GRANT_INVALID_REF      0
-
 
 static void connect(struct blkfront_info *);
 static void blkfront_closing(struct xenbus_device *);
@@ -117,6 +113,8 @@
                info->shadow[i].req.id = i+1;
        info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
 
+       info->users = 0;
+
        /* Front end dir is a number, which is used as the id. */
        info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
        dev->data = info;
@@ -265,6 +263,7 @@
                            XenbusState backend_state)
 {
        struct blkfront_info *info = dev->data;
+       struct block_device *bd;
 
        DPRINTK("blkfront:backend_changed.\n");
 
@@ -281,7 +280,18 @@
                break;
 
        case XenbusStateClosing:
-               blkfront_closing(dev);
+               bd = bdget(info->dev);
+               if (bd == NULL)
+                       xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
+
+               down(&bd->bd_sem);
+               if (info->users > 0)
+                       xenbus_dev_error(dev, -EBUSY,
+                                        "Device in use; refusing to close");
+               else
+                       blkfront_closing(dev);
+               up(&bd->bd_sem);
+               bdput(bd);
                break;
        }
 }
@@ -290,6 +300,10 @@
 /* ** Connection ** */
 
 
+/* 
+** Invoked when the backend is finally 'ready' (and has told produced 
+** the details about the physical device - #sectors, size, etc). 
+*/
 static void connect(struct blkfront_info *info)
 {
        unsigned long sectors, sector_size;
@@ -297,7 +311,7 @@
        int err;
 
         if( (info->connected == BLKIF_STATE_CONNECTED) || 
-           (info->connected == BLKIF_STATE_SUSPENDED) ) 
+           (info->connected == BLKIF_STATE_SUSPENDED) )
                return;
 
        DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
@@ -313,20 +327,19 @@
                                 info->xbdev->otherend);
                return;
        }
-       
-        info->connected = BLKIF_STATE_CONNECTED;
+
         xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
-       
-       err = xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected);
-       if (err)
-               return;
-       
+
+       (void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected); 
+
        /* Kick pending requests. */
        spin_lock_irq(&blkif_io_lock);
+       info->connected = BLKIF_STATE_CONNECTED;
        kick_pending_request_queues(info);
        spin_unlock_irq(&blkif_io_lock);
-}
-
+
+       add_disk(info->gd);
+}
 
 /**
  * Handle the change of state of the backend to Closing.  We must delete our
@@ -384,8 +397,12 @@
 
 static inline void flush_requests(struct blkfront_info *info)
 {
-       RING_PUSH_REQUESTS(&info->ring);
-       notify_remote_via_irq(info->irq);
+       int notify;
+
+       RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->ring, notify);
+
+       if (notify)
+               notify_remote_via_irq(info->irq);
 }
 
 static void kick_pending_request_queues(struct blkfront_info *info)
@@ -414,12 +431,26 @@
 
 int blkif_open(struct inode *inode, struct file *filep)
 {
+       struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
+       info->users++;
        return 0;
 }
 
 
 int blkif_release(struct inode *inode, struct file *filep)
 {
+       struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
+       info->users--;
+       if (info->users == 0) {
+               /* Check whether we have been instructed to close.  We will
+                  have ignored this request initially, as the device was
+                  still mounted. */
+               struct xenbus_device * dev = info->xbdev;
+               XenbusState state = xenbus_read_driver_state(dev->otherend);
+
+               if (state == XenbusStateClosing)
+                       blkfront_closing(dev);
+       }
        return 0;
 }
 
@@ -441,7 +472,7 @@
        case CDROMMULTISESSION:
                DPRINTK("FIXME: support multisession CDs later\n");
                for (i = 0; i < sizeof(struct cdrom_multisession); i++)
-                       if (put_user(0, (char *)(argument + i)))
+                       if (put_user(0, (char __user *)(argument + i)))
                                return -EFAULT;
                return 0;
 
@@ -523,8 +554,11 @@
                        info->shadow[id].frame[ring_req->nr_segments] =
                                mfn_to_pfn(buffer_mfn);
 
-                       ring_req->frame_and_sects[ring_req->nr_segments] =
-                               blkif_fas_from_gref(ref, fsect, lsect);
+                       ring_req->seg[ring_req->nr_segments] =
+                               (struct blkif_request_segment) {
+                                       .gref       = ref,
+                                       .first_sect = fsect, 
+                                       .last_sect  = lsect };
 
                        ring_req->nr_segments++;
                }
@@ -556,7 +590,6 @@
 
        while ((req = elv_next_request(rq)) != NULL) {
                info = req->rq_disk->private_data;
-
                if (!blk_fs_request(req)) {
                        end_request(req, 0);
                        continue;
@@ -604,6 +637,7 @@
                return IRQ_HANDLED;
        }
 
+ again:
        rp = info->ring.sring->rsp_prod;
        rmb(); /* Ensure we see queued responses up to 'rp'. */
 
@@ -639,6 +673,15 @@
 
        info->ring.rsp_cons = i;
 
+       if (i != info->ring.req_prod_pvt) {
+               int more_to_do;
+               RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
+               if (more_to_do)
+                       goto again;
+       } else {
+               info->ring.sring->rsp_event = i + 1;
+       }
+
        kick_pending_request_queues(info);
 
        spin_unlock_irqrestore(&blkif_io_lock, flags);
@@ -671,8 +714,7 @@
 {
        int i;
        for (i = 0; i < s->req.nr_segments; i++)
-               gnttab_end_foreign_access(
-                       blkif_gref_from_fas(s->req.frame_and_sects[i]), 0, 0UL);
+               gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL);
 }
 
 static void blkif_recover(struct blkfront_info *info)
@@ -712,7 +754,7 @@
                /* Rewrite any grant references invalidated by susp/resume. */
                for (j = 0; j < req->nr_segments; j++)
                        gnttab_grant_foreign_access_ref(
-                               blkif_gref_from_fas(req->frame_and_sects[j]),
+                               req->seg[j].gref,
                                info->xbdev->otherend_id,
                                pfn_to_mfn(info->shadow[req->id].frame[j]),
                                rq_data_dir(
@@ -725,14 +767,20 @@
 
        kfree(copy);
 
-       /* info->ring->req_prod will be set when we flush_requests().*/
-       wmb();
-
-       /* Kicks things back into life. */
+       (void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected); 
+       
+       /* Now safe for us to use the shared ring */
+       spin_lock_irq(&blkif_io_lock);
+        info->connected = BLKIF_STATE_CONNECTED;
+       spin_unlock_irq(&blkif_io_lock);
+
+       /* Send off requeued requests */
        flush_requests(info);
 
-       /* Now safe to let other people use the interface. */
-       info->connected = BLKIF_STATE_CONNECTED;
+       /* Kick any other new requests queued since we resumed */
+       spin_lock_irq(&blkif_io_lock);
+       kick_pending_request_queues(info);
+       spin_unlock_irq(&blkif_io_lock);
 }
 
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Fri Dec  2 18:52:25 2005
@@ -127,6 +127,12 @@
        struct gnttab_free_callback callback;
        struct blk_shadow shadow[BLK_RING_SIZE];
        unsigned long shadow_free;
+
+       /**
+        * The number of people holding this device open.  We won't allow a
+        * hot-unplug unless this is 0.
+        */
+       int users;
 };
 
 extern spinlock_t blkif_io_lock;
@@ -140,6 +146,9 @@
 extern void do_blkif_request (request_queue_t *rq); 
 
 /* Virtual block-device subsystem. */
+/* Note that xlvbd_add doesn't call add_disk for you: you're expected
+   to call add_disk on info->gd once the disk is properly connected
+   up. */
 int xlvbd_add(blkif_sector_t capacity, int device,
              u16 vdisk_info, u16 sector_size, struct blkfront_info *info);
 void xlvbd_del(struct blkfront_info *info);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Fri Dec  2 18:52:25 2005
@@ -32,6 +32,9 @@
 #include "block.h"
 #include <linux/blkdev.h>
 #include <linux/list.h>
+
+#define BLKIF_MAJOR(dev) ((dev)>>8)
+#define BLKIF_MINOR(dev) ((dev) & 0xff)
 
 /*
  * For convenience we distinguish between ide, scsi and 'other' (i.e.,
@@ -258,7 +261,6 @@
        if (vdisk_info & VDISK_CDROM)
                gd->flags |= GENHD_FL_CD;
 
-       add_disk(gd);
        info->gd = gd;
 
        return 0;
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Fri Dec  2 18:52:25 2005
@@ -177,8 +177,8 @@
  */
 struct grant_handle_pair
 {
-       u16  kernel;
-       u16  user;
+       grant_handle_t kernel;
+       grant_handle_t user;
 };
 static struct grant_handle_pair pending_grant_handles[MMAP_PAGES];
 #define pending_handle(_idx, _i) \
@@ -375,7 +375,7 @@
 static unsigned int blktap_poll(struct file *file, poll_table *wait)
 {
        poll_wait(file, &blktap_wait, wait);
-       if (RING_HAS_UNPUSHED_REQUESTS(&blktap_ufe_ring)) {
+       if (blktap_ufe_ring.req_prod_pvt != blktap_ufe_ring.sring->req_prod) {
                flush_tlb_all();
                RING_PUSH_REQUESTS(&blktap_ufe_ring);
                return POLLIN | POLLRDNORM;
@@ -713,7 +713,7 @@
                /* Map the remote page to kernel. */
                map[op].host_addr = kvaddr;
                map[op].dom   = blkif->domid;
-               map[op].ref   = blkif_gref_from_fas(req->frame_and_sects[i]);
+               map[op].ref   = req->seg[i].gref;
                map[op].flags = GNTMAP_host_map;
                /* This needs a bit more thought in terms of interposition: 
                 * If we want to be able to modify pages during write using 
@@ -733,7 +733,7 @@
 
                map[op].host_addr = ptep;
                map[op].dom       = blkif->domid;
-               map[op].ref       = 
blkif_gref_from_fas(req->frame_and_sects[i]);
+               map[op].ref       = req->seg[i].gref;
                map[op].flags     = GNTMAP_host_map | GNTMAP_application_map
                        | GNTMAP_contains_pte;
                /* Above interposition comment applies here as well. */
@@ -755,17 +755,17 @@
                uvaddr = MMAP_VADDR(user_vstart, pending_idx, i/2);
                kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i/2);
 
-               if (unlikely(map[i].handle < 0)) {
+               if (unlikely(map[i].status)) {
                        DPRINTK("Error on kernel grant mapping (%d)\n",
-                               map[i].handle);
-                       ret = map[i].handle;
+                               map[i].status);
+                       ret = map[i].status;
                        cancel = 1;
                }
 
-               if (unlikely(map[i+1].handle < 0)) {
+               if (unlikely(map[i+1].status)) {
                        DPRINTK("Error on user grant mapping (%d)\n",
-                               map[i+1].handle);
-                       ret = map[i+1].handle;
+                               map[i+1].status);
+                       ret = map[i+1].status;
                        cancel = 1;
                }
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Fri Dec  2 18:52:25 2005
@@ -64,7 +64,7 @@
 
        struct work_struct free_work;
 
-       u16              shmem_handle;
+       grant_handle_t   shmem_handle;
        grant_ref_t      shmem_ref;
 } blkif_t;
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Fri Dec  2 
18:52:25 2005
@@ -43,9 +43,9 @@
        unlock_vm_area(blkif->blk_ring_area);
        BUG_ON(ret);
 
-       if (op.handle < 0) {
+       if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
-               return op.handle;
+               return op.status;
        }
 
        blkif->shmem_ref    = shared_page;
@@ -97,7 +97,6 @@
        blkif->evtchn = op.u.bind_interdomain.local_port;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
-       SHARED_RING_INIT(sring);
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
        blkif->irq = bind_evtchn_to_irqhandler(
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c        Fri Dec  2 
18:52:25 2005
@@ -55,7 +55,6 @@
 #include <asm-xen/evtchn.h>
 #include <asm-xen/xencons.h>
 
-#include "xencons_ring.h"
 /*
  * Modes:
  *  'xencons=off'  [XC_OFF]:     Console is disabled.
@@ -135,19 +134,21 @@
 static void kcons_write(
        struct console *c, const char *s, unsigned int count)
 {
-       int           i;
-       unsigned long flags;
-
-       spin_lock_irqsave(&xencons_lock, flags);
-    
-       for (i = 0; i < count; i++) {
-               if ((wp - wc) >= (wbuf_size - 1))
-                       break;
-               if ((wbuf[WBUF_MASK(wp++)] = s[i]) == '\n')
-                       wbuf[WBUF_MASK(wp++)] = '\r';
-       }
-
-       __xencons_tx_flush();
+       int           i = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&xencons_lock, flags);
+
+       while (i < count) {
+               for (; i < count; i++) {
+                       if ((wp - wc) >= (wbuf_size - 1))
+                               break;
+                       if ((wbuf[WBUF_MASK(wp++)] = s[i]) == '\n')
+                               wbuf[WBUF_MASK(wp++)] = '\r';
+               }
+
+               __xencons_tx_flush();
+       }
 
        spin_unlock_irqrestore(&xencons_lock, flags);
 }
@@ -247,7 +248,6 @@
        if (xen_start_info->flags & SIF_INITDOMAIN)
                return;
 
-
        /* Spin until console data is flushed through to the daemon. */
        while (wc != wp) {
                int sent = 0;
@@ -271,8 +271,7 @@
 static int xencons_priv_irq;
 static char x_char;
 
-/* Non-privileged receive callback. */
-static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
 {
        int           i;
        unsigned long flags;
@@ -311,10 +310,9 @@
        spin_unlock_irqrestore(&xencons_lock, flags);
 }
 
-/* Privileged and non-privileged transmit worker. */
 static void __xencons_tx_flush(void)
 {
-       int sz, work_done = 0;
+       int sent, sz, work_done = 0;
 
        if (xen_start_info->flags & SIF_INITDOMAIN) {
                if (x_char) {
@@ -340,20 +338,18 @@
                }
 
                while (wc != wp) {
-                       int sent;
                        sz = wp - wc;
                        if (sz > (wbuf_size - WBUF_MASK(wc)))
                                sz = wbuf_size - WBUF_MASK(wc);
                        sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
-                       if (sent > 0) {
-                               wc += sent;
-                               work_done = 1;
-                       }
+                       if (sent == 0)
+                               break;
+                       wc += sent;
+                       work_done = 1;
                }
        }
 
-       if (work_done && (xencons_tty != NULL))
-       {
+       if (work_done && (xencons_tty != NULL)) {
                wake_up_interruptible(&xencons_tty->write_wait);
                if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                    (xencons_tty->ldisc.write_wakeup != NULL))
@@ -361,31 +357,26 @@
        }
 }
 
+void xencons_tx(void)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&xencons_lock, flags);
+       __xencons_tx_flush();
+       spin_unlock_irqrestore(&xencons_lock, flags);
+}
+
 /* Privileged receive callback and transmit kicker. */
 static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
 {
-       static char   rbuf[16];
-       int           i, l;
-       unsigned long flags;
-
-       spin_lock_irqsave(&xencons_lock, flags);
-
-       if (xencons_tty != NULL)
-       {
-               /* Receive work. */
-               while ((l = HYPERVISOR_console_io(
-                       CONSOLEIO_read, 16, rbuf)) > 0)
-                       for (i = 0; i < l; i++)
-                               tty_insert_flip_char(xencons_tty, rbuf[i], 0);
-               if (xencons_tty->flip.count != 0)
-                       tty_flip_buffer_push(xencons_tty);
-       }
-
-       /* Transmit work. */
-       __xencons_tx_flush();
-
-       spin_unlock_irqrestore(&xencons_lock, flags);
+       static char rbuf[16];
+       int         l;
+
+       while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0)
+               xencons_rx(rbuf, l, regs);
+
+       xencons_tx();
 
        return IRQ_HANDLED;
 }
@@ -579,7 +570,7 @@
        .wait_until_sent = xencons_wait_until_sent,
 };
 
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+#ifdef CONFIG_XEN_PHYSDEV_ACCESS
 static const char *xennullcon_startup(void)
 {
        return NULL;
@@ -664,7 +655,8 @@
        if ((rc = tty_register_driver(DRV(xencons_driver))) != 0) {
                printk("WARNING: Failed to register Xen virtual "
                       "console driver as '%s%d'\n",
-                      DRV(xencons_driver)->name, 
DRV(xencons_driver)->name_base);
+                      DRV(xencons_driver)->name,
+                      DRV(xencons_driver)->name_base);
                put_tty_driver(xencons_driver);
                xencons_driver = NULL;
                return rc;
@@ -681,8 +673,6 @@
                        "console",
                        NULL);
                BUG_ON(xencons_priv_irq < 0);
-       } else {
-               xencons_ring_register_receiver(xencons_rx);
        }
 
        printk("Xen virtual console successfully installed as %s%d\n",
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Fri Dec  2 
18:52:25 2005
@@ -15,15 +15,14 @@
 
 #include <asm/hypervisor.h>
 #include <asm-xen/evtchn.h>
+#include <asm-xen/xencons.h>
 #include <linux/wait.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/err.h>
-#include "xencons_ring.h"
 #include <asm-xen/xen-public/io/console.h>
 
 static int xencons_irq;
-static xencons_receiver_func *xencons_receiver;
 
 static inline struct xencons_interface *xencons_interface(void)
 {
@@ -69,10 +68,8 @@
        BUG_ON((prod - cons) > sizeof(intf->in));
 
        while (cons != prod) {
-               if (xencons_receiver != NULL)
-                       xencons_receiver(
-                               intf->in + MASK_XENCONS_IDX(cons++, intf->in),
-                               1, regs);
+               xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
+               cons++;
        }
 
        mb();
@@ -80,12 +77,9 @@
 
        notify_daemon();
 
+       xencons_tx();
+
        return IRQ_HANDLED;
-}
-
-void xencons_ring_register_receiver(xencons_receiver_func *f)
-{
-       xencons_receiver = f;
 }
 
 int xencons_ring_init(void)
@@ -103,7 +97,7 @@
                xen_start_info->console_evtchn,
                handle_input, 0, "xencons", NULL);
        if (err <= 0) {
-               xprintk("XEN console request irq failed %i\n", err);
+               printk(KERN_ERR "XEN console request irq failed %i\n", err);
                return err;
        }
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Fri Dec  2 18:52:25 2005
@@ -50,9 +50,9 @@
 
 struct per_user_data {
        /* Notification ring, accessed via /dev/xen/evtchn. */
-#define EVTCHN_RING_SIZE     2048  /* 2048 16-bit entries */
+#define EVTCHN_RING_SIZE     (PAGE_SIZE / sizeof(evtchn_port_t))
 #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
-       u16 *ring;
+       evtchn_port_t *ring;
        unsigned int ring_cons, ring_prod, ring_overflow;
 
        /* Processes wait on this queue when ring is empty. */
@@ -75,7 +75,7 @@
 
        if ((u = port_user[port]) != NULL) {
                if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
-                       u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port;
+                       u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
                        if (u->ring_cons == u->ring_prod++) {
                                wake_up_interruptible(&u->evtchn_wait);
                                kill_fasync(&u->evtchn_async_queue,
@@ -89,57 +89,45 @@
        spin_unlock(&port_user_lock);
 }
 
-static ssize_t evtchn_read(struct file *file, char *buf,
+static ssize_t evtchn_read(struct file *file, char __user *buf,
                            size_t count, loff_t *ppos)
 {
        int rc;
        unsigned int c, p, bytes1 = 0, bytes2 = 0;
-       DECLARE_WAITQUEUE(wait, current);
        struct per_user_data *u = file->private_data;
 
-       add_wait_queue(&u->evtchn_wait, &wait);
-
-       count &= ~1; /* even number of bytes */
-
-       if (count == 0) {
-               rc = 0;
-               goto out;
-       }
+       /* Whole number of ports. */
+       count &= ~(sizeof(evtchn_port_t)-1);
+
+       if (count == 0)
+               return 0;
 
        if (count > PAGE_SIZE)
                count = PAGE_SIZE;
 
        for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
+               if (u->ring_overflow)
+                       return -EFBIG;
 
                if ((c = u->ring_cons) != (p = u->ring_prod))
                        break;
 
-               if (u->ring_overflow) {
-                       rc = -EFBIG;
-                       goto out;
-               }
-
-               if (file->f_flags & O_NONBLOCK) {
-                       rc = -EAGAIN;
-                       goto out;
-               }
-
-               if (signal_pending(current)) {
-                       rc = -ERESTARTSYS;
-                       goto out;
-               }
-
-               schedule();
+               if (file->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+
+               rc = wait_event_interruptible(
+                       u->evtchn_wait, u->ring_cons != u->ring_prod);
+               if (rc)
+                       return rc;
        }
 
        /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
        if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
                bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
-                       sizeof(u16);
-               bytes2 = EVTCHN_RING_MASK(p) * sizeof(u16);
+                       sizeof(evtchn_port_t);
+               bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
        } else {
-               bytes1 = (p - c) * sizeof(u16);
+               bytes1 = (p - c) * sizeof(evtchn_port_t);
                bytes2 = 0;
        }
 
@@ -153,32 +141,26 @@
 
        if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
            ((bytes2 != 0) &&
-            copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) {
-               rc = -EFAULT;
-               goto out;
-       }
-
-       u->ring_cons += (bytes1 + bytes2) / sizeof(u16);
-
-       rc = bytes1 + bytes2;
-
- out:
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&u->evtchn_wait, &wait);
-       return rc;
-}
-
-static ssize_t evtchn_write(struct file *file, const char *buf,
+            copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
+               return -EFAULT;
+
+       u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
+
+       return bytes1 + bytes2;
+}
+
+static ssize_t evtchn_write(struct file *file, const char __user *buf,
                             size_t count, loff_t *ppos)
 {
        int  rc, i;
-       u16 *kbuf = (u16 *)__get_free_page(GFP_KERNEL);
+       evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
        struct per_user_data *u = file->private_data;
 
        if (kbuf == NULL)
                return -ENOMEM;
 
-       count &= ~1; /* even number of bytes */
+       /* Whole number of ports. */
+       count &= ~(sizeof(evtchn_port_t)-1);
 
        if (count == 0) {
                rc = 0;
@@ -194,7 +176,7 @@
        }
 
        spin_lock_irq(&port_user_lock);
-       for (i = 0; i < (count/2); i++)
+       for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
                if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
                        unmask_evtchn(kbuf[i]);
        spin_unlock_irq(&port_user_lock);
@@ -220,6 +202,7 @@
 {
        int rc;
        struct per_user_data *u = file->private_data;
+       void __user *uarg = (void __user *) arg;
        evtchn_op_t op = { 0 };
 
        switch (cmd) {
@@ -227,7 +210,7 @@
                struct ioctl_evtchn_bind_virq bind;
 
                rc = -EFAULT;
-               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+               if (copy_from_user(&bind, uarg, sizeof(bind)))
                        break;
 
                op.cmd = EVTCHNOP_bind_virq;
@@ -246,7 +229,7 @@
                struct ioctl_evtchn_bind_interdomain bind;
 
                rc = -EFAULT;
-               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+               if (copy_from_user(&bind, uarg, sizeof(bind)))
                        break;
 
                op.cmd = EVTCHNOP_bind_interdomain;
@@ -265,7 +248,7 @@
                struct ioctl_evtchn_bind_unbound_port bind;
 
                rc = -EFAULT;
-               if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
+               if (copy_from_user(&bind, uarg, sizeof(bind)))
                        break;
 
                op.cmd = EVTCHNOP_alloc_unbound;
@@ -285,7 +268,7 @@
                int ret;
 
                rc = -EFAULT;
-               if (copy_from_user(&unbind, (void *)arg, sizeof(unbind)))
+               if (copy_from_user(&unbind, uarg, sizeof(unbind)))
                        break;
 
                rc = -EINVAL;
@@ -318,7 +301,7 @@
                struct ioctl_evtchn_notify notify;
 
                rc = -EFAULT;
-               if (copy_from_user(&notify, (void *)arg, sizeof(notify)))
+               if (copy_from_user(&notify, uarg, sizeof(notify)))
                        break;
 
                if (notify.port >= NR_EVENT_CHANNELS) {
@@ -378,8 +361,8 @@
        memset(u, 0, sizeof(*u));
        init_waitqueue_head(&u->evtchn_wait);
 
-       if ((u->ring = (u16 *)__get_free_page(GFP_KERNEL)) == NULL)
-       {
+       u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+       if (u->ring == NULL) {
                kfree(u);
                return -ENOMEM;
        }
@@ -399,8 +382,7 @@
 
        free_page((unsigned long)u->ring);
 
-       for (i = 0; i < NR_EVENT_CHANNELS; i++)
-       {
+       for (i = 0; i < NR_EVENT_CHANNELS; i++) {
                int ret;
                if (port_user[i] != u)
                        continue;
@@ -446,10 +428,9 @@
        spin_lock_init(&port_user_lock);
        memset(port_user, 0, sizeof(port_user));
 
-       /* (DEVFS) create '/dev/misc/evtchn'. */
+       /* Create '/dev/misc/evtchn'. */
        err = misc_register(&evtchn_miscdev);
-       if (err != 0)
-       {
+       if (err != 0) {
                printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
                return err;
        }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Dec  2 18:52:25 2005
@@ -45,24 +45,20 @@
        u8               fe_dev_addr[6];
 
        /* Physical parameters of the comms window. */
-       u16              tx_shmem_handle;
+       grant_handle_t   tx_shmem_handle;
        grant_ref_t      tx_shmem_ref; 
-       u16              rx_shmem_handle;
+       grant_handle_t   rx_shmem_handle;
        grant_ref_t      rx_shmem_ref; 
        unsigned int     evtchn;
        unsigned int     irq;
 
        /* The shared rings and indexes. */
-       netif_tx_interface_t *tx;
-       netif_rx_interface_t *rx;
+       netif_tx_back_ring_t tx;
+       netif_rx_back_ring_t rx;
        struct vm_struct *comms_area;
 
-       /* Private indexes into shared ring. */
-       NETIF_RING_IDX rx_req_cons;
-       NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
-       NETIF_RING_IDX rx_resp_prod_copy;
-       NETIF_RING_IDX tx_req_cons;
-       NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */
+       /* Allow netif_be_start_xmit() to peek ahead in the rx request ring. */
+       RING_IDX rx_req_cons_peek;
 
        /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
        unsigned long   credit_bytes;
@@ -80,6 +76,9 @@
 
        struct work_struct free_work;
 } netif_t;
+
+#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
+#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
 
 void netif_creditlimit(netif_t *netif);
 int  netif_disconnect(netif_t *netif);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Dec  2 
18:52:25 2005
@@ -127,9 +127,9 @@
        unlock_vm_area(netif->comms_area);
        BUG_ON(ret);
 
-       if (op.handle < 0) { 
+       if (op.status) { 
                DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
-               return op.handle;
+               return op.status;
        }
 
        netif->tx_shmem_ref    = tx_ring_ref;
@@ -145,9 +145,9 @@
        unlock_vm_area(netif->comms_area);
        BUG_ON(ret);
 
-       if (op.handle < 0) { 
+       if (op.status) {
                DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
-               return op.handle;
+               return op.status;
        }
 
        netif->rx_shmem_ref    = rx_ring_ref;
@@ -184,6 +184,8 @@
              unsigned long rx_ring_ref, unsigned int evtchn)
 {
        int err;
+       netif_tx_sring_t *txs;
+       netif_rx_sring_t *rxs;
        evtchn_op_t op = {
                .cmd = EVTCHNOP_bind_interdomain,
                .u.bind_interdomain.remote_dom = netif->domid,
@@ -216,10 +218,15 @@
                netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
        disable_irq(netif->irq);
 
-       netif->tx = (netif_tx_interface_t *)netif->comms_area->addr;
-       netif->rx = (netif_rx_interface_t *)
+       txs = (netif_tx_sring_t *)netif->comms_area->addr;
+       BACK_RING_INIT(&netif->tx, txs, PAGE_SIZE);
+
+       rxs = (netif_rx_sring_t *)
                ((char *)netif->comms_area->addr + PAGE_SIZE);
-       netif->tx->resp_prod = netif->rx->resp_prod = 0;
+       BACK_RING_INIT(&netif->rx, rxs, PAGE_SIZE);
+
+       netif->rx_req_cons_peek = 0;
+
        netif_get(netif);
        wmb(); /* Other CPUs see new state before interface is started. */
 
@@ -246,7 +253,7 @@
 
        unregister_netdev(netif->dev);
 
-       if (netif->tx) {
+       if (netif->tx.sring) {
                unmap_frontend_pages(netif);
                free_vm_area(netif->comms_area);
        }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Dec  2 
18:52:25 2005
@@ -25,7 +25,7 @@
                              s8       st,
                              u16      offset,
                              u16      size,
-                             u16      csum_valid);
+                             u16      flags);
 
 static void net_tx_action(unsigned long unused);
 static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
@@ -38,14 +38,11 @@
 #define MAX_PENDING_REQS 256
 
 static struct sk_buff_head rx_queue;
-static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1];
-static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
+static multicall_entry_t rx_mcl[NET_RX_RING_SIZE*2+1];
+static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
 
 static gnttab_transfer_t grant_rx_op[MAX_PENDING_REQS];
 static unsigned char rx_notify[NR_IRQS];
-
-/* Don't currently gate addition of an interface to the tx scheduling list. */
-#define tx_work_exists(_if) (1)
 
 static unsigned long mmap_vstart;
 #define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
@@ -68,7 +65,7 @@
 
 static struct sk_buff_head tx_queue;
 
-static u16 grant_tx_ref[MAX_PENDING_REQS];
+static grant_handle_t grant_tx_handle[MAX_PENDING_REQS];
 static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS];
 static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS];
 
@@ -99,29 +96,6 @@
        return mfn;
 }
 
-#if 0
-static void free_mfn(unsigned long mfn)
-{
-       unsigned long flags;
-       struct xen_memory_reservation reservation = {
-               .extent_start = &mfn,
-               .nr_extents   = 1,
-               .extent_order = 0,
-               .domid        = DOMID_SELF
-       };
-       spin_lock_irqsave(&mfn_lock, flags);
-       if ( alloc_index != MAX_MFN_ALLOC )
-               mfn_list[alloc_index++] = mfn;
-       else {
-               int ret;
-               ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-                                           &reservation);
-               BUG_ON(ret != 1);
-       }
-       spin_unlock_irqrestore(&mfn_lock, flags);
-}
-#endif
-
 static inline void maybe_schedule_tx_action(void)
 {
        smp_mb();
@@ -149,8 +123,9 @@
 
        /* Drop the packet if the target domain has no receive buffers. */
        if (!netif->active || 
-           (netif->rx_req_cons == netif->rx->req_prod) ||
-           ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE))
+           (netif->rx_req_cons_peek == netif->rx.sring->req_prod) ||
+           ((netif->rx_req_cons_peek - netif->rx.rsp_prod_pvt) ==
+            NET_RX_RING_SIZE))
                goto drop;
 
        /*
@@ -177,7 +152,7 @@
                skb = nskb;
        }
 
-       netif->rx_req_cons++;
+       netif->rx_req_cons_peek++;
        netif_get(netif);
 
        skb_queue_tail(&rx_queue, skb);
@@ -221,7 +196,7 @@
        unsigned long vdata, old_mfn, new_mfn;
        struct sk_buff_head rxq;
        struct sk_buff *skb;
-       u16 notify_list[NETIF_RX_RING_SIZE];
+       u16 notify_list[NET_RX_RING_SIZE];
        int notify_nr = 0;
        int ret;
 
@@ -256,9 +231,9 @@
 
                gop->mfn = old_mfn;
                gop->domid = netif->domid;
-               gop->ref = netif->rx->ring[
-                       MASK_NETIF_RX_IDX(netif->rx_resp_prod_copy)].req.gref;
-               netif->rx_resp_prod_copy++;
+               gop->ref = RING_GET_REQUEST(
+                       &netif->rx, netif->rx.req_cons)->gref;
+               netif->rx.req_cons++;
                gop++;
 
                mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
@@ -287,28 +262,19 @@
        ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
        BUG_ON(ret != 0);
 
+       ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 
+                                       gop - grant_rx_op);
+       BUG_ON(ret != 0);
+
        mcl = rx_mcl;
-       if( HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 
-                                     gop - grant_rx_op)) { 
-               /*
-                * The other side has given us a bad grant ref, or has no 
-                * headroom, or has gone away. Unfortunately the current grant
-                * table code doesn't inform us which is the case, so not much
-                * we can do. 
-                */
-               DPRINTK("net_rx: transfer to DOM%u failed; dropping (up to) "
-                       "%d packets.\n",
-                       grant_rx_op[0].domid, gop - grant_rx_op); 
-       }
        gop = grant_rx_op;
-
        while ((skb = __skb_dequeue(&rxq)) != NULL) {
                netif   = netdev_priv(skb->dev);
                size    = skb->tail - skb->data;
 
                /* Rederive the machine addresses. */
-               new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
-               old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
+               new_mfn = mcl->args[1] >> PAGE_SHIFT;
+               old_mfn = gop->mfn;
                atomic_set(&(skb_shinfo(skb)->dataref), 1);
                skb_shinfo(skb)->nr_frags = 0;
                skb_shinfo(skb)->frag_list = NULL;
@@ -317,22 +283,26 @@
                netif->stats.tx_packets++;
 
                /* The update_va_mapping() must not fail. */
-               BUG_ON(mcl[0].result != 0);
+               BUG_ON(mcl->result != 0);
 
                /* Check the reassignment error code. */
                status = NETIF_RSP_OKAY;
-               if(gop->status != 0) { 
+               if (gop->status != 0) { 
                        DPRINTK("Bad status %d from grant transfer to DOM%u\n",
                                gop->status, netif->domid);
-                       /* XXX SMH: should free 'old_mfn' here */
+                       /*
+                         * Page no longer belongs to us unless GNTST_bad_page,
+                         * but that should be a fatal error anyway.
+                         */
+                       BUG_ON(gop->status == GNTST_bad_page);
                        status = NETIF_RSP_ERROR; 
                }
                irq = netif->irq;
-               id = netif->rx->ring[
-                       MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
+               id = RING_GET_REQUEST(&netif->rx, netif->rx.rsp_prod_pvt)->id;
                if (make_rx_response(netif, id, status,
                                     (unsigned long)skb->data & ~PAGE_MASK,
-                                    size, skb->proto_csum_valid) &&
+                                    size, skb->proto_csum_valid ?
+                                    NETRXF_csum_valid : 0) &&
                    (rx_notify[irq] == 0)) {
                        rx_notify[irq] = 1;
                        notify_list[notify_nr++] = irq;
@@ -399,10 +369,25 @@
        spin_unlock_irq(&net_schedule_list_lock);
 }
 
+/*
+ * Note on CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER:
+ * If this driver is pipelining transmit requests then we can be very
+ * aggressive in avoiding new-packet notifications -- frontend only needs to
+ * send a notification if there are no outstanding unreceived responses.
+ * If we may be buffer transmit buffers for any reason then we must be rather
+ * more conservative and treat this as the final check for pending work.
+ */
 void netif_schedule_work(netif_t *netif)
 {
-       if ((netif->tx_req_cons != netif->tx->req_prod) &&
-           ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE)) {
+       int more_to_do;
+
+#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER
+       more_to_do = RING_HAS_UNCONSUMED_REQUESTS(&netif->tx);
+#else
+       RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do);
+#endif
+
+       if (more_to_do) {
                add_to_net_schedule_list_tail(netif);
                maybe_schedule_tx_action();
        }
@@ -440,7 +425,7 @@
                pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
                gop->host_addr    = MMAP_VADDR(pending_idx);
                gop->dev_bus_addr = 0;
-               gop->handle       = grant_tx_ref[pending_idx];
+               gop->handle       = grant_tx_handle[pending_idx];
                gop++;
        }
        ret = HYPERVISOR_grant_table_op(
@@ -457,19 +442,6 @@
         
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
 
-               /*
-                * Scheduling checks must happen after the above response is
-                * posted. This avoids a possible race with a guest OS on
-                * another CPU if that guest is testing against 'resp_prod'
-                * when deciding whether to notify us when it queues additional
-                 * packets.
-                */
-               mb();
-               if ((netif->tx_req_cons != netif->tx->req_prod) &&
-                   ((netif->tx_req_cons-netif->tx_resp_prod) !=
-                    NETIF_TX_RING_SIZE))
-                       add_to_net_schedule_list_tail(netif);
-        
                netif_put(netif);
        }
 }
@@ -482,10 +454,10 @@
        netif_t *netif;
        netif_tx_request_t txreq;
        u16 pending_idx;
-       NETIF_RING_IDX i;
+       RING_IDX i;
        gnttab_map_grant_ref_t *mop;
        unsigned int data_len;
-       int ret;
+       int ret, work_to_do;
 
        if (dealloc_cons != dealloc_prod)
                net_tx_action_dealloc();
@@ -499,17 +471,15 @@
                netif_get(netif);
                remove_from_net_schedule_list(netif);
 
-               /* Work to do? */
-               i = netif->tx_req_cons;
-               if ((i == netif->tx->req_prod) ||
-                   ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE)) {
+               RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, work_to_do);
+               if (!work_to_do) {
                        netif_put(netif);
                        continue;
                }
 
+               i = netif->tx.req_cons;
                rmb(); /* Ensure that we see the request before we copy it. */
-               memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req, 
-                      sizeof(txreq));
+               memcpy(&txreq, RING_GET_REQUEST(&netif->tx, i), sizeof(txreq));
                /* Credit-based scheduling. */
                if (txreq.size > netif->remaining_credit) {
                        unsigned long now = jiffies;
@@ -543,12 +513,7 @@
                }
                netif->remaining_credit -= txreq.size;
 
-               /*
-                * Why the barrier? It ensures that the frontend sees updated
-                * req_cons before we check for more work to schedule.
-                */
-               netif->tx->req_cons = ++netif->tx_req_cons;
-               mb();
+               netif->tx.req_cons++;
 
                netif_schedule_work(netif);
 
@@ -620,7 +585,7 @@
                       sizeof(txreq));
 
                /* Check the remap error code. */
-               if (unlikely(mop->handle < 0)) {
+               if (unlikely(mop->status)) {
                        printk(KERN_ALERT "#### netback grant fails\n");
                        make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
                        netif_put(netif);
@@ -633,7 +598,7 @@
                set_phys_to_machine(
                        __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
                        FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
-               grant_tx_ref[pending_idx] = mop->handle;
+               grant_tx_handle[pending_idx] = mop->handle;
 
                data_len = (txreq.size > PKT_PROT_LEN) ?
                        PKT_PROT_LEN : txreq.size;
@@ -668,7 +633,7 @@
                  */
                skb->ip_summed        = CHECKSUM_UNNECESSARY;
                skb->proto_csum_valid = 1;
-               skb->proto_csum_blank = txreq.csum_blank;
+               skb->proto_csum_blank = !!(txreq.flags & NETTXF_csum_blank);
 
                netif->stats.rx_bytes += txreq.size;
                netif->stats.rx_packets++;
@@ -705,10 +670,8 @@
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
 {
        netif_t *netif = dev_id;
-       if (tx_work_exists(netif)) {
-               add_to_net_schedule_list_tail(netif);
-               maybe_schedule_tx_action();
-       }
+       add_to_net_schedule_list_tail(netif);
+       maybe_schedule_tx_action();
        return IRQ_HANDLED;
 }
 
@@ -716,18 +679,27 @@
                              u16      id,
                              s8       st)
 {
-       NETIF_RING_IDX i = netif->tx_resp_prod;
+       RING_IDX i = netif->tx.rsp_prod_pvt;
        netif_tx_response_t *resp;
-
-       resp = &netif->tx->ring[MASK_NETIF_TX_IDX(i)].resp;
+       int notify;
+
+       resp = RING_GET_RESPONSE(&netif->tx, i);
        resp->id     = id;
        resp->status = st;
-       wmb();
-       netif->tx->resp_prod = netif->tx_resp_prod = ++i;
-
-       mb(); /* Update producer before checking event threshold. */
-       if (i == netif->tx->event)
+
+       netif->tx.rsp_prod_pvt = ++i;
+       RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify);
+       if (notify)
                notify_remote_via_irq(netif->irq);
+
+#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER
+       if (i == netif->tx.req_cons) {
+               int more_to_do;
+               RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do);
+               if (more_to_do)
+                       add_to_net_schedule_list_tail(netif);
+       }
+#endif
 }
 
 static int make_rx_response(netif_t *netif, 
@@ -735,23 +707,24 @@
                             s8       st,
                             u16      offset,
                             u16      size,
-                            u16      csum_valid)
-{
-       NETIF_RING_IDX i = netif->rx_resp_prod;
+                            u16      flags)
+{
+       RING_IDX i = netif->rx.rsp_prod_pvt;
        netif_rx_response_t *resp;
-
-       resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
+       int notify;
+
+       resp = RING_GET_RESPONSE(&netif->rx, i);
        resp->offset     = offset;
-       resp->csum_valid = csum_valid;
+       resp->flags      = flags;
        resp->id         = id;
        resp->status     = (s16)size;
        if (st < 0)
                resp->status = (s16)st;
-       wmb();
-       netif->rx->resp_prod = netif->rx_resp_prod = ++i;
-
-       mb(); /* Update producer before checking event threshold. */
-       return (i == netif->rx->event);
+
+       netif->rx.rsp_prod_pvt = ++i;
+       RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, notify);
+
+       return notify;
 }
 
 static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
@@ -767,16 +740,16 @@
                netif = list_entry(ent, netif_t, list);
                printk(KERN_ALERT " %d: private(rx_req_cons=%08x "
                       "rx_resp_prod=%08x\n",
-                      i, netif->rx_req_cons, netif->rx_resp_prod);
+                      i, netif->rx.req_cons, netif->rx.rsp_prod_pvt);
                printk(KERN_ALERT "   tx_req_cons=%08x tx_resp_prod=%08x)\n",
-                      netif->tx_req_cons, netif->tx_resp_prod);
+                      netif->tx.req_cons, netif->tx.rsp_prod_pvt);
                printk(KERN_ALERT "   shared(rx_req_prod=%08x "
                       "rx_resp_prod=%08x\n",
-                      netif->rx->req_prod, netif->rx->resp_prod);
+                      netif->rx.sring->req_prod, netif->rx.sring->rsp_prod);
                printk(KERN_ALERT "   rx_event=%08x tx_req_prod=%08x\n",
-                      netif->rx->event, netif->tx->req_prod);
+                      netif->rx.sring->rsp_event, netif->tx.sring->req_prod);
                printk(KERN_ALERT "   tx_resp_prod=%08x, tx_event=%08x)\n",
-                      netif->tx->resp_prod, netif->tx->event);
+                      netif->tx.sring->rsp_prod, netif->tx.sring->rsp_event);
                i++;
        }
 
@@ -792,7 +765,7 @@
        struct page *page;
 
        /* We can increase reservation by this much in net_rx_action(). */
-       balloon_update_driver_allowance(NETIF_RX_RING_SIZE);
+       balloon_update_driver_allowance(NET_RX_RING_SIZE);
 
        skb_queue_head_init(&rx_queue);
        skb_queue_head_init(&tx_queue);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Dec  2 18:52:25 2005
@@ -216,13 +216,14 @@
                break;
 
        case XenbusStateClosed:
-               device_unregister(&be->dev->dev);
+               kobject_hotplug(&dev->dev.kobj, KOBJ_OFFLINE);
+               device_unregister(&dev->dev);
                break;
 
        case XenbusStateUnknown:
        case XenbusStateInitWait:
        default:
-               xenbus_dev_fatal(be->dev, -EINVAL, "saw state %d at frontend",
+               xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
                                 frontend_state);
                break;
        }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Dec  2 
18:52:25 2005
@@ -61,6 +61,9 @@
 
 #define GRANT_INVALID_REF      0
 
+#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
+#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
+
 #ifndef __GFP_NOWARN
 #define __GFP_NOWARN 0
 #endif
@@ -76,22 +79,9 @@
 /* Allow headroom on each rx pkt for Ethernet header, alignment padding, ... */
 #define RX_HEADROOM 200
 
-/*
- * If the backend driver is pipelining transmit requests then we can be very
- * aggressive in avoiding new-packet notifications -- only need to send a
- * notification if there are no outstanding unreceived responses.
- * If the backend may be buffering our transmit buffers for any reason then we
- * are rather more conservative.
- */
-#ifdef CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER
-#define TX_TEST_IDX resp_prod /* aggressive: any outstanding responses? */
-#else
-#define TX_TEST_IDX req_cons  /* conservative: not seen all our requests? */
-#endif
-
-static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE];
-static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1];
-static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
+static unsigned long rx_pfn_array[NET_RX_RING_SIZE];
+static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
+static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
 
 struct netfront_info
 {
@@ -99,11 +89,10 @@
        struct net_device *netdev;
 
        struct net_device_stats stats;
-       NETIF_RING_IDX rx_resp_cons, tx_resp_cons;
        unsigned int tx_full;
     
-       netif_tx_interface_t *tx;
-       netif_rx_interface_t *rx;
+       netif_tx_front_ring_t tx;
+       netif_rx_front_ring_t rx;
 
        spinlock_t   tx_lock;
        spinlock_t   rx_lock;
@@ -124,7 +113,7 @@
 
        /* Receive-ring batched refills. */
 #define RX_MIN_TARGET 8
-#define RX_MAX_TARGET NETIF_RX_RING_SIZE
+#define RX_MAX_TARGET NET_RX_RING_SIZE
        int rx_min_target, rx_max_target, rx_target;
        struct sk_buff_head rx_batch;
 
@@ -132,13 +121,13 @@
         * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
         * array is an index into a chain of free entries.
         */
-       struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1];
-       struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
+       struct sk_buff *tx_skbs[NET_TX_RING_SIZE+1];
+       struct sk_buff *rx_skbs[NET_RX_RING_SIZE+1];
 
        grant_ref_t gref_tx_head;
-       grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1]; 
+       grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; 
        grant_ref_t gref_rx_head;
-       grant_ref_t grant_rx_ref[NETIF_TX_RING_SIZE + 1]; 
+       grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1]; 
 
        struct xenbus_device *xbdev;
        int tx_ring_ref;
@@ -337,37 +326,45 @@
 
 static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
 {
+       netif_tx_sring_t *txs;
+       netif_rx_sring_t *rxs;
        int err;
        struct net_device *netdev = info->netdev;
 
        info->tx_ring_ref = GRANT_INVALID_REF;
        info->rx_ring_ref = GRANT_INVALID_REF;
-       info->rx = NULL;
-       info->tx = NULL;
+       info->rx.sring = NULL;
+       info->tx.sring = NULL;
        info->irq = 0;
 
-       info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
-       if (!info->tx) {
+       txs = (netif_tx_sring_t *)__get_free_page(GFP_KERNEL);
+       if (!txs) {
                err = -ENOMEM;
                xenbus_dev_fatal(dev, err, "allocating tx ring page");
                goto fail;
        }
-       info->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
-       if (!info->rx) {
+       rxs = (netif_rx_sring_t *)__get_free_page(GFP_KERNEL);
+       if (!rxs) {
                err = -ENOMEM;
                xenbus_dev_fatal(dev, err, "allocating rx ring page");
                goto fail;
        }
-       memset(info->tx, 0, PAGE_SIZE);
-       memset(info->rx, 0, PAGE_SIZE);
+       memset(txs, 0, PAGE_SIZE);
+       memset(rxs, 0, PAGE_SIZE);
        info->backend_state = BEST_DISCONNECTED;
 
-       err = xenbus_grant_ring(dev, virt_to_mfn(info->tx));
+       SHARED_RING_INIT(txs);
+       FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
+
+       SHARED_RING_INIT(rxs);
+       FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
+
+       err = xenbus_grant_ring(dev, virt_to_mfn(txs));
        if (err < 0)
                goto fail;
        info->tx_ring_ref = err;
 
-       err = xenbus_grant_ring(dev, virt_to_mfn(info->rx));
+       err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
        if (err < 0)
                goto fail;
        info->rx_ring_ref = err;
@@ -454,7 +451,7 @@
        np->user_state = UST_OPEN;
 
        network_alloc_rx_buffers(dev);
-       np->rx->event = np->rx_resp_cons + 1;
+       np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
 
        netif_start_queue(dev);
 
@@ -463,7 +460,7 @@
 
 static void network_tx_buf_gc(struct net_device *dev)
 {
-       NETIF_RING_IDX i, prod;
+       RING_IDX i, prod;
        unsigned short id;
        struct netfront_info *np = netdev_priv(dev);
        struct sk_buff *skb;
@@ -472,11 +469,11 @@
                return;
 
        do {
-               prod = np->tx->resp_prod;
+               prod = np->tx.sring->rsp_prod;
                rmb(); /* Ensure we see responses up to 'rp'. */
 
-               for (i = np->tx_resp_cons; i != prod; i++) {
-                       id  = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id;
+               for (i = np->tx.rsp_cons; i != prod; i++) {
+                       id  = RING_GET_RESPONSE(&np->tx, i)->id;
                        skb = np->tx_skbs[id];
                        if (unlikely(gnttab_query_foreign_access(
                                np->grant_tx_ref[id]) != 0)) {
@@ -494,7 +491,7 @@
                        dev_kfree_skb_irq(skb);
                }
         
-               np->tx_resp_cons = prod;
+               np->tx.rsp_cons = prod;
         
                /*
                 * Set a new event, then check for race with update of tx_cons.
@@ -504,12 +501,14 @@
                 * data is outstanding: in such cases notification from Xen is
                 * likely to be the only kick that we'll get.
                 */
-               np->tx->event = prod + ((np->tx->req_prod - prod) >> 1) + 1;
+               np->tx.sring->rsp_event =
+                       prod + ((np->tx.sring->req_prod - prod) >> 1) + 1;
                mb();
-       } while (prod != np->tx->resp_prod);
+       } while (prod != np->tx.sring->rsp_prod);
 
  out: 
-       if (np->tx_full && ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE)) {
+       if (np->tx_full &&
+           ((np->tx.sring->req_prod - prod) < NET_TX_RING_SIZE)) {
                np->tx_full = 0;
                if (np->user_state == UST_OPEN)
                        netif_wake_queue(dev);
@@ -523,7 +522,7 @@
        struct netfront_info *np = netdev_priv(dev);
        struct sk_buff *skb;
        int i, batch_target;
-       NETIF_RING_IDX req_prod = np->rx->req_prod;
+       RING_IDX req_prod = np->rx.req_prod_pvt;
        struct xen_memory_reservation reservation;
        grant_ref_t ref;
 
@@ -536,7 +535,7 @@
         * allocator, so should reduce the chance of failed allocation requests
         *  both for ourself and for other kernel subsystems.
         */
-       batch_target = np->rx_target - (req_prod - np->rx_resp_cons);
+       batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
        for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
                skb = alloc_xen_skb(dev->mtu + RX_HEADROOM);
                if (skb == NULL)
@@ -558,13 +557,13 @@
 
                np->rx_skbs[id] = skb;
         
-               np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
+               RING_GET_REQUEST(&np->rx, req_prod + i)->id = id;
                ref = gnttab_claim_grant_reference(&np->gref_rx_head);
                BUG_ON((signed short)ref < 0);
                np->grant_rx_ref[id] = ref;
                gnttab_grant_foreign_transfer_ref(ref,
                                                  np->xbdev->otherend_id);
-               np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref;
+               RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
                rx_pfn_array[i] = virt_to_mfn(skb->head);
 
                /* Remove this page from map before passing back to Xen. */
@@ -599,10 +598,11 @@
                panic("Unable to reduce memory reservation\n");
 
        /* Above is a suitable barrier to ensure backend will see requests. */
-       np->rx->req_prod = req_prod + i;
+       np->rx.req_prod_pvt = req_prod + i;
+       RING_PUSH_REQUESTS(&np->rx);
 
        /* Adjust our fill target if we risked running out of buffers. */
-       if (((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) &&
+       if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
            ((np->rx_target *= 2) > np->rx_max_target))
                np->rx_target = np->rx_max_target;
 }
@@ -613,9 +613,10 @@
        unsigned short id;
        struct netfront_info *np = netdev_priv(dev);
        netif_tx_request_t *tx;
-       NETIF_RING_IDX i;
+       RING_IDX i;
        grant_ref_t ref;
        unsigned long mfn;
+       int notify;
 
        if (unlikely(np->tx_full)) {
                printk(KERN_ALERT "%s: full queue wasn't stopped!\n",
@@ -643,12 +644,12 @@
                goto drop;
        }
 
-       i = np->tx->req_prod;
+       i = np->tx.req_prod_pvt;
 
        id = GET_ID_FROM_FREELIST(np->tx_skbs);
        np->tx_skbs[id] = skb;
 
-       tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req;
+       tx = RING_GET_REQUEST(&np->tx, i);
 
        tx->id   = id;
        ref = gnttab_claim_grant_reference(&np->gref_tx_head);
@@ -659,14 +660,16 @@
        tx->gref = np->grant_tx_ref[id] = ref;
        tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
        tx->size = skb->len;
-       tx->csum_blank = (skb->ip_summed == CHECKSUM_HW);
-
-       wmb(); /* Ensure that backend will see the request. */
-       np->tx->req_prod = i + 1;
+       tx->flags = (skb->ip_summed == CHECKSUM_HW) ? NETTXF_csum_blank : 0;
+
+       np->tx.req_prod_pvt = i + 1;
+       RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
+       if (notify)
+               notify_remote_via_irq(np->irq);
 
        network_tx_buf_gc(dev);
 
-       if ((i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1)) {
+       if (RING_FULL(&np->tx)) {
                np->tx_full = 1;
                netif_stop_queue(dev);
        }
@@ -675,11 +678,6 @@
 
        np->stats.tx_bytes += skb->len;
        np->stats.tx_packets++;
-
-       /* Only notify Xen if we really have to. */
-       mb();
-       if (np->tx->TX_TEST_IDX == i)
-               notify_remote_via_irq(np->irq);
 
        return 0;
 
@@ -699,7 +697,7 @@
        network_tx_buf_gc(dev);
        spin_unlock_irqrestore(&np->tx_lock, flags);
 
-       if ((np->rx_resp_cons != np->rx->resp_prod) &&
+       if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx) &&
            (np->user_state == UST_OPEN))
                netif_rx_schedule(dev);
 
@@ -712,7 +710,7 @@
        struct netfront_info *np = netdev_priv(dev);
        struct sk_buff *skb, *nskb;
        netif_rx_response_t *rx;
-       NETIF_RING_IDX i, rp;
+       RING_IDX i, rp;
        mmu_update_t *mmu = rx_mmu;
        multicall_entry_t *mcl = rx_mcl;
        int work_done, budget, more_to_do = 1;
@@ -732,46 +730,42 @@
 
        if ((budget = *pbudget) > dev->quota)
                budget = dev->quota;
-       rp = np->rx->resp_prod;
+       rp = np->rx.sring->rsp_prod;
        rmb(); /* Ensure we see queued responses up to 'rp'. */
 
-       for (i = np->rx_resp_cons, work_done = 0; 
+       for (i = np->rx.rsp_cons, work_done = 0; 
             (i != rp) && (work_done < budget);
             i++, work_done++) {
-               rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
+               rx = RING_GET_RESPONSE(&np->rx, i);
+
                /*
-                * An error here is very odd. Usually indicates a backend bug,
-                * low-mem condition, or we didn't have reservation headroom.
-                */
-               if (unlikely(rx->status <= 0)) {
-                       if (net_ratelimit())
-                               printk(KERN_WARNING "Bad rx buffer "
-                                      "(memory squeeze?).\n");
-                       np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].
-                               req.id = rx->id;
-                       wmb();
-                       np->rx->req_prod++;
+                 * This definitely indicates a bug, either in this driver or
+                 * in the backend driver. In future this should flag the bad
+                 * situation to the system controller to reboot the backed.
+                 */
+               if ((ref = np->grant_rx_ref[rx->id]) == GRANT_INVALID_REF) {
+                       WPRINTK("Bad rx response id %d.\n", rx->id);
                        work_done--;
                        continue;
                }
 
-               ref = np->grant_rx_ref[rx->id]; 
-
-               if(ref == GRANT_INVALID_REF) { 
-                       printk(KERN_WARNING "Bad rx grant reference %d "
-                              "from dom %d.\n",
-                              ref, np->xbdev->otherend_id);
-                       np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].
-                               req.id = rx->id;
-                       wmb();
-                       np->rx->req_prod++;
+               /* Memory pressure, insufficient buffer headroom, ... */
+               if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) {
+                       if (net_ratelimit())
+                               WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n",
+                                       rx->id, rx->status);
+                       RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id =
+                               rx->id;
+                       RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref =
+                               ref;
+                       np->rx.req_prod_pvt++;
+                       RING_PUSH_REQUESTS(&np->rx);
                        work_done--;
                        continue;
                }
 
+               gnttab_release_grant_reference(&np->gref_rx_head, ref);
                np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
-               mfn = gnttab_end_foreign_transfer_ref(ref);
-               gnttab_release_grant_reference(&np->gref_rx_head, ref);
 
                skb = np->rx_skbs[rx->id];
                ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
@@ -781,7 +775,7 @@
                skb->len  = rx->status;
                skb->tail = skb->data + skb->len;
 
-               if ( rx->csum_valid )
+               if ( rx->flags & NETRXF_csum_valid )
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
 
                np->stats.rx_packets++;
@@ -867,11 +861,11 @@
                dev->last_rx = jiffies;
        }
 
-       np->rx_resp_cons = i;
+       np->rx.rsp_cons = i;
 
        /* If we get a callback with very few responses, reduce fill target. */
        /* NB. Note exponential increase, linear decrease. */
-       if (((np->rx->req_prod - np->rx->resp_prod) >
+       if (((np->rx.req_prod_pvt - np->rx.sring->rsp_prod) >
             ((3*np->rx_target) / 4)) &&
            (--np->rx_target < np->rx_min_target))
                np->rx_target = np->rx_min_target;
@@ -884,14 +878,9 @@
        if (work_done < budget) {
                local_irq_save(flags);
 
-               np->rx->event = i + 1;
-    
-               /* Deal with hypervisor racing our resetting of rx_event. */
-               mb();
-               if (np->rx->resp_prod == i) {
+               RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
+               if (!more_to_do)
                        __netif_rx_complete(dev);
-                       more_to_do = 0;
-               }
 
                local_irq_restore(flags);
        }
@@ -931,8 +920,7 @@
        /* Recovery procedure: */
 
        /* Step 1: Reinitialise variables. */
-       np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
-       np->rx->event = np->tx->event = 1;
+       np->tx_full = 0;
 
        /*
         * Step 2: Rebuild the RX and TX ring contents.
@@ -952,13 +940,14 @@
         * to avoid this but maybe it doesn't matter so much given the
         * interface has been down.
         */
-       for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) {
+       for (requeue_idx = 0, i = 1; i <= NET_TX_RING_SIZE; i++) {
                if ((unsigned long)np->tx_skbs[i] < __PAGE_OFFSET)
                        continue;
 
                skb = np->tx_skbs[i];
 
-               tx = &np->tx->ring[requeue_idx++].req;
+               tx = RING_GET_REQUEST(&np->tx, requeue_idx);
+               requeue_idx++;
 
                tx->id = i;
                gnttab_grant_foreign_access_ref(
@@ -968,27 +957,30 @@
                tx->gref = np->grant_tx_ref[i];
                tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
                tx->size = skb->len;
-               tx->csum_blank = (skb->ip_summed == CHECKSUM_HW);
+               tx->flags = (skb->ip_summed == CHECKSUM_HW) ?
+                       NETTXF_csum_blank : 0;
 
                np->stats.tx_bytes += skb->len;
                np->stats.tx_packets++;
        }
-       wmb();
-       np->tx->req_prod = requeue_idx;
+
+       np->tx.req_prod_pvt = requeue_idx;
+       RING_PUSH_REQUESTS(&np->tx);
 
        /* Rebuild the RX buffer freelist and the RX ring itself. */
-       for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) { 
+       for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) { 
                if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
                        continue;
                gnttab_grant_foreign_transfer_ref(
                        np->grant_rx_ref[i], np->xbdev->otherend_id);
-               np->rx->ring[requeue_idx].req.gref =
+               RING_GET_REQUEST(&np->rx, requeue_idx)->gref =
                        np->grant_rx_ref[i];
-               np->rx->ring[requeue_idx].req.id = i;
+               RING_GET_REQUEST(&np->rx, requeue_idx)->id = i;
                requeue_idx++; 
        }
-       wmb();                
-       np->rx->req_prod = requeue_idx;
+
+       np->rx.req_prod_pvt = requeue_idx;
+       RING_PUSH_REQUESTS(&np->rx);
 
        /*
         * Step 3: All public and private state should now be sane.  Get
@@ -997,7 +989,6 @@
         * packets.
         */
        np->backend_state = BEST_CONNECTED;
-       wmb();
        notify_remote_via_irq(np->irq);
        network_tx_buf_gc(dev);
 
@@ -1072,25 +1063,25 @@
        np->rx_max_target = RX_MAX_TARGET;
 
        /* Initialise {tx,rx}_skbs as a free chain containing every entry. */
-       for (i = 0; i <= NETIF_TX_RING_SIZE; i++) {
+       for (i = 0; i <= NET_TX_RING_SIZE; i++) {
                np->tx_skbs[i] = (void *)((unsigned long) i+1);
                np->grant_tx_ref[i] = GRANT_INVALID_REF;
        }
 
-       for (i = 0; i <= NETIF_RX_RING_SIZE; i++) {
+       for (i = 0; i <= NET_RX_RING_SIZE; i++) {
                np->rx_skbs[i] = (void *)((unsigned long) i+1);
                np->grant_rx_ref[i] = GRANT_INVALID_REF;
        }
 
        /* A grant for every tx ring slot */
-       if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
+       if (gnttab_alloc_grant_references(NET_TX_RING_SIZE,
                                          &np->gref_tx_head) < 0) {
                printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
                err = -ENOMEM;
                goto exit;
        }
        /* A grant for every rx ring slot */
-       if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
+       if (gnttab_alloc_grant_references(NET_RX_RING_SIZE,
                                          &np->gref_rx_head) < 0) {
                printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
                gnttab_free_grant_references(np->gref_tx_head);
@@ -1218,12 +1209,12 @@
        spin_unlock(&info->rx_lock);
        spin_unlock_irq(&info->tx_lock);
     
-       end_access(info->tx_ring_ref, info->tx);
-       end_access(info->rx_ring_ref, info->rx);
+       end_access(info->tx_ring_ref, info->tx.sring);
+       end_access(info->rx_ring_ref, info->rx.sring);
        info->tx_ring_ref = GRANT_INVALID_REF;
        info->rx_ring_ref = GRANT_INVALID_REF;
-       info->tx = NULL;
-       info->rx = NULL;
+       info->tx.sring = NULL;
+       info->rx.sring = NULL;
 
        if (info->irq)
                unbind_from_irqhandler(info->irq, info->netdev);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Fri Dec  2 
18:52:25 2005
@@ -33,18 +33,19 @@
 #include <asm-xen/xen_proc.h>
 
 static struct proc_dir_entry *privcmd_intf;
+static struct proc_dir_entry *capabilities_intf;
 
 static int privcmd_ioctl(struct inode *inode, struct file *file,
                          unsigned int cmd, unsigned long data)
 {
        int ret = -ENOSYS;
+       void __user *udata = (void __user *) data;
 
        switch (cmd) {
        case IOCTL_PRIVCMD_HYPERCALL: {
                privcmd_hypercall_t hypercall;
   
-               if (copy_from_user(&hypercall, (void *)data,
-                                  sizeof(hypercall)))
+               if (copy_from_user(&hypercall, udata, sizeof(hypercall)))
                        return -EFAULT;
 
 #if defined(__i386__)
@@ -97,10 +98,11 @@
        case IOCTL_PRIVCMD_MMAP: {
 #define PRIVCMD_MMAP_SZ 32
                privcmd_mmap_t mmapcmd;
-               privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ], *p;
+               privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ];
+               privcmd_mmap_entry_t __user *p;
                int i, rc;
 
-               if (copy_from_user(&mmapcmd, (void *)data, sizeof(mmapcmd)))
+               if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd)))
                        return -EFAULT;
 
                p = mmapcmd.entry;
@@ -146,12 +148,12 @@
                mmu_update_t u;
                privcmd_mmapbatch_t m;
                struct vm_area_struct *vma = NULL;
-               unsigned long *p, addr;
-               unsigned long mfn; 
+               unsigned long __user *p;
+               unsigned long addr, mfn; 
                uint64_t ptep;
                int i;
 
-               if (copy_from_user(&m, (void *)data, sizeof(m))) {
+               if (copy_from_user(&m, udata, sizeof(m))) {
                        ret = -EFAULT;
                        goto batch_err;
                }
@@ -212,43 +214,6 @@
        break;
 #endif
 
-#ifndef __ia64__
-       case IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS: {
-               pgd_t *pgd; 
-               pud_t *pud; 
-               pmd_t *pmd; 
-               unsigned long m2pv, m2p_mfn;    
-               privcmd_m2pmfns_t m; 
-               unsigned long *p; 
-               int i; 
-
-               if (copy_from_user(&m, (void *)data, sizeof(m)))
-                       return -EFAULT;
-
-               m2pv = (unsigned long)machine_to_phys_mapping;
-
-               p = m.arr; 
-
-               for (i=0; i < m.num; i++) { 
-                       pgd = pgd_offset_k(m2pv);
-                       pud = pud_offset(pgd, m2pv);
-                       pmd = pmd_offset(pud, m2pv);
-                       m2p_mfn  = (*(uint64_t *)pmd >> PAGE_SHIFT)&0xFFFFFFFF;
-                       m2p_mfn += pte_index(m2pv);
-
-                       if (put_user(m2p_mfn, p + i))
-                               return -EFAULT;
-
-                       m2pv += (1 << 21); 
-               }
-
-               ret = 0; 
-               break; 
-
-       }
-       break;
-#endif
-
        default:
                ret = -EINVAL;
                break;
@@ -270,12 +235,28 @@
        .mmap  = privcmd_mmap,
 };
 
+static int capabilities_read(char *page, char **start, off_t off,
+                        int count, int *eof, void *data)
+{
+       int len = 0;
+       *page = 0;
+
+       if (xen_start_info->flags & SIF_INITDOMAIN)
+               len = sprintf( page, "control_d\n" );
+
+       *eof = 1;
+       return len;
+}
 
 static int __init privcmd_init(void)
 {
        privcmd_intf = create_xen_proc_entry("privcmd", 0400);
        if (privcmd_intf != NULL)
                privcmd_intf->proc_fops = &privcmd_file_ops;
+
+       capabilities_intf = create_xen_proc_entry("capabilities", 0400 );
+       if (capabilities_intf != NULL)
+               capabilities_intf->read_proc = capabilities_read;
 
        return 0;
 }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Fri Dec  2 18:52:25 2005
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <asm-xen/evtchn.h>
 #include <asm-xen/driver_util.h>
+#include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/xen-public/io/tpmif.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
@@ -28,7 +29,7 @@
 #endif
 
 typedef struct tpmif_st {
-        struct list_head tpmif_list;
+       struct list_head tpmif_list;
        /* Unique identifier for this interface. */
        domid_t domid;
        unsigned int handle;
@@ -54,7 +55,7 @@
 
        struct work_struct work;
 
-       u16 shmem_handle;
+       grant_handle_t shmem_handle;
        grant_ref_t shmem_ref;
 } tpmif_t;
 
@@ -83,6 +84,11 @@
 
 #define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
 
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
 #endif /* __TPMIF__BACKEND__COMMON_H__ */
 
 /*
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Fri Dec  2 
18:52:25 2005
@@ -91,9 +91,9 @@
        unlock_vm_area(tpmif->tx_area);
        BUG_ON(ret);
 
-       if (op.handle < 0) {
+       if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
-               return op.handle;
+               return op.status;
        }
 
        tpmif->shmem_ref = shared_page;
@@ -127,6 +127,10 @@
                .u.bind_interdomain.remote_dom = tpmif->domid,
                .u.bind_interdomain.remote_port = evtchn };
 
+        if (tpmif->irq) {
+                return 0;
+        }
+
        if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
 
@@ -149,7 +153,6 @@
 
        tpmif->irq = bind_evtchn_to_irqhandler(
                tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
-       tpmif->status = CONNECTED;
        tpmif->shmem_ref = shared_page;
        tpmif->active = 1;
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Fri Dec  2 
18:52:25 2005
@@ -249,7 +249,7 @@
         * and send it to the front end.
         */
        tpmif_t *tpmif = pak->tpmif;
-       u16 handle;
+       grant_handle_t handle;
        int rc = 0;
        unsigned int i = 0;
        unsigned int offset = 0;
@@ -290,7 +290,7 @@
 
                handle = map_op.handle;
 
-               if (map_op.handle < 0) {
+               if (map_op.status) {
                        DPRINTK(" Grant table operation failure !\n");
                        return 0;
                }
@@ -427,7 +427,7 @@
        u32 i = (last_read / PAGE_SIZE);
        u32 pg_offset = last_read & (PAGE_SIZE - 1);
        u32 to_copy;
-       u16 handle;
+       grant_handle_t handle;
 
        tpmif_tx_request_t *tx;
        tx = &tpmif->tx->ring[0].req;
@@ -455,7 +455,7 @@
                        BUG();
                }
 
-               if (map_op.handle < 0) {
+               if (map_op.status) {
                        DPRINTK(" Grant table operation failure !\n");
                        return -EFAULT;
                }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Fri Dec  2 18:52:25 2005
@@ -1,4 +1,5 @@
 /*  Xenbus code for tpmif backend
+    Copyright (C) 2005 IBM Corporation
     Copyright (C) 2005 Rusty Russell <rusty@xxxxxxxxxxxxxxx>
 
     This program is free software; you can redistribute it and/or modify
@@ -29,72 +30,189 @@
 
        long int frontend_id;
        long int instance; // instance of TPM
+       u8 is_instance_set;// whether instance number has been set
 
        /* watch front end for changes */
        struct xenbus_watch backend_watch;
-
-       struct xenbus_watch watch;
-       char * frontpath;
+       XenbusState frontend_state;
 };
 
+static void maybe_connect(struct backend_info *be);
+static void connect(struct backend_info *be);
+static int connect_ring(struct backend_info *be);
+static void backend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len);
+static void frontend_changed(struct xenbus_device *dev,
+                             XenbusState frontend_state);
+
 static int tpmback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->data;
 
-       if (be->watch.node)
-               unregister_xenbus_watch(&be->watch);
-       unregister_xenbus_watch(&be->backend_watch);
-
-       tpmif_vtpm_close(be->instance);
-
-       if (be->tpmif)
+       if (be->backend_watch.node) {
+               unregister_xenbus_watch(&be->backend_watch);
+               kfree(be->backend_watch.node);
+               be->backend_watch.node = NULL;
+       }
+       if (be->tpmif) {
                tpmif_put(be->tpmif);
-
-       kfree(be->frontpath);
+               be->tpmif = NULL;
+       }
        kfree(be);
+       dev->data = NULL;
        return 0;
 }
 
-
-static void frontend_changed(struct xenbus_watch *watch,
-                            const char **vec, unsigned int len)
-{
-       unsigned long ringref;
-       unsigned int evtchn;
-       unsigned long ready = 1;
-       int err;
-       struct xenbus_transaction *xbt;
+static int tpmback_probe(struct xenbus_device *dev,
+                         const struct xenbus_device_id *id)
+{
+       int err;
+       struct backend_info *be = kmalloc(sizeof(struct backend_info),
+                                         GFP_KERNEL);
+
+       if (!be) {
+               xenbus_dev_fatal(dev, -ENOMEM,
+                                "allocating backend structure");
+               return -ENOMEM;
+       }
+
+       memset(be, 0, sizeof(*be));
+
+       be->is_instance_set = FALSE;
+       be->dev = dev;
+       dev->data = be;
+
+       err = xenbus_watch_path2(dev, dev->nodename,
+                               "instance", &be->backend_watch,
+                               backend_changed);
+       if (err) {
+               goto fail;
+       }
+
+       err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
+       if (err) {
+               goto fail;
+       }
+       return 0;
+fail:
+       tpmback_remove(dev);
+       return err;
+}
+
+
+static void backend_changed(struct xenbus_watch *watch,
+                            const char **vec, unsigned int len)
+{
+       int err;
+       long instance;
        struct backend_info *be
-               = container_of(watch, struct backend_info, watch);
-
-       /* If other end is gone, delete ourself. */
-       if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
-               xenbus_rm(NULL, be->dev->nodename, "");
+               = container_of(watch, struct backend_info, backend_watch);
+       struct xenbus_device *dev = be->dev;
+
+       err = xenbus_scanf(NULL, dev->nodename,
+                          "instance","%li", &instance);
+       if (XENBUS_EXIST_ERR(err)) {
+               return;
+       }
+
+       if (err != 1) {
+               xenbus_dev_fatal(dev, err, "reading instance");
+               return;
+       }
+
+       if (be->is_instance_set != FALSE && be->instance != instance) {
+               printk(KERN_WARNING
+                      "tpmback: changing instance (from %ld to %ld) "
+                      "not allowed.\n",
+                      be->instance, instance);
+               return;
+       }
+
+       if (be->is_instance_set == FALSE) {
+               be->tpmif = tpmif_find(dev->otherend_id,
+                                      instance);
+               if (IS_ERR(be->tpmif)) {
+                       err = PTR_ERR(be->tpmif);
+                       be->tpmif = NULL;
+                       xenbus_dev_fatal(dev,err,"creating block interface");
+                       return;
+               }
+               be->instance = instance;
+               be->is_instance_set = TRUE;
+
+               /*
+                * There's an unfortunate problem:
+                * Sometimes after a suspend/resume the
+                * state switch to XenbusStateInitialised happens
+                * *before* I get to this point here. Since then
+                * the connect_ring() must have failed (be->tpmif is
+                * still NULL), I just call it here again indirectly.
+                */
+               if (be->frontend_state == XenbusStateInitialised) {
+                       frontend_changed(dev, be->frontend_state);
+               }
+       }
+}
+
+
+static void frontend_changed(struct xenbus_device *dev,
+                             XenbusState frontend_state)
+{
+       struct backend_info *be = dev->data;
+       int err;
+
+       be->frontend_state = frontend_state;
+
+       switch (frontend_state) {
+       case XenbusStateInitialising:
+       case XenbusStateConnected:
+               break;
+
+       case XenbusStateInitialised:
+               err = connect_ring(be);
+               if (err) {
+                       return;
+               }
+               maybe_connect(be);
+               break;
+
+       case XenbusStateClosing:
+               xenbus_switch_state(dev, NULL, XenbusStateClosing);
+               break;
+
+       case XenbusStateClosed:
+               /*
+                * Notify the vTPM manager about the front-end
+                * having left.
+                */
+               tpmif_vtpm_close(be->instance);
                device_unregister(&be->dev->dev);
-               return;
-       }
+               break;
+
+       case XenbusStateUnknown:
+       case XenbusStateInitWait:
+       default:
+               xenbus_dev_fatal(dev, -EINVAL,
+                                "saw state %d at frontend",
+                                frontend_state);
+               break;
+       }
+}
+
+
+
+static void maybe_connect(struct backend_info *be)
+{
+       int err;
 
        if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
                return;
 
-       err = xenbus_gather(NULL, be->frontpath,
-                           "ring-ref", "%lu", &ringref,
-                           "event-channel", "%u", &evtchn, NULL);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "reading %s/ring-ref and event-channel",
-                                be->frontpath);
-               return;
-       }
-
-       err = tpmif_map(be->tpmif, ringref, evtchn);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "mapping shared-frame %lu port %u",
-                                ringref, evtchn);
-               return;
-       }
-
+       connect(be);
+
+       /*
+        * Notify the vTPM manager about a new front-end.
+        */
        err = tpmif_vtpm_open(be->tpmif,
                              be->frontend_id,
                              be->instance);
@@ -107,157 +225,75 @@
                 */
                return;
        }
-
-       /*
-        * Tell the front-end that we are ready to go -
-        * unless something bad happens
-        */
+}
+
+
+static void connect(struct backend_info *be)
+{
+       struct xenbus_transaction *xbt;
+       int err;
+       struct xenbus_device *dev = be->dev;
+       unsigned long ready = 1;
+
 again:
        xbt = xenbus_transaction_start();
        if (IS_ERR(xbt)) {
-               xenbus_dev_error(be->dev, err, "starting transaction");
+               err = PTR_ERR(xbt);
+               xenbus_dev_fatal(be->dev, err, "starting transaction");
                return;
        }
 
        err = xenbus_printf(xbt, be->dev->nodename,
                            "ready", "%lu", ready);
        if (err) {
-               xenbus_dev_error(be->dev, err, "writing 'ready'");
+               xenbus_dev_fatal(be->dev, err, "writing 'ready'");
                goto abort;
        }
+
+       err = xenbus_switch_state(dev, xbt, XenbusStateConnected);
+       if (err)
+               goto abort;
+
+       be->tpmif->status = CONNECTED;
 
        err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
        if (err) {
-               xenbus_dev_error(be->dev, err, "end of transaction");
-               goto abort;
-       }
-
-       xenbus_dev_ok(be->dev);
+               xenbus_dev_fatal(be->dev, err, "end of transaction");
+       }
        return;
 abort:
        xenbus_transaction_end(xbt, 1);
 }
 
 
-static void backend_changed(struct xenbus_watch *watch,
-                           const char **vec, unsigned int len)
-{
-       int err;
-       long int instance;
-       struct backend_info *be
-               = container_of(watch, struct backend_info, backend_watch);
+static int connect_ring(struct backend_info *be)
+{
        struct xenbus_device *dev = be->dev;
-
-       err = xenbus_scanf(NULL, dev->nodename, "instance", "%li", &instance);
-       if (XENBUS_EXIST_ERR(err))
-               return;
-       if (err < 0) {
-               xenbus_dev_error(dev, err, "reading 'instance' variable");
-               return;
-       }
-
-       if (be->instance != -1 && be->instance != instance) {
-               printk(KERN_WARNING
-                      "cannot change the instance\n");
-               return;
-       }
-       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)) {
-                       err = PTR_ERR(be->tpmif);
-                       be->tpmif = NULL;
-                       xenbus_dev_error(dev, err, "creating interface");
-                       return;
+       unsigned long ring_ref;
+       unsigned int evtchn;
+       int err;
+
+       err = xenbus_gather(NULL, dev->otherend,
+                           "ring-ref", "%lu", &ring_ref,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(dev, err,
+                                "reading %s/ring-ref and event-channel",
+                                dev->otherend);
+               return err;
+       }
+       if (be->tpmif != NULL) {
+               err = tpmif_map(be->tpmif, ring_ref, evtchn);
+               if (err) {
+                       xenbus_dev_error(dev, err,
+                                        "mapping shared-frame %lu port %u",
+                                        ring_ref, evtchn);
+                       return err;
                }
-
-               vec[XS_WATCH_PATH] = be->frontpath;
-               vec[XS_WATCH_TOKEN] = NULL;
-
-               /* Pass in NULL node to skip exist test. */
-               frontend_changed(&be->watch, vec, len);
-       }
-}
-
-
-static int tpmback_probe(struct xenbus_device *dev,
-                        const struct xenbus_device_id *id)
-{
-       struct backend_info *be;
-       char *frontend;
-       int err;
-
-       be = kmalloc(sizeof(*be), GFP_KERNEL);
-       if (!be) {
-               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
-               err = -ENOMEM;
-       }
-
-       memset(be, 0, sizeof(*be));
-
-       frontend = NULL;
-       err = xenbus_gather(NULL, dev->nodename,
-                           "frontend-id", "%li", &be->frontend_id,
-                           "frontend", NULL, &frontend,
-                           NULL);
-       if (XENBUS_EXIST_ERR(err))
-               goto free_be;
-       if (err < 0) {
-               xenbus_dev_error(dev, err,
-                                "reading %s/frontend or frontend-id",
-                                dev->nodename);
-               goto free_be;
-       }
-       if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
-               /* If we can't get a frontend path and a frontend-id,
-                * then our bus-id is no longer valid and we need to
-                * destroy the backend device.
-                */
-               err = -ENOENT;
-               goto free_be;
-       }
-
-       be->dev = dev;
-       be->backend_watch.node     = dev->nodename;
-       /* Implicitly calls backend_changed() once. */
-       be->backend_watch.callback = backend_changed;
-       be->instance = -1;
-       err = register_xenbus_watch(&be->backend_watch);
-       if (err) {
-               be->backend_watch.node = NULL;
-               xenbus_dev_error(dev, err, "adding backend watch on %s",
-                                dev->nodename);
-               goto free_be;
-       }
-
-       be->frontpath = frontend;
-       be->watch.node = be->frontpath;
-       be->watch.callback = frontend_changed;
-       err = register_xenbus_watch(&be->watch);
-       if (err) {
-               be->watch.node = NULL;
-               xenbus_dev_error(dev, err,
-                                "adding frontend watch on %s",
-                                be->frontpath);
-               goto free_be;
-       }
-
-       dev->data = be;
-       return err;
-
-free_be:
-       if (be->backend_watch.node)
-               unregister_xenbus_watch(&be->backend_watch);
-       kfree(frontend);
-       kfree(be);
-       return err;
+       }
+       return 0;
 }
 
 
@@ -273,6 +309,7 @@
        .ids = tpmback_ids,
        .probe = tpmback_probe,
        .remove = tpmback_remove,
+       .otherend_changed = frontend_changed,
 };
 
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Fri Dec  2 
18:52:25 2005
@@ -38,12 +38,13 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/tpmfe.h>
+#include <asm-xen/tpmfe.h>
 #include <linux/err.h>
 
 #include <asm/semaphore.h>
 #include <asm/io.h>
 #include <asm-xen/evtchn.h>
+#include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/xen-public/io/tpmif.h>
 #include <asm/uaccess.h>
 #include <asm-xen/xenbus.h>
@@ -73,7 +74,8 @@
 static void tpmif_connect(u16 evtchn, domid_t domid);
 static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
 static int tpm_allocate_buffers(struct tpm_private *tp);
-static void tpmif_set_connected_state(struct tpm_private *tp, int newstate);
+static void tpmif_set_connected_state(struct tpm_private *tp,
+                                      u8 newstate);
 static int tpm_xmit(struct tpm_private *tp,
                     const u8 * buf, size_t count, int userbuffer,
                     void *remember);
@@ -212,87 +214,46 @@
  XENBUS support code
 **************************************************************/
 
-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);
-
-       if (tp->connected)
-               return;
-
-       err = xenbus_gather(NULL, watch->node,
-                           "ready", "%lu", &ready,
-                           NULL);
-       if (err) {
-               xenbus_dev_error(info->dev, err, "reading 'ready' field");
-               return;
-       }
-
-       tpmif_set_connected_state(tp, 1);
-
-       xenbus_dev_ok(info->dev);
-}
-
-
 static int setup_tpmring(struct xenbus_device *dev,
-                         struct tpmfront_info * info,
-                         domid_t backend_id)
+                         struct tpmfront_info * info)
 {
        tpmif_tx_interface_t *sring;
        struct tpm_private *tp = &my_private;
        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) {
-               xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
+               xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
                return -ENOMEM;
        }
        tp->tx = sring;
 
        tpm_allocate_buffers(tp);
 
-       err = gnttab_grant_foreign_access(backend_id,
-                                         (virt_to_machine(tp->tx) >> 
PAGE_SHIFT),
-                                         0);
-
-       if (err == -ENOSPC) {
+       err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
+       if (err < 0) {
                free_page((unsigned long)sring);
                tp->tx = NULL;
-               xenbus_dev_error(dev, err, "allocating grant reference");
-               return err;
+               xenbus_dev_fatal(dev, err, "allocating grant reference");
+               goto fail;
        }
        info->ring_ref = err;
 
-       err = HYPERVISOR_event_channel_op(&op);
-       if (err) {
-               gnttab_end_foreign_access(info->ring_ref, 0,
-                                         (unsigned long)sring);
-               tp->tx = NULL;
-               xenbus_dev_error(dev, err, "allocating event channel");
-               return err;
-       }
-
-       tpmif_connect(op.u.alloc_unbound.port, backend_id);
+       err = xenbus_alloc_evtchn(dev, &tp->evtchn);
+       if (err)
+               goto fail;
+
+       tpmif_connect(tp->evtchn, dev->otherend_id);
 
        return 0;
+fail:
+       return err;
 }
 
 
 static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
 {
-       tpmif_set_connected_state(tp,0);
-
+       tpmif_set_connected_state(tp, FALSE);
        if ( tp->tx != NULL ) {
                gnttab_end_foreign_access(info->ring_ref, 0,
                                          (unsigned long)tp->tx);
@@ -308,42 +269,20 @@
 static int talk_to_backend(struct xenbus_device *dev,
                            struct tpmfront_info *info)
 {
-       char *backend;
-       const char *message;
+       const char *message = NULL;
        int err;
-       int backend_id;
        struct xenbus_transaction *xbt;
 
-       backend = NULL;
-       err = xenbus_gather(NULL, dev->nodename,
-                           "backend-id", "%i", &backend_id,
-                           "backend", NULL, &backend,
-                           NULL);
-       if (XENBUS_EXIST_ERR(err))
-               goto out;
-       if (backend && strlen(backend) == 0) {
-               err = -ENOENT;
-               goto out;
-       }
-       if (err < 0) {
-               xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
-                                dev->nodename);
-               goto out;
-       }
-
-       info->backend_id      = backend_id;
-       my_private.backend_id = backend_id;
-
-       err = setup_tpmring(dev, info, backend_id);
+       err = setup_tpmring(dev, info);
        if (err) {
-               xenbus_dev_error(dev, err, "setting up ring");
+               xenbus_dev_fatal(dev, err, "setting up ring");
                goto out;
        }
 
 again:
        xbt = xenbus_transaction_start();
        if (IS_ERR(xbt)) {
-               xenbus_dev_error(dev, err, "starting transaction");
+               xenbus_dev_fatal(dev, err, "starting transaction");
                goto destroy_tpmring;
        }
 
@@ -361,34 +300,60 @@
                goto abort_transaction;
        }
 
+       err = xenbus_switch_state(dev, xbt, XenbusStateInitialised);
+       if (err) {
+               goto abort_transaction;
+       }
+
        err = xenbus_transaction_end(xbt, 0);
        if (err == -EAGAIN)
                goto again;
        if (err) {
-               xenbus_dev_error(dev, err, "completing transaction");
+               xenbus_dev_fatal(dev, err, "completing transaction");
                goto destroy_tpmring;
        }
-
-       info->watch.node = backend;
-       info->watch.callback = watch_for_status;
-       err = register_xenbus_watch(&info->watch);
-       if (err) {
-               xenbus_dev_error(dev, err, "registering watch on backend");
-               goto destroy_tpmring;
-       }
-
-       info->backend = backend;
-
        return 0;
 
 abort_transaction:
        xenbus_transaction_end(xbt, 1);
-       xenbus_dev_error(dev, err, "%s", message);
+       if (message)
+               xenbus_dev_error(dev, err, "%s", message);
 destroy_tpmring:
        destroy_tpmring(info, &my_private);
 out:
-       kfree(backend);
        return err;
+}
+
+/**
+ * Callback received when the backend's state changes.
+ */
+static void backend_changed(struct xenbus_device *dev,
+                           XenbusState backend_state)
+{
+       struct tpm_private *tp = &my_private;
+       DPRINTK("\n");
+
+       switch (backend_state) {
+       case XenbusStateInitialising:
+       case XenbusStateInitWait:
+       case XenbusStateInitialised:
+       case XenbusStateUnknown:
+               break;
+
+       case XenbusStateConnected:
+               tpmif_set_connected_state(tp, TRUE);
+               break;
+
+       case XenbusStateClosing:
+               tpmif_set_connected_state(tp, FALSE);
+               break;
+
+       case XenbusStateClosed:
+               if (tp->is_suspended == FALSE) {
+                       device_unregister(&dev->dev);
+               }
+               break;
+       }
 }
 
 
@@ -398,8 +363,6 @@
        int err;
        struct tpmfront_info *info;
        int handle;
-       int len = max(XS_WATCH_PATH, XS_WATCH_TOKEN) + 1;
-       const char *vec[len];
 
        err = xenbus_scanf(NULL, dev->nodename,
                           "handle", "%i", &handle);
@@ -407,19 +370,19 @@
                return err;
 
        if (err < 0) {
-               xenbus_dev_error(dev,err,"reading virtual-device");
+               xenbus_dev_fatal(dev,err,"reading virtual-device");
                return err;
        }
 
        info = kmalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
-               xenbus_dev_error(dev,err,"allocating info structure");
+               err = -ENOMEM;
+               xenbus_dev_fatal(dev,err,"allocating info structure");
                return err;
        }
        memset(info, 0x0, sizeof(*info));
 
        info->dev = dev;
-       info->handle = handle;
        dev->data = info;
 
        err = talk_to_backend(dev, info);
@@ -428,41 +391,33 @@
                dev->data = NULL;
                return err;
        }
-
-       vec[XS_WATCH_PATH]  = info->watch.node;
-       vec[XS_WATCH_TOKEN] = NULL;
-       watch_for_status(&info->watch, vec, len);
-
        return 0;
 }
 
+
 static int tpmfront_remove(struct xenbus_device *dev)
 {
        struct tpmfront_info *info = dev->data;
-       if (info->backend)
-               unregister_xenbus_watch(&info->watch);
 
        destroy_tpmring(info, &my_private);
 
-       kfree(info->backend);
        kfree(info);
-
        return 0;
 }
 
 static int
 tpmfront_suspend(struct xenbus_device *dev)
 {
-       struct tpmfront_info *info = dev->data;
        struct tpm_private *tp = &my_private;
        u32 ctr = 0;
 
        /* lock, so no app can send */
        down(&suspend_lock);
+       tp->is_suspended = TRUE;
 
        while (atomic_read(&tp->tx_busy) && ctr <= 25) {
-               if ((ctr % 10) == 0)
-                       printk("INFO: Waiting for outstanding request.\n");
+               if ((ctr % 10) == 0)
+                       printk("TPM-FE [INFO]: Waiting for outstanding 
request.\n");
                /*
                 * Wait for a request to be responded to.
                 */
@@ -474,14 +429,9 @@
                /*
                 * A temporary work-around.
                 */
-               printk("WARNING: Resetting busy flag.");
+               printk("TPM-FE [WARNING]: Resetting busy flag.");
                atomic_set(&tp->tx_busy, 0);
        }
-
-       unregister_xenbus_watch(&info->watch);
-
-       kfree(info->backend);
-       info->backend = NULL;
 
        return 0;
 }
@@ -492,8 +442,6 @@
        struct tpmfront_info *info = dev->data;
        int err = talk_to_backend(dev, info);
 
-       /* unlock, so apps can resume sending */
-       up(&suspend_lock);
 
        return err;
 }
@@ -530,12 +478,13 @@
        .probe = tpmfront_probe,
        .remove =  tpmfront_remove,
        .resume = tpmfront_resume,
+       .otherend_changed = backend_changed,
        .suspend = tpmfront_suspend,
 };
 
 static void __init init_tpm_xenbus(void)
 {
-       xenbus_register_driver(&tpmfront);
+       xenbus_register_frontend(&tpmfront);
 }
 
 
@@ -628,12 +577,13 @@
        spin_lock_irq(&tp->tx_lock);
 
        if (unlikely(atomic_read(&tp->tx_busy))) {
-               printk("There's an outstanding request/response on the way!\n");
+               printk("tpm_xmit: There's an outstanding request/response "
+                      "on the way!\n");
                spin_unlock_irq(&tp->tx_lock);
                return -EBUSY;
        }
 
-       if (tp->connected != 1) {
+       if (tp->is_connected != TRUE) {
                spin_unlock_irq(&tp->tx_lock);
                return -EIO;
        }
@@ -705,24 +655,40 @@
        down(&upperlayer_lock);
 
        if (upperlayer_tpmfe != NULL) {
-               switch (tp->connected) {
-                       case 1:
-                               
upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
-                       break;
-
-                       default:
-                               upperlayer_tpmfe->status(0);
-                       break;
+               if (tp->is_connected) {
+                       upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
+               } else {
+                       upperlayer_tpmfe->status(0);
                }
        }
        up(&upperlayer_lock);
 }
 
 
-static void tpmif_set_connected_state(struct tpm_private *tp, int newstate)
-{
-       if (newstate != tp->connected) {
-               tp->connected = newstate;
+static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
+{
+       /*
+        * Don't notify upper layer if we are in suspend mode and
+        * should disconnect - assumption is that we will resume
+        * The semaphore keeps apps from sending.
+        */
+       if (is_connected == FALSE && tp->is_suspended == TRUE) {
+               return;
+       }
+
+       /*
+        * Unlock the semaphore if we are connected again
+        * after being suspended - now resuming.
+        * This also removes the suspend state.
+        */
+       if (is_connected == TRUE && tp->is_suspended == TRUE) {
+               tp->is_suspended = FALSE;
+               /* unlock, so apps can resume sending */
+               up(&suspend_lock);
+       }
+
+       if (is_connected != tp->is_connected) {
+               tp->is_connected = is_connected;
                tpmif_notify_upperlayer(tp);
        }
 }
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Fri Dec  2 
18:52:25 2005
@@ -1,12 +1,17 @@
 #ifndef TPM_FRONT_H
 #define TPM_FRONT_H
 
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
 
-struct tpm_private
-{
+struct tpm_private {
        tpmif_tx_interface_t *tx;
-       unsigned int evtchn, irq;
-       int connected;
+       unsigned int evtchn;
+       unsigned int irq;
+       u8 is_connected;
+       u8 is_suspended;
 
        spinlock_t tx_lock;
 
@@ -16,25 +21,18 @@
        void *tx_remember;
        domid_t backend_id;
        wait_queue_head_t wait_q;
+
 };
 
-
-struct tpmfront_info
-{
-       struct xenbus_watch watch;
-       int handle;
+struct tpmfront_info {
        struct xenbus_device *dev;
-       char *backend;
        int ring_ref;
-       domid_t backend_id;
 };
 
-
-struct tx_buffer
-{
+struct tx_buffer {
        unsigned int size;      // available space in data
        unsigned int len;       // used space in data
-       unsigned char *data;    // pointer to a page
+       unsigned char *data;    // pointer to a page
 };
 
 #endif
diff -r eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c   Fri Dec  2 18:52:25 2005
@@ -56,7 +56,7 @@
         * page-fault path will copy the page directory pointers from init_mm.
         */
        for (i = 0; i < area->size; i += PAGE_SIZE)
-               (void)__get_user(c, (char *)area->addr + i);
+               (void)__get_user(c, (char __user *)area->addr + i);
 }
 
 void unlock_vm_area(struct vm_struct *area)
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Fri Dec  2 
18:52:25 2005
@@ -97,14 +97,17 @@
        /* We check whether the state is currently set to the given value, and
           if not, then the state is set.  We don't want to unconditionally
           write the given state, because we don't want to fire watches
-          unnecessarily.
+          unnecessarily.  Furthermore, if the node has gone, we don't write
+          to it, as the device will be tearing down, and we don't want to
+          resurrect that directory.
         */
 
        int current_state;
 
        int err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
                               &current_state);
-       if (err == 1 && (XenbusState)current_state == state)
+       if ((err == 1 && (XenbusState)current_state == state) ||
+           err == -ENOENT)
                return 0;
 
        err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h    Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h    Fri Dec  2 
18:52:25 2005
@@ -501,7 +501,7 @@
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
        barrier();                                                      \
@@ -512,7 +512,7 @@
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 0;                                  \
        barrier(); /* unmask then check (avoid races) */                \
        if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
@@ -524,7 +524,7 @@
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        preempt_enable();                                               \
 } while (0)
@@ -534,7 +534,7 @@
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
                barrier(); /* unmask then check (avoid races) */        \
                if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
@@ -550,7 +550,7 @@
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
@@ -568,7 +568,7 @@
 ({     int ___x;                                                       \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        ___x = (_vcpu->evtchn_upcall_mask != 0);                        \
        preempt_enable_no_resched();                                    \
        ___x; })
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h  Fri Dec  2 
18:12:11 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h  Fri Dec  2 
18:52:25 2005
@@ -325,7 +325,7 @@
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
        barrier();                                                      \
@@ -336,7 +336,7 @@
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 0;                                  \
        barrier(); /* unmask then check (avoid races) */                \
        if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
@@ -348,7 +348,7 @@
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        preempt_enable();                                               \
 } while (0)
@@ -358,7 +358,7 @@
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
                barrier(); /* unmask then check (avoid races) */        \
                if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
@@ -374,7 +374,7 @@
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
@@ -394,7 +394,7 @@
 ({     int ___x;                                                       \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        ___x = (_vcpu->evtchn_upcall_mask != 0);                        \
        preempt_enable_no_resched();                                    \
        ___x; })
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Fri Dec  2 18:52:25 2005
@@ -102,7 +102,7 @@
 static inline void unmask_evtchn(int port)
 {
        shared_info_t *s = HYPERVISOR_shared_info;
-       vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
+       vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
 
        synch_clear_bit(port, &s->evtchn_mask[0]);
 
diff -r eae5812f33f1 -r 28bd01c9b596 
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       Fri Dec 
 2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Fri Dec 
 2 18:52:25 2005
@@ -30,6 +30,10 @@
 #ifndef __LINUX_PUBLIC_PRIVCMD_H__
 #define __LINUX_PUBLIC_PRIVCMD_H__
 
+#ifndef __user
+#define __user
+#endif
+
 typedef struct privcmd_hypercall
 {
        unsigned long op;
@@ -45,20 +49,15 @@
 typedef struct privcmd_mmap {
        int num;
        domid_t dom; /* target domain */
-       privcmd_mmap_entry_t *entry;
+       privcmd_mmap_entry_t __user *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 */
+       unsigned long __user *arr; /* array of mfns - top nibble set on err */
 } privcmd_mmapbatch_t; 
-
-typedef struct privcmd_m2pmfns { 
-       int num;    /* max number of mfns to return */
-       unsigned long *arr; /* array of mfns */
-} privcmd_m2pmfns_t; 
 
 typedef struct privcmd_blkmsg
 {
@@ -78,8 +77,6 @@
        _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_MFNS                       \
-       _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
 
 #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
 
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Fri Dec  2 18:52:25 2005
@@ -4,6 +4,7 @@
  * Talks to Xen Store to figure out what devices we have.
  *
  * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 XenSource Ltd.
  * 
  * This file may be distributed separately from the Linux kernel, or
  * incorporated into other software packages, subject to the following license:
@@ -33,6 +34,7 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <asm/semaphore.h>
+#include <asm-xen/xen-public/io/xenbus.h>
 #include <asm-xen/xen-public/io/xs_wire.h>
 
 /* Register callback to watch this node. */
@@ -47,27 +49,6 @@
        void (*callback)(struct xenbus_watch *,
                         const char **vec, unsigned int len);
 };
-
-
-/* The state of either end of the Xenbus, i.e. the current communication
-   status of initialisation across the bus.  States here imply nothing about
-   the state of the connection between the driver and the kernel's device
-   layers.  */
-typedef enum
-{
-  XenbusStateUnknown      = 0,
-  XenbusStateInitialising = 1,
-  XenbusStateInitWait     = 2,  /* Finished early initialisation, but waiting
-                                   for information from the peer or hotplug
-                                  scripts. */
-  XenbusStateInitialised  = 3,  /* Initialised and waiting for a connection
-                                  from the peer. */
-  XenbusStateConnected    = 4,
-  XenbusStateClosing      = 5,  /* The device is being closed due to an error
-                                  or an unplug event. */
-  XenbusStateClosed       = 6
-
-} XenbusState;
 
 
 /* A xenbus device. */
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/include/asm-xen/xencons.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xencons.h    Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xencons.h    Fri Dec  2 18:52:25 2005
@@ -4,4 +4,11 @@
 void xencons_force_flush(void);
 void xencons_resume(void);
 
+/* Interrupt work hooks. Receive data, or kick data out. */
+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
+void xencons_tx(void);
+
+int xencons_ring_init(void);
+int xencons_ring_send(const char *data, unsigned len);
+
 #endif /* __ASM_XENCONS_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c       Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/net/core/dev.c       Fri Dec  2 18:52:25 2005
@@ -1283,6 +1283,11 @@
                        skb->csum = offsetof(struct udphdr, check);
                        break;
                default:
+                       if (net_ratelimit())
+                               printk(KERN_ERR "Attempting to checksum a non-"
+                                      "TCP/UDP packet, dropping a protocol"
+                                      " %d packet", skb->nh.iph->protocol);
+                       rc = -EPROTO;
                        goto out_kfree_skb;
                }
                if ((skb->h.raw + skb->csum + 2) > skb->tail)
diff -r eae5812f33f1 -r 28bd01c9b596 patches/linux-2.6.12/pmd-shared.patch
--- a/patches/linux-2.6.12/pmd-shared.patch     Fri Dec  2 18:12:11 2005
+++ b/patches/linux-2.6.12/pmd-shared.patch     Fri Dec  2 18:52:25 2005
@@ -1,15 +1,3 @@
-diff -urNpP linux-2.6.12/arch/i386/mm/init.c 
linux-2.6.12.new/arch/i386/mm/init.c
---- linux-2.6.12/arch/i386/mm/init.c   2005-06-17 20:48:29.000000000 +0100
-+++ linux-2.6.12.new/arch/i386/mm/init.c       2005-07-11 16:28:09.778165582 
+0100
-@@ -634,7 +634,7 @@ void __init pgtable_cache_init(void)
-                               PTRS_PER_PGD*sizeof(pgd_t),
-                               0,
-                               pgd_ctor,
--                              PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
-+                              pgd_dtor);
-       if (!pgd_cache)
-               panic("pgtable_cache_init(): Cannot create pgd cache");
- }
 diff -urNpP linux-2.6.12/arch/i386/mm/pageattr.c 
linux-2.6.12.new/arch/i386/mm/pageattr.c
 --- linux-2.6.12/arch/i386/mm/pageattr.c       2005-06-17 20:48:29.000000000 
+0100
 +++ linux-2.6.12.new/arch/i386/mm/pageattr.c   2005-07-11 16:28:09.775165494 
+0100
@@ -23,72 +11,73 @@
  
        spin_lock_irqsave(&pgd_lock, flags);
 diff -urNpP linux-2.6.12/arch/i386/mm/pgtable.c 
linux-2.6.12.new/arch/i386/mm/pgtable.c
---- linux-2.6.12/arch/i386/mm/pgtable.c        2005-06-17 20:48:29.000000000 
+0100
-+++ linux-2.6.12.new/arch/i386/mm/pgtable.c    2005-07-11 16:32:01.478023726 
+0100
-@@ -199,14 +199,14 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
+--- linux-2.6.12/arch/i386/mm/pgtable.c        2005-11-26 09:55:10.000000000 
+0000
++++ linux-2.6.12.new/arch/i386/mm/pgtable.c    2005-11-26 10:20:36.000000000 
+0000
+@@ -199,19 +199,20 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
  {
        unsigned long flags;
  
 -      if (PTRS_PER_PMD == 1)
-+      if (!HAVE_SHARED_KERNEL_PMD)
++      if (PTRS_PER_PMD > 1) {
++              if (HAVE_SHARED_KERNEL_PMD)
++                      memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
++                             swapper_pg_dir + USER_PTRS_PER_PGD,
++                             (PTRS_PER_PGD - USER_PTRS_PER_PGD) * 
sizeof(pgd_t));
++      } else {
                spin_lock_irqsave(&pgd_lock, flags);
- 
-       memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
-                       swapper_pg_dir + USER_PTRS_PER_PGD,
-                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
- 
+-
+-      memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
+-                      swapper_pg_dir + USER_PTRS_PER_PGD,
+-                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+-
 -      if (PTRS_PER_PMD > 1)
-+      if (HAVE_SHARED_KERNEL_PMD)
-               return;
- 
-       pgd_list_add(pgd);
-@@ -214,11 +214,13 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
-       memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
+-              return;
+-
+-      pgd_list_add(pgd);
+-      spin_unlock_irqrestore(&pgd_lock, flags);
+-      memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++              memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
++                     swapper_pg_dir + USER_PTRS_PER_PGD,
++                     (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++              memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++              pgd_list_add(pgd);
++              spin_unlock_irqrestore(&pgd_lock, flags);
++      }
  }
  
--/* never called when PTRS_PER_PMD > 1 */
- void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
- {
-       unsigned long flags; /* can be called from interrupt context */
- 
-+      if (HAVE_SHARED_KERNEL_PMD)
-+              return;
+ /* never called when PTRS_PER_PMD > 1 */
+@@ -238,6 +239,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+                       goto out_oom;
+               set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
+       }
 +
-       spin_lock_irqsave(&pgd_lock, flags);
-       pgd_list_del(pgd);
-       spin_unlock_irqrestore(&pgd_lock, flags);
-@@ -226,12 +228,29 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
- 
- pgd_t *pgd_alloc(struct mm_struct *mm)
- {
--      int i;
-+      int i = 0;
-       pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
- 
-       if (PTRS_PER_PMD == 1 || !pgd)
-               return pgd;
- 
 +      if (!HAVE_SHARED_KERNEL_PMD) {
-+              /* alloc and copy kernel pmd */
 +              unsigned long flags;
-+              pgd_t *copy_pgd = pgd_offset_k(PAGE_OFFSET);
-+              pud_t *copy_pud = pud_offset(copy_pgd, PAGE_OFFSET);
-+              pmd_t *copy_pmd = pmd_offset(copy_pud, PAGE_OFFSET);
-+              pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-+              if (0 == pmd)
-+                      goto out_oom;
++
++              for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
++                      pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
++                      if (!pmd)
++                              goto out_oom;
++                      set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
++              }
 +
 +              spin_lock_irqsave(&pgd_lock, flags);
-+              memcpy(pmd, copy_pmd, PAGE_SIZE);
++              for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
++                      unsigned long v = (unsigned long)i << PGDIR_SHIFT;
++                      pgd_t *kpgd = pgd_offset_k(v);
++                      pud_t *kpud = pud_offset(kpgd, v);
++                      pmd_t *kpmd = pmd_offset(kpud, v);
++                      pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
++                      memcpy(pmd, kpmd, PAGE_SIZE);
++              }
++              pgd_list_add(pgd);
 +              spin_unlock_irqrestore(&pgd_lock, flags);
-+              set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
 +      }
 +
-+      /* alloc user pmds */
-       for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
-               pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-               if (!pmd)
-@@ -252,9 +271,16 @@ void pgd_free(pgd_t *pgd)
+       return pgd;
+ 
+ out_oom:
+@@ -252,9 +277,23 @@ void pgd_free(pgd_t *pgd)
        int i;
  
        /* in the PAE case user pgd entries are overwritten before usage */
@@ -101,8 +90,15 @@
 +                      kmem_cache_free(pmd_cache, pmd);
 +              }
 +              if (!HAVE_SHARED_KERNEL_PMD) {
-+                      pmd_t *pmd = (void 
*)__va(pgd_val(pgd[USER_PTRS_PER_PGD])-1);
-+                      kmem_cache_free(pmd_cache, pmd);
++                      unsigned long flags;
++                      spin_lock_irqsave(&pgd_lock, flags);
++                      pgd_list_del(pgd);
++                      spin_unlock_irqrestore(&pgd_lock, flags);
++                      for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
++                              pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
++                              memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
++                              kmem_cache_free(pmd_cache, pmd);
++                      }
 +              }
 +      }
        /* in the non-PAE case, free_pgtables() clears user pgd entries */
diff -r eae5812f33f1 -r 28bd01c9b596 tools/Rules.mk
--- a/tools/Rules.mk    Fri Dec  2 18:12:11 2005
+++ b/tools/Rules.mk    Fri Dec  2 18:52:25 2005
@@ -1,4 +1,7 @@
 #  -*- mode: Makefile; -*-
+
+# `all' is the default target
+all:
 
 include $(XEN_ROOT)/Config.mk
 
@@ -27,3 +30,13 @@
 
 %.o: %.cc
        $(CC) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
+
+mk-symlinks: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
+mk-symlinks:
+       mkdir -p xen
+       ( cd xen && ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
+       mkdir -p xen/io
+       ( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
+       mkdir -p xen/linux
+       ( cd xen/linux && \
+         ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
diff -r eae5812f33f1 -r 28bd01c9b596 tools/blktap/Makefile
--- a/tools/blktap/Makefile     Fri Dec  2 18:12:11 2005
+++ b/tools/blktap/Makefile     Fri Dec  2 18:52:25 2005
@@ -47,17 +47,6 @@
                $(MAKE) -C $$subdir $@;       \
        done
 
-LINUX_ROOT := $(wildcard $(XEN_ROOT)/linux-2.6.*-xen-sparse)
-mk-symlinks:
-       [ -e xen/linux ] || mkdir -p xen/linux
-       [ -e xen/io ]    || mkdir -p xen/io
-       ( cd xen >/dev/null ; \
-         ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
-       ( cd xen/io >/dev/null ; \
-          ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
-       ( cd xen/linux >/dev/null ; \
-         ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
-
 install: all
        $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
        $(INSTALL_DIR) -p $(DESTDIR)/usr/include
diff -r eae5812f33f1 -r 28bd01c9b596 tools/blktap/blkdump.c
--- a/tools/blktap/blkdump.c    Fri Dec  2 18:12:11 2005
+++ b/tools/blktap/blkdump.c    Fri Dec  2 18:52:25 2005
@@ -11,7 +11,6 @@
 int request_print(blkif_request_t *req)
 {
     int i;
-    unsigned long fas;
     
     if ( (req->operation == BLKIF_OP_READ) ||
          (req->operation == BLKIF_OP_WRITE) )
@@ -24,12 +23,10 @@
         
         
         for (i=0; i < req->nr_segments; i++) {
-            fas = req->frame_and_sects[i];
-            printf("              (pf: 0x%8lx start: %lu stop: %lu)\n",
-                    (fas & PAGE_MASK),
-                    blkif_first_sect(fas),
-                    blkif_last_sect(fas)
-                    );
+            printf("              (gref: 0x%8x start: %u stop: %u)\n",
+                   req->seg[i].gref,
+                   req->seg[i].first_sect,
+                   req->seg[i].last_sect);
         }
             
     } else {
diff -r eae5812f33f1 -r 28bd01c9b596 tools/blktap/blktaplib.c
--- a/tools/blktap/blktaplib.c  Fri Dec  2 18:12:11 2005
+++ b/tools/blktap/blktaplib.c  Fri Dec  2 18:52:25 2005
@@ -244,8 +244,8 @@
     RING_IDX          rp, i, pfd_count; 
     
     /* pending rings */
-    blkif_request_t req_pending[BLKIF_RING_SIZE];
-    /* blkif_response_t rsp_pending[BLKIF_RING_SIZE] */;
+    blkif_request_t req_pending[BLK_RING_SIZE];
+    /* blkif_response_t rsp_pending[BLK_RING_SIZE] */;
     
     /* handler hooks: */
     request_hook_t   *req_hook;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/blktap/blktaplib.h
--- a/tools/blktap/blktaplib.h  Fri Dec  2 18:12:11 2005
+++ b/tools/blktap/blktaplib.h  Fri Dec  2 18:52:25 2005
@@ -18,11 +18,13 @@
 #include <xen/io/domain_controller.h>
 #include <xs.h>
 
+#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
+
 /* /dev/xen/blktap resides at device number major=10, minor=202        */ 
 #define BLKTAP_MINOR 202
 
 /* size of the extra VMA area to map in attached pages. */
-#define BLKTAP_VMA_PAGES BLKIF_RING_SIZE
+#define BLKTAP_VMA_PAGES BLK_RING_SIZE
 
 /* blktap IOCTLs:                                                      */
 #define BLKTAP_IOCTL_KICK_FE         1
diff -r eae5812f33f1 -r 28bd01c9b596 tools/blktap/parallax/parallax.c
--- a/tools/blktap/parallax/parallax.c  Fri Dec  2 18:12:11 2005
+++ b/tools/blktap/parallax/parallax.c  Fri Dec  2 18:52:25 2005
@@ -280,8 +280,7 @@
       goto err;
 
     /* Make sure the buffer is page-sized. */
-    if ( (blkif_first_sect(req->frame_and_sects[0]) != 0) ||
-       (blkif_last_sect (req->frame_and_sects[0]) != 7) )
+    if ( (req->seg[0].first_sect != 0) || (req->seg[0].last_sect != 7) )
       goto err;
 
     /* fill the list of devices */
@@ -350,17 +349,16 @@
     /* Calculate read size and offset within the read block. */
 
     offset = (param->sector << SECTOR_SHIFT) % BLOCK_SIZE;
-    size = ( blkif_last_sect (req->frame_and_sects[segment]) -
-             blkif_first_sect(req->frame_and_sects[segment]) + 1
-        ) << SECTOR_SHIFT;
-    start = blkif_first_sect(req->frame_and_sects[segment]) 
-        << SECTOR_SHIFT;
+    size = (req->seg[segment].last_sect - req->seg[segment].first_sect + 1) <<
+        SECTOR_SHIFT;
+    start = req->seg[segment].first_sect << SECTOR_SHIFT;
 
     DPRINTF("ParallaxRead: sect: %lld (%ld,%ld),  "
             "vblock %llx, "
             "size %lx\n", 
-            param->sector, blkif_first_sect(p->req->frame_and_sects[segment]),
-            blkif_last_sect (p->req->frame_and_sects[segment]),
+            param->sector,
+            p->req->seg[segment].first_sect,
+            p->req->seg[segment].last_sect,
             param->vblock, size); 
 
     memcpy(dpage + start, spage + offset, size);
@@ -506,16 +504,15 @@
         /* Calculate read size and offset within the read block. */
         
         offset = (sector << SECTOR_SHIFT) % BLOCK_SIZE;
-        size = ( blkif_last_sect (req->frame_and_sects[i]) -
-                 blkif_first_sect(req->frame_and_sects[i]) + 1
-            ) << SECTOR_SHIFT;
-        start = blkif_first_sect(req->frame_and_sects[i]) << SECTOR_SHIFT;
+        size = (req->seg[i].last_sect - req->seg[i].first_sect + 1) <<
+            SECTOR_SHIFT;
+        start = req->seg[i].first_sect << SECTOR_SHIFT;
 
         DPRINTF("ParallaxWrite: sect: %lld (%ld,%ld),  "
                 "vblock %llx, gblock %llx, "
                 "size %lx\n", 
-                sector, blkif_first_sect(req->frame_and_sects[i]),
-                blkif_last_sect (req->frame_and_sects[i]),
+                sector, 
+                req->seg[i].first_sect, req->seg[i].last_sect,
                 vblock, gblock, size); 
       
         /* XXX: For now we just freak out if they try to write a   */
diff -r eae5812f33f1 -r 28bd01c9b596 tools/blktap/ublkback/ublkbacklib.c
--- a/tools/blktap/ublkback/ublkbacklib.c       Fri Dec  2 18:12:11 2005
+++ b/tools/blktap/ublkback/ublkbacklib.c       Fri Dec  2 18:52:25 2005
@@ -233,8 +233,7 @@
     case BLKIF_OP_WRITE:
     {
         unsigned long size;
-        
-        
+
         batch_count++;
 
         idx = ID_TO_IDX(req->id);
@@ -247,18 +246,17 @@
             
             sector = req->sector_number + (8*i);
             
-            size = blkif_last_sect (req->frame_and_sects[i]) -
-                   blkif_first_sect(req->frame_and_sects[i]) + 1;
-            
-            if (blkif_first_sect(req->frame_and_sects[i]) != 0)
-            DPRINTF("iWR: sec_nr: %10llu sec: %10llu (%1lu,%1lu) pos: %15lu\n",
-                    req->sector_number, sector, 
-                    blkif_first_sect(req->frame_and_sects[i]),
-                    blkif_last_sect (req->frame_and_sects[i]),
-                    (long)(sector << SECTOR_SHIFT));
+            size = req->seg[i].last_sect - req->seg[i].first_sect + 1;
+            
+            if (req->seg[i].first_sect != 0)
+                DPRINTF("iWR: sec_nr: %10llu sec: %10llu (%1lu,%1lu) "
+                        "pos: %15lu\n",
+                        req->sector_number, sector, 
+                        req->seg[i].first_sect, req->seg[i].last_sect,
+                        (long)(sector << SECTOR_SHIFT));
                         
             spage  = (char *)MMAP_VADDR(ID_TO_IDX(req->id), i);
-            spage += blkif_first_sect(req->frame_and_sects[i]) << SECTOR_SHIFT;
+            spage += req->seg[i].first_sect << SECTOR_SHIFT;
             
             /*convert size and sector to byte offsets */
             size   <<= SECTOR_SHIFT;
@@ -297,19 +295,17 @@
             
             sector  = req->sector_number + (8*i);
             
-            size = blkif_last_sect (req->frame_and_sects[i]) -
-                   blkif_first_sect(req->frame_and_sects[i]) + 1;
-            
+            size = req->seg[i].last_sect - req->seg[i].first_sect + 1;
+
             dpage  = (char *)MMAP_VADDR(ID_TO_IDX(req->id), i);
-            dpage += blkif_first_sect(req->frame_and_sects[i]) << SECTOR_SHIFT;
-            
-            if (blkif_first_sect(req->frame_and_sects[i]) != 0)
-            DPRINTF("iRD : sec_nr: %10llu sec: %10llu (%1lu,%1lu) "
-                    "pos: %15lu dpage: %p\n", 
-                    req->sector_number, sector, 
-                    blkif_first_sect(req->frame_and_sects[i]),
-                    blkif_last_sect (req->frame_and_sects[i]),
-                    (long)(sector << SECTOR_SHIFT), dpage);
+            dpage += req->seg[i].first_sect << SECTOR_SHIFT;
+            
+            if (req->seg[i].first_sect != 0)
+                DPRINTF("iRD : sec_nr: %10llu sec: %10llu (%1lu,%1lu) "
+                        "pos: %15lu dpage: %p\n", 
+                        req->sector_number, sector, 
+                        req->seg[i].first_sect, req->seg[i].last_sect,
+                        (long)(sector << SECTOR_SHIFT), dpage);
             
             /*convert size and sector to byte offsets */
             size   <<= SECTOR_SHIFT;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/check/check_hotplug
--- a/tools/check/check_hotplug Fri Dec  2 18:12:11 2005
+++ b/tools/check/check_hotplug Fri Dec  2 18:52:25 2005
@@ -6,8 +6,10 @@
    echo '  *** Check for the hotplug scripts (hotplug) FAILED'
    exit 1
 }
+[ -x "$(which udevinfo)" ] && \
+  UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* 
\([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
 
-if [ -x /sbin/udev ] && [ ! -z `/sbin/udev -V` ] && [ `/sbin/udev -V` -ge 059 
]; then
+if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
   exit 0
 fi
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Fri Dec  2 18:12:11 2005
+++ b/tools/console/daemon/io.c Fri Dec  2 18:52:25 2005
@@ -62,7 +62,7 @@
        struct domain *next;
        char *conspath;
        int ring_ref;
-       int local_port;
+       evtchn_port_t local_port;
        int evtchn_fd;
        struct xencons_interface *interface;
 };
@@ -376,9 +376,6 @@
 
 static void cleanup_domain(struct domain *d)
 {
-       if (!buffer_empty(&d->buffer))
-               return;
-
        if (d->tty_fd != -1) {
                close(d->tty_fd);
                d->tty_fd = -1;
@@ -491,7 +488,7 @@
 
 static void handle_ring_read(struct domain *dom)
 {
-       uint16_t v;
+       evtchn_port_t v;
 
        if (!read_sync(dom->evtchn_fd, &v, sizeof(v)))
                return;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/Makefile
--- a/tools/examples/Makefile   Fri Dec  2 18:12:11 2005
+++ b/tools/examples/Makefile   Fri Dec  2 18:52:25 2005
@@ -26,9 +26,10 @@
 XEN_SCRIPTS += network-nat vif-nat
 XEN_SCRIPTS += block
 XEN_SCRIPTS += block-enbd block-nbd
+XEN_SCRIPTS += vtpm
 XEN_SCRIPT_DATA = xen-script-common.sh
 XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
-XEN_SCRIPT_DATA += block-common.sh
+XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh
 
 XEN_HOTPLUG_DIR = /etc/hotplug
 XEN_HOTPLUG_SCRIPTS = xen-backend.agent
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/block
--- a/tools/examples/block      Fri Dec  2 18:12:11 2005
+++ b/tools/examples/block      Fri Dec  2 18:52:25 2005
@@ -2,12 +2,6 @@
 
 dir=$(dirname "$0")
 . "$dir/block-common.sh"
-
-case "$command" in
-    online | offline)
-        exit 0
-        ;;
-esac
 
 expand_dev() {
   local dev
@@ -22,27 +16,287 @@
   echo -n $dev
 }
 
-t=$(xenstore_read_default "$XENBUS_PATH"/type "MISSING")
-
-case "$command" in 
+
+##
+# canonicalise_mode mode
+#
+# Takes the given mode, which may be r, w, ro, rw, w!, or rw!, or variations
+# thereof, and canonicalises them to one of
+#
+#   'r': perform checks for a new read-only mount;
+#   'w': perform checks for a read-write mount; or
+#   '!': perform no checks at all.
+#
+canonicalise_mode()
+{
+  local mode="$1"
+
+  if ! expr index "$mode" 'w' >/dev/null
+  then
+    echo 'r'
+  elif ! expr index "$mode" '!' >/dev/null
+  then
+    echo 'w'
+  else
+    echo '!'
+  fi
+}
+
+
+##
+# check_sharing device mode
+#
+# Check whether the device requested is already in use.  To use the device in
+# read-only mode, it may be in use in read-only mode, but may not be in use in
+# read-write anywhere at all.  To use the device in read-write mode, it must
+# not be in use anywhere at all.
+#
+# Prints one of
+#
+#    'local': the device may not be used because it is mounted in the current
+#             (i.e. the privileged domain) in a way incompatible with the
+#             requested mode;
+#    'guest': the device may not be used because it already mounted by a guest
+#             in a way incompatible with the requested mode; or
+#    'ok':    the device may be used.
+#
+check_sharing()
+{
+  local dev="$1"
+  local mode="$2"
+
+  local devmm=$(device_major_minor "$dev")
+  local file
+
+  if [ "$mode" == 'w' ]
+  then
+    toskip="^$"
+  else
+    toskip="^[^ ]* [^ ]* [^ ]* ro "
+  fi
+
+  for file in $(cat /proc/mounts | grep -v "$toskip" | cut -f 1 -d ' ')
+  do
+    if [ -e "$file" ]
+    then
+      local d=$(device_major_minor "$file")
+
+      if [ "$d" == "$devmm" ]
+      then
+        echo 'local'
+        return
+      fi
+    fi
+  done
+
+##
+## XXX SMH: the below causes live migration on localhost to fail sometimes
+## since the source domain may still appear to be using a local device. 
+## For now simply comment it out - a proper fix will come in due course. 
+
+#   for file in /sys/devices/xen-backend/*/physical_device
+#   do
+#     if [ -e "$file" ] # Cope with no devices, i.e. the * above did not 
expand.
+#     then
+#       local d=$(cat "$file")
+#       if [ "$d" == "$devmm" ]
+#       then
+#         if [ "$mode" == 'w' ]
+#         then
+#           echo 'guest'
+#           return
+#         else
+#           local m=$(cat "${file/physical_device/mode}")
+
+#           if expr index "$m" 'w' >/dev/null
+#           then
+#             echo 'guest'
+#             return
+#           fi
+#         fi
+#       fi
+#     fi
+#   done
+
+  echo 'ok'
+}
+
+
+##
+# check_device_sharing dev mode
+#
+# Perform the sharing check for the given physical device and mode.
+#
+check_device_sharing()
+{
+  local dev="$1"
+  local mode=$(canonicalise_mode "$2")
+  local result
+
+  if [ "$mode" == '!' ]
+  then
+    return 0
+  fi
+
+  result=$(check_sharing "$dev" "$mode")
+
+  if [ "$result" != 'ok' ]
+  then
+    do_ebusy "Device $dev is mounted " "$mode" "$result"
+  fi
+}
+
+
+##
+# check_device_sharing file dev mode
+#
+# Perform the sharing check for the given file mounted through the given
+# loopback interface, in the given mode.
+#
+check_file_sharing()
+{
+  local file="$1"
+  local dev="$2"
+  local mode="$3"
+
+  result=$(check_sharing "$dev" "$mode")
+
+  if [ "$result" != 'ok' ]
+  then
+    do_ebusy "File $file is loopback-mounted through $dev,
+which is mounted " "$mode" "$result"
+  fi
+}
+
+
+##
+# do_ebusy prefix mode result
+#
+# Helper function for check_device_sharing check_file_sharing, calling ebusy
+# with an error message constructed from the given prefix, mode, and result
+# from a call to check_sharing.
+#
+do_ebusy()
+{
+  local prefix="$1"
+  local mode="$2"
+  local result="$3"
+
+  if [ "$result" == 'guest' ]
+  then
+    dom='a guest '
+    when='now'
+  else
+    dom='the privileged '
+    when='by a guest'
+  fi
+
+  if [ "$mode" == 'w' ]
+  then
+    m1=''
+    m2=''
+  else
+    m1='read-write '
+    m2='read-only '
+  fi
+
+  ebusy \
+"${prefix}${m1}in ${dom}domain,
+and so cannot be mounted ${m2}${when}."
+}
+
+
+t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
+
+case "$command" in
   add)
-    p=$(xenstore_read "$XENBUS_PATH"/params)
+    phys=$(xenstore_read_default "$XENBUS_PATH/physical-device" 'MISSING')
+    if [ "$phys" != 'MISSING' ]
+    then
+      # Depending upon the hotplug configuration, it is possible for this
+      # script to be called twice, so just bail.
+      exit 0
+    fi
+
+    p=$(xenstore_read "$XENBUS_PATH/params")
+    mode=$(xenstore_read "$XENBUS_PATH/mode")
+
     case $t in 
       phy)
         dev=$(expand_dev $p)
+        check_device_sharing "$dev" "$mode"
        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"
+        # Canonicalise the file, for sharing check comparison, and the mode
+        # for ease of use here.
+        file=$(readlink -f "$p")
+        mode=$(canonicalise_mode "$mode")
+
+        if [ "$mode" == 'w' ] && ! stat "$file" -c %A | grep -q w
+        then
+          ebusy \
+"File $file is read-only, and so I will not
+mount it read-write in a guest domain."
+        fi
+
+
+       while true
+        do 
+          loopdev=''
+          for dev in /dev/loop*
+          do
+            if [ ! -b "$dev" ]
+            then
+              continue
+            fi
+
+            f=$(losetup "$dev" 2>/dev/null) || f='()'
+            f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g')
+
+            log err "$file $f $dev"
+
+            if [ "$f" ]
+            then
+              # $dev is in use.  Check sharing.
+              if [ "$mode" == '!' ]
+              then
+                continue
+              fi
+
+              f=$(readlink -f "$f")
+
+              if [ "$f" == "$file" ]
+              then
+                check_file_sharing "$file" "$dev" "$mode"
+              fi
+            else
+              # $dev is not in use, so we'll remember it for use later; we want
+              # to finish the sharing check first.
+              
+              if [ "$loopdev" == '' ]
+              then
+                loopdev="$dev"
+              fi
+            fi
+          done
+
+          if [ "$loopdev" == '' ]
+          then
+            fatal 'Failed to find an unused loop device'
+          fi
+          if losetup "$loopdev" "$file"
+          then
+           log err "mapped $file using $loopdev"
+            xenstore_write "$XENBUS_PATH/node" "$loopdev"
+            write_dev "$loopdev"
             exit 0
-         fi
+          else
+            log err "losetup $loopdev $file failed, retry"
+          fi
        done
-       exit 1
        ;;
     esac
     ;;
@@ -54,8 +308,8 @@
        ;;
 
       file)
-        node=$(xenstore_read "$XENBUS_PATH"/node)
-       losetup -d $node
+        node=$(xenstore_read "$XENBUS_PATH/node")
+       losetup -d "$node"
        exit 0
        ;;
     esac
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/block-common.sh
--- a/tools/examples/block-common.sh    Fri Dec  2 18:12:11 2005
+++ b/tools/examples/block-common.sh    Fri Dec  2 18:52:25 2005
@@ -21,9 +21,7 @@
 
 findCommand "$@"
 
-if [ "$command" != "online" ]  &&
-   [ "$command" != "offline" ] &&
-   [ "$command" != "add" ]     &&
+if [ "$command" != "add" ] &&
    [ "$command" != "remove" ]
 then
   log err "Invalid command: $command"
@@ -34,28 +32,42 @@
 XENBUS_PATH="${XENBUS_PATH:?}"
 
 
+ebusy()
+{
+  xenstore_write "$XENBUS_PATH/hotplug-error" "$*" \
+                 "$XENBUS_PATH/hotplug-status" busy
+  log err "$@"
+  exit 1
+}
+
+
 ##
-# Write physical-device = 0xMMmm and node = device to the store, where MM
-# and mm are the major and minor numbers of device.
+# Print the given device's major and minor numbers, written in hex and
+# separated by a colon.
+device_major_minor()
+{
+  stat -L -c %t:%T "$1"
+}
+
+
+##
+# Write physical-device = MM,mm to the store, where MM and mm are the major 
+# and minor numbers of device respectively.
 #
 # @param device The device from which major and minor numbers are read, which
 #               will be written into the store.
 #
 write_dev() {
-  local major
-  local minor
-  local pdev
+  local mm
   
-  major=$(stat -L -c %t "$1")
-  minor=$(stat -L -c %T "$1")
+  mm=$(device_major_minor "$1")
  
-  if [ -z $major  -o -z $minor ]; then
+  if [ -z $mm ]
+  then
     fatal "Backend device does not exist"
   fi
  
-  pdev=$(printf "0x%02x%02x" "0x$major" "0x$minor")
-  xenstore_write "$XENBUS_PATH"/physical-device "$pdev" \
-                 "$XENBUS_PATH"/node "$1"
+  xenstore_write "$XENBUS_PATH/physical-device" "$mm"
 
   success
 }
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/block-enbd
--- a/tools/examples/block-enbd Fri Dec  2 18:12:11 2005
+++ b/tools/examples/block-enbd Fri Dec  2 18:52:25 2005
@@ -11,7 +11,7 @@
 . "$dir/block-common.sh"
 
 case "$command" in
-  bind)
+  add)
     for dev in /dev/nd*; do
       if nbd-client $2:$3 $dev; then
         write_dev $dev
@@ -20,7 +20,7 @@
     done
     exit 1
     ;;
-  unbind)
+  remove)
     nbd-client -d $2
     exit 0
     ;;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/block-nbd
--- a/tools/examples/block-nbd  Fri Dec  2 18:12:11 2005
+++ b/tools/examples/block-nbd  Fri Dec  2 18:52:25 2005
@@ -11,7 +11,7 @@
 . "$dir/block-common.sh"
 
 case "$command" in
-  bind)
+  add)
     for dev in /dev/nbd*; do
       if nbd-client $2 $3 $dev; then
         write_dev $dev
@@ -20,7 +20,7 @@
     done
     exit 1
     ;;
-  unbind)
+  remove)
     nbd-client -d $2
     exit 0
     ;;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/network-nat
--- a/tools/examples/network-nat        Fri Dec  2 18:12:11 2005
+++ b/tools/examples/network-nat        Fri Dec  2 18:52:25 2005
@@ -13,35 +13,69 @@
 #
 # netdev     The gateway interface (default eth0).
 # antispoof  Whether to use iptables to prevent spoofing (default no).
+# dhcp       Whether to alter the local DHCP configuration (default no).
 #
 #============================================================================
 
+dir=$(dirname "$0")
+. "$dir/xen-script-common.sh"
+. "$dir/xen-network-common.sh"
 
-
-# Exit if anything goes wrong.
-set -e 
-
-# First arg is the operation.
-OP=$1
-shift
-
-# Pull variables in args in to environment.
-for arg ; do export "${arg}" ; done
+findCommand "$@"
+evalVariables "$@"
 
 netdev=${netdev:-eth0}
 # antispoofing not yet implemented
 antispoof=${antispoof:-no}
+dhcp=${dhcp:-no}
 
-echo "*network-nat $OP netdev=$netdev antispoof=$antispoof" >&2
+if [ "$dhcp" != 'no' ]
+then
+  dhcpd_conf_file=$(find_dhcpd_conf_file)
+  dhcpd_init_file=$(find_dhcpd_init_file)
+  if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ]
+  then
+    echo 'Failed to find dhcpd configuration or init file.' >&2
+    exit 1
+  fi
+fi
+
+
+function dhcp_start()
+{
+  if ! grep -q "subnet 10.0.0.0" "$dhcpd_conf_file"
+  then
+    echo >>"$dhcpd_conf_file" "subnet 10.0.0.0 netmask 255.255.0.0 {}"
+  fi
+
+  "$dhcpd_init_file" restart
+}
+
+
+function dhcp_stop()
+{
+  local tmpfile=$(mktemp)
+  grep -v "subnet 10.0.0.0" "$dhcpd_conf_file" >"$tmpfile"
+  if diff "$tmpfile" "$dhcpd_conf_file" >&/dev/null
+  then
+    rm "$tmpfile"
+  else
+    mv "$tmpfile" "$dhcpd_conf_file"
+  fi
+
+  "$dhcpd_init_file" restart
+}
 
 
 op_start() {
        echo 1 >/proc/sys/net/ipv4/ip_forward
        iptables -t nat -A POSTROUTING -o ${netdev} -j MASQUERADE
+        [ "$dhcp" != 'no' ] && dhcp_start
 }
 
 
 op_stop() {
+        [ "$dhcp" != 'no' ] && dhcp_stop
        iptables -t nat -D POSTROUTING -o ${netdev} -j MASQUERADE
 }
 
@@ -57,7 +91,7 @@
 
 }
 
-case ${OP} in
+case "$command" in
     start)
         op_start
         ;;
@@ -71,7 +105,7 @@
        ;;
 
     *)
-       echo 'Unknown command: ' ${OP} >&2
+       echo "Unknown command: $command" >&2
        echo 'Valid commands are: start, stop, status' >&2
        exit 1
 esac
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Fri Dec  2 18:12:11 2005
+++ b/tools/examples/vif-bridge Fri Dec  2 18:52:25 2005
@@ -48,9 +48,9 @@
 
 case "$command" in
     online)
-        if brctl show "$bridge" | grep "$vif" >&/dev/null
+        if brctl show | grep -q "$vif"
         then
-          log debug "$vif already attached to $bridge"
+          log debug "$vif already attached to a bridge"
           exit 0
         fi
 
@@ -61,12 +61,16 @@
         ;;
 
     offline)
-        # vifs are auto-removed from bridge.
-        ifconfig "$vif" down || fatal "ifconfig $vif down failed"
+        brctl delif "$bridge" "$vif" ||
+          log debug "brctl delif $bridge $vif failed"
+        ifconfig "$vif" down || log debug "ifconfig $vif down failed"
         ;;
 esac
 
 handle_iptable
 
-log debug "Successful vif-bridge operation for $vif, bridge $bridge."
-success
+log debug "Successful vif-bridge $command for $vif, bridge $bridge."
+if [ "$command" == "online" ]
+then
+  success
+fi
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/vif-common.sh
--- a/tools/examples/vif-common.sh      Fri Dec  2 18:12:11 2005
+++ b/tools/examples/vif-common.sh      Fri Dec  2 18:52:25 2005
@@ -63,6 +63,7 @@
   fi
 
   iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT ||
+    [ "$c" == "-D" ] ||
     log err \
      "iptables $c FORWARD -m physdev --physdev-in $vif $@ -j ACCEPT failed.
 If you are using iptables, this may affect networking for guest domains."
@@ -82,7 +83,7 @@
   # binary is not sufficient, because the user may not have the appropriate
   # modules installed.  If iptables is not working, then there's no need to do
   # anything with it, so we can just return.
-  if ! iptables -L >&/dev/null
+  if ! iptables -L -n >&/dev/null
   then
     return
   fi
@@ -102,3 +103,37 @@
       frob_iptable
   fi
 }
+
+
+##
+# ip_of interface
+#
+# Print the IP address currently in use at the given interface, or nothing if
+# the interface is not up.
+#
+function ip_of()
+{
+  ip addr show "$1" | sed -n 's/^.*inet \([0-9.]*\).*$/\1/p'
+}
+
+
+##
+# dom0_ip
+#
+# Print the IP address of the interface in dom0 through which we are routing.
+# This is the IP address on the interface specified as "netdev" as a parameter
+# to these scripts, or eth0 by default.  This function will call fatal if no
+# such interface could be found.
+#
+function dom0_ip()
+{
+  local nd=${netdev:-eth0}
+  local result=$(ip_of "$nd")
+  if [ -z "$result" ]
+  then
+      fatal
+"$netdev is not up.  Bring it up or specify another interface with " \
+"netdev=<if> as a parameter to $0."
+  fi
+  echo "$result"
+}
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/vif-nat
--- a/tools/examples/vif-nat    Fri Dec  2 18:12:11 2005
+++ b/tools/examples/vif-nat    Fri Dec  2 18:52:25 2005
@@ -15,44 +15,146 @@
 # vif         vif interface name (required).
 # XENBUS_PATH path to this device's details in the XenStore (required).
 #
+# Parameters:
+# dhcp        Whether to alter the local DHCP configuration to include this
+#             new host (default no).
+#
 # Read from the store:
 # ip      list of IP networks for the vif, space-separated (default given in
 #         this script).
 #============================================================================
 
+
 dir=$(dirname "$0")
 . "$dir/vif-common.sh"
 
+dhcp=${dhcp:-no}
+
+if [ "$dhcp" != 'no' ]
+then
+  dhcpd_conf_file=$(find_dhcpd_conf_file)
+  dhcpd_init_file=$(find_dhcpd_init_file)
+  if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ]
+  then
+    echo 'Failed to find dhcpd configuration or init file.' >&2
+    exit 1
+  fi
+fi
+
+
+ip_from_dom()
+{
+  local domid=$(echo "$XENBUS_PATH" | sed -n 's#.*/\([0-9]*\)/[0-9]*$#\1#p')
+  local vifid=$(echo "$XENBUS_PATH" | sed -n 's#.*/[0-9]*/\([0-9]*\)$#\1#p')
+
+  local domid1=$(( $domid / 256 ))
+  local domid2=$(( $domid % 256 ))
+  vifid=$(( $vifid + 1 ))
+
+  echo "10.$domid1.$domid2.$vifid/16"
+}
+
+
+routing_ip()
+{
+  echo $(echo $1 | awk -F. '{print $1"."$2"."$3"."$4 + 127}')
+}
+
+
+dotted_quad()
+{
+ echo\
+ $(( ($1 & 0xFF000000) >> 24))\
+.$(( ($1 & 0x00FF0000) >> 16))\
+.$(( ($1 & 0x0000FF00) >> 8 ))\
+.$((  $1 & 0x000000FF       ))
+}
+
+
 if [ "$ip" == "" ]
 then
-  ip='169.254.1.1/24'
+  ip=$(ip_from_dom)
 fi
 
-#determine ip address and netmask 
+router_ip=$(routing_ip "$ip")
+
+# Split the given IP/bits pair.
 vif_ip=`echo ${ip} | awk -F/ '{print $1}'`
 bits=`echo ${ip} | awk -F/ '{print $2}'`
-intmask=$(( ((0xFFFFFFFF << ((32 - $bits)))) & 0xFFFFFFFF ))
-netmask=$(( (($intmask & 0xFF000000)) >> 24 ))
-netmask=$netmask.$(( (($intmask & 0x00FF0000)) >> 16 ))
-netmask=$netmask.$(( (($intmask & 0x0000FF00)) >> 8 ))
-netmask=$netmask.$(( $intmask & 0x000000FF ))
 
-main_ip=$(ip addr show eth0 | sed -e '/inet /!d;s/^.*inet \([^\s*]\)\s.*$/\1/')
+# Convert $bits and $vif_ip to integers, mask appropriately to get a network
+# address, and convert them both to dotted quads.
+
+intmask=$(( (0xFFFFFFFF << (32 - $bits)) & 0xFFFFFFFF ))
+vif_int=$(( $(echo "((($vif_ip" | sed -e 's#\.#)\*256\+#g') ))
+
+netmask=$(dotted_quad $intmask)
+network=$(dotted_quad $(( $vif_int & $intmask )) )
+
+main_ip=$(dom0_ip)
+
+
+dhcp_remove_entry()
+{
+  local tmpfile=$(mktemp)
+  grep -v "host Xen-${vif/./-}" "$dhcpd_conf_file" >"$tmpfile"
+  if diff "$tmpfile" "$dhcpd_conf_file" >/dev/null
+  then
+    rm "$tmpfile"
+  else
+    mv "$tmpfile" "$dhcpd_conf_file"
+  fi
+}
+
+
+dhcp_up()
+{
+  dhcp_remove_entry
+  mac=$(xenstore_read "$XENBUS_PATH/mac")
+  echo >>"$dhcpd_conf_file" \
+"host Xen-${vif/./-} { hardware ethernet $mac; fixed-address $vif_ip; option 
routers $router_ip; }"
+
+  "$dhcpd_init_file" restart
+}
+
+
+dhcp_down()
+{
+  dhcp_remove_entry
+  "$dhcpd_init_file" restart || true # We need to ignore failure because
+                                     # ISC dhcpd 3 borks if there is nothing
+                                     # for it to do, which is the case if
+                                     # the outgoing interface is not
+                                     # configured to offer leases and there
+                                     # are no vifs.
+}
+
 
 case "$command" in
     online)
-        ifconfig ${vif} ${vif_ip} netmask ${netmask} up
+        if ip route | grep -q "dev $vif"
+        then
+          log debug "$vif already up"
+          exit 0
+        fi
+
+        do_or_die ip link set "$vif" up arp on
+        do_or_die ip addr add "$router_ip" dev "$vif"
+        do_or_die ip route add "$vif_ip" dev "$vif" src "$main_ip"
         echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp
-        ipcmd='a'
+        [ "$dhcp" != 'no' ] && dhcp_up
         ;;
     offline)
-        ifconfig ${vif} down
-        ipcmd='d'
+        [ "$dhcp" != 'no' ] && dhcp_down
+        ifconfig "$vif" down || true
         ;;
 esac
 
-ip r ${ipcmd} ${ip} dev ${vif} src ${main_ip}
 
 handle_iptable
 
-success
+log debug "Successful vif-nat $command for $vif."
+if [ "$command" == "online" ]
+then
+  success
+fi
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/vif-route
--- a/tools/examples/vif-route  Fri Dec  2 18:12:11 2005
+++ b/tools/examples/vif-route  Fri Dec  2 18:52:25 2005
@@ -23,7 +23,7 @@
 dir=$(dirname "$0")
 . "$dir/vif-common.sh"
 
-main_ip=$(ip addr show eth0 | sed -e '/inet /!d;s/^.*inet \([^\s*]\)\s.*$/\1/')
+main_ip=$(dom0_ip)
 
 case "$command" in
     online)
@@ -47,4 +47,8 @@
 
 handle_iptable
 
-success
+log debug "Successful vif-route $command for $vif."
+if [ "$command" == "online" ]
+then
+  success
+fi
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent  Fri Dec  2 18:12:11 2005
+++ b/tools/examples/xen-backend.agent  Fri Dec  2 18:52:25 2005
@@ -5,6 +5,9 @@
 case "$XENBUS_TYPE" in
   vbd)
     /etc/xen/scripts/block "$ACTION"
+    ;;
+  vtpm)
+    /etc/xen/scripts/vtpm "$ACTION"
     ;;
   vif)
     [ -n "$script" ] && $script "$ACTION"
@@ -15,6 +18,9 @@
   add)
     ;;
   remove)
+    # remove device frontend store entries
+    xenstore-rm -t $(xenstore-read "$XENBUS_PATH/frontend") || true
+
     # remove device backend store entries
     xenstore-rm -t "$XENBUS_PATH"       || true
     xenstore-rm -t "error/$XENBUS_PATH" || true
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules  Fri Dec  2 18:12:11 2005
+++ b/tools/examples/xen-backend.rules  Fri Dec  2 18:52:25 2005
@@ -1,5 +1,7 @@
 SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block 
$env{ACTION}"
+SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm 
$env{ACTION}"
 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} 
online"
 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", 
RUN+="$env{script} offline"
+SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/bin/bash -c 
'/usr/bin/xenstore-rm -t $$(/usr/bin/xenstore-read $env{XENBUS_PATH}/frontend)'"
 SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm -t 
$env{XENBUS_PATH}"
 SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm -t 
error/$env{XENBUS_PATH}"
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/xen-hotplug-common.sh
--- a/tools/examples/xen-hotplug-common.sh      Fri Dec  2 18:12:11 2005
+++ b/tools/examples/xen-hotplug-common.sh      Fri Dec  2 18:52:25 2005
@@ -40,6 +40,17 @@
   xenstore_write "$XENBUS_PATH"/hotplug-status connected
 }
 
+do_or_die() {
+  "$@" || fatal "$@ failed"
+}
+
+sigerr() {
+  fatal "$0" "$@" "failed; error detected."
+}
+
+trap sigerr ERR
+
+
 ##
 # xenstore_read <path>+
 #
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/xen-network-common.sh
--- a/tools/examples/xen-network-common.sh      Fri Dec  2 18:12:11 2005
+++ b/tools/examples/xen-network-common.sh      Fri Dec  2 18:52:25 2005
@@ -69,3 +69,29 @@
     true
   }
 fi
+
+
+first_file()
+{
+  t="$1"
+  shift
+  for file in $@
+  do
+    if [ "$t" "$file" ]
+    then
+      echo "$file"
+      return
+    fi
+  done
+}
+
+find_dhcpd_conf_file()
+{
+  first_file -f /etc/dhcp3/dhcpd.conf /etc/dhcpd.conf
+}
+
+
+find_dhcpd_init_file()
+{
+  first_file -x /etc/init.d/dhcp3-server /etc/init.d/dhcp
+}
diff -r eae5812f33f1 -r 28bd01c9b596 tools/ioemu/exec.c
--- a/tools/ioemu/exec.c        Fri Dec  2 18:12:11 2005
+++ b/tools/ioemu/exec.c        Fri Dec  2 18:52:25 2005
@@ -262,13 +262,24 @@
                                   unsigned long size,
                                   unsigned long phys_offset)
 {
-        if (mmio_cnt == MAX_MMIO) {
-                fprintf(logfile, "too many mmio regions\n");
-                exit(-1);
-        }
-        mmio[mmio_cnt].io_index = phys_offset;
-        mmio[mmio_cnt].start = start_addr;
-        mmio[mmio_cnt++].size = size;
+    int i;
+
+    for (i = 0; i < mmio_cnt; i++) { 
+        if(mmio[i].start == start_addr) {
+            mmio[i].io_index = phys_offset;
+            mmio[i].size = size;
+            return;
+        }
+    }
+
+    if (mmio_cnt == MAX_MMIO) {
+        fprintf(logfile, "too many mmio regions\n");
+        exit(-1);
+    }
+
+    mmio[mmio_cnt].io_index = phys_offset;
+    mmio[mmio_cnt].start = start_addr;
+    mmio[mmio_cnt++].size = size;
 }
 
 /* mem_read and mem_write are arrays of functions containing the
diff -r eae5812f33f1 -r 28bd01c9b596 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c      Fri Dec  2 18:12:11 2005
+++ b/tools/ioemu/hw/ide.c      Fri Dec  2 18:52:25 2005
@@ -669,6 +669,8 @@
     }
     if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
         s->status = READY_STAT | SEEK_STAT;
+        s->bmdma->status &= ~BM_STATUS_DMAING;
+        s->bmdma->status |= BM_STATUS_INT;
         ide_set_irq(s);
 #ifdef DEBUG_IDE_ATAPI
         printf("dma status=0x%x\n", s->status);
@@ -736,6 +738,8 @@
             if (n == 0) {
                 /* end of transfer */
                 s->status = READY_STAT | SEEK_STAT;
+                s->bmdma->status &= ~BM_STATUS_DMAING;
+                s->bmdma->status |= BM_STATUS_INT;
                 ide_set_irq(s);
                 return 0;
             }
@@ -983,6 +987,8 @@
     if (s->packet_transfer_size <= 0) {
         s->status = READY_STAT;
         s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | 
ATAPI_INT_REASON_CD;
+        s->bmdma->status &= ~BM_STATUS_DMAING;
+        s->bmdma->status |= BM_STATUS_INT;
         ide_set_irq(s);
 #ifdef DEBUG_IDE_ATAPI
         printf("dma status=0x%x\n", s->status);
@@ -2065,8 +2071,6 @@
     }
     /* end of transfer */
  the_end:
-    bm->status &= ~BM_STATUS_DMAING;
-    bm->status |= BM_STATUS_INT;
     bm->dma_cb = NULL;
     bm->ide_if = NULL;
 }
diff -r eae5812f33f1 -r 28bd01c9b596 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Fri Dec  2 18:12:11 2005
+++ b/tools/ioemu/hw/vga.c      Fri Dec  2 18:52:25 2005
@@ -1834,16 +1834,6 @@
 
     /* TODO:add vbe support if enable it */
 
-    FILE *qemuf = fopen("/etc/xen/qemu-vgaram-bin", "rb");
-    if (!qemuf) {
-        fprintf(logfile, "open qemu vgaram binary failed!\n");
-    } else {
-        /*load vram contents, else vga console can't boot */
-        qemu_get_buffer(qemuf, s->vram_ptr, 256*1024);
-
-        fclose(qemuf);
-    }
-
 }
 
 void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Fri Dec  2 18:12:11 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c      Fri Dec  2 18:52:25 2005
@@ -1,6 +1,6 @@
 /*
  *  i386 helpers (without register variable usage)
- * 
+ *
  *  Copyright (c) 2003 Fabrice Bellard
  *
  * This library is free software; you can redistribute it and/or
@@ -56,6 +56,7 @@
 #include "vl.h"
 
 extern int domid;
+extern int vcpus;
 
 void *shared_vram;
 
@@ -93,7 +94,7 @@
 }
 
 
-void cpu_dump_state(CPUState *env, FILE *f, 
+void cpu_dump_state(CPUState *env, FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags)
 {
@@ -121,270 +122,273 @@
 
 //the evtchn fd for polling
 int evtchn_fd = -1;
-//the evtchn port for polling the notification, should be inputed as bochs's 
parameter
-uint16_t ioreq_remote_port, ioreq_local_port;
+
+//the evtchn port for polling the notification,
+//should be inputed as bochs's parameter
+evtchn_port_t ioreq_remote_port, ioreq_local_port;
 
 //some functions to handle the io req packet
-void
-sp_info()
-{
-       ioreq_t *req;
-
-       req = &(shared_page->vcpu_iodata[0].vp_ioreq);
-        term_printf("event port: %d\n", shared_page->sp_global.eport);
-        term_printf("req state: %x, pvalid: %x, addr: %llx, data: %llx, count: 
%llx, size: %llx\n", req->state, req->pdata_valid, req->addr, req->u.data, 
req->count, req->size);
+void sp_info()
+{
+    ioreq_t *req;
+    int i;
+
+    term_printf("event port: %d\n", shared_page->sp_global.eport);
+    for ( i = 0; i < vcpus; i++ ) {
+        req = &(shared_page->vcpu_iodata[i].vp_ioreq);
+        term_printf("vcpu %d:\n", i);
+        term_printf("  req state: %x, pvalid: %x, addr: %llx, "
+                    "data: %llx, count: %llx, size: %llx\n",
+                    req->state, req->pdata_valid, req->addr,
+                    req->u.data, req->count, req->size);
+    }
 }
 
 //get the ioreq packets from share mem
 ioreq_t* __cpu_get_ioreq(void)
 {
-       ioreq_t *req;
-
-       req = &(shared_page->vcpu_iodata[0].vp_ioreq);
-       if (req->state == STATE_IOREQ_READY) {
-               req->state = STATE_IOREQ_INPROCESS;
-       } else {
-               fprintf(logfile, "False I/O request ... in-service already: %x, 
pvalid: %x,port: %llx, data: %llx, count: %llx, size: %llx\n", req->state, 
req->pdata_valid, req->addr, req->u.data, req->count, req->size);
-               req = NULL;
-       }
-
-       return req;
+    ioreq_t *req;
+
+    req = &(shared_page->vcpu_iodata[0].vp_ioreq);
+    if (req->state == STATE_IOREQ_READY) {
+        req->state = STATE_IOREQ_INPROCESS;
+    } else {
+        fprintf(logfile, "False I/O request ... in-service already: "
+                         "%x, pvalid: %x, port: %llx, "
+                         "data: %llx, count: %llx, size: %llx\n",
+                         req->state, req->pdata_valid, req->addr,
+                         req->u.data, req->count, req->size);
+        req = NULL;
+    }
+
+    return req;
 }
 
 //use poll to get the port notification
-//ioreq_vec--out,the 
+//ioreq_vec--out,the
 //retval--the number of ioreq packet
 ioreq_t* cpu_get_ioreq(void)
 {
-       int rc;
-       uint16_t port;
-       rc = read(evtchn_fd, &port, sizeof(port));
-       if ((rc == sizeof(port)) && (port == ioreq_local_port)) {
-               // unmask the wanted port again
-               write(evtchn_fd, &ioreq_local_port, 2);
-
-               //get the io packet from shared memory
-               return __cpu_get_ioreq();
-       }
-
-       //read error or read nothing
-       return NULL;
-}
-
-unsigned long
-do_inp(CPUState *env, unsigned long addr, unsigned long size)
-{
-       switch(size) {
-       case 1:
-               return cpu_inb(env, addr);
-       case 2:
-               return cpu_inw(env, addr);
-       case 4:
-               return cpu_inl(env, addr);
-       default:
-               fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
-               exit(-1);
-       }
-}
-
-void
-do_outp(CPUState *env, unsigned long addr, unsigned long size, 
-        unsigned long val)
-{
-       switch(size) {
-       case 1:
-               return cpu_outb(env, addr, val);
-       case 2:
-               return cpu_outw(env, addr, val);
-       case 4:
-               return cpu_outl(env, addr, val);
-       default:
-               fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
-               exit(-1);
-       }
-}
-
-extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
+    int rc;
+    evtchn_port_t port;
+
+    rc = read(evtchn_fd, &port, sizeof(port));
+    if ((rc == sizeof(port)) && (port == ioreq_local_port)) {
+        // unmask the wanted port again
+        write(evtchn_fd, &ioreq_local_port, sizeof(port));
+
+        //get the io packet from shared memory
+        return __cpu_get_ioreq();
+    }
+
+    //read error or read nothing
+    return NULL;
+}
+
+unsigned long do_inp(CPUState *env, unsigned long addr, unsigned long size)
+{
+    switch(size) {
+    case 1:
+        return cpu_inb(env, addr);
+    case 2:
+        return cpu_inw(env, addr);
+    case 4:
+        return cpu_inl(env, addr);
+    default:
+        fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
+        exit(-1);
+    }
+}
+
+void do_outp(CPUState *env, unsigned long addr,
+             unsigned long size, unsigned long val)
+{
+    switch(size) {
+    case 1:
+        return cpu_outb(env, addr, val);
+    case 2:
+        return cpu_outw(env, addr, val);
+    case 4:
+        return cpu_outl(env, addr, val);
+    default:
+        fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
+        exit(-1);
+    }
+}
+
+extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                                    int len, int is_write);
 
-static inline void
-read_physical(uint64_t addr, unsigned long size, void *val)
-{
-        return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0);
-}
-
-static inline void
-write_physical(uint64_t addr, unsigned long size, void *val)
-{
-        return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1);
-}
-
-void
-cpu_ioreq_pio(CPUState *env, ioreq_t *req)
-{
-       int i, sign;
-
-       sign = req->df ? -1 : 1;
-
-       if (req->dir == IOREQ_READ) {
-               if (!req->pdata_valid) {
-                       req->u.data = do_inp(env, req->addr, req->size);
-               } else {
-                       unsigned long tmp; 
-
-                       for (i = 0; i < req->count; i++) {
-                               tmp = do_inp(env, req->addr, req->size);
-                               write_physical((target_phys_addr_t) req->u.pdata
-                                               + (sign * i * req->size), 
-                                       req->size, &tmp);
-                       }
-               }
-       } else if (req->dir == IOREQ_WRITE) {
-               if (!req->pdata_valid) {
-                       do_outp(env, req->addr, req->size, req->u.data);
-               } else {
-                       for (i = 0; i < req->count; i++) {
-                               unsigned long tmp;
-
-                               read_physical((target_phys_addr_t) req->u.pdata
-                                               + (sign * i * req->size),
-                                       req->size, &tmp);
-                               do_outp(env, req->addr, req->size, tmp);
-                       }
-               }
-       }
-}
-
-void
-cpu_ioreq_move(CPUState *env, ioreq_t *req)
-{
-       int i, sign;
-
-       sign = req->df ? -1 : 1;
-
-       if (!req->pdata_valid) {
-               if (req->dir == IOREQ_READ) {
-                       for (i = 0; i < req->count; i++) {
-                               read_physical(req->addr
-                                               + (sign * i * req->size),
-                                       req->size, &req->u.data);
-                       }
-               } else if (req->dir == IOREQ_WRITE) {
-                       for (i = 0; i < req->count; i++) {
-                               write_physical(req->addr
-                                               + (sign * i * req->size),
-                                       req->size, &req->u.data);
-                       }
-               }
-       } else {
-               unsigned long tmp;
-
-               if (req->dir == IOREQ_READ) {
-                       for (i = 0; i < req->count; i++) {
-                               read_physical(req->addr
-                                               + (sign * i * req->size),
-                                       req->size, &tmp);
-                               write_physical((target_phys_addr_t )req->u.pdata
-                                               + (sign * i * req->size),
-                                       req->size, &tmp);
-                       }
-               } else if (req->dir == IOREQ_WRITE) {
-                       for (i = 0; i < req->count; i++) {
-                               read_physical((target_phys_addr_t) req->u.pdata
-                                               + (sign * i * req->size),
-                                       req->size, &tmp);
-                               write_physical(req->addr
-                                               + (sign * i * req->size),
-                                       req->size, &tmp);
-                       }
-               }
-       }
-}
-
-void
-cpu_ioreq_and(CPUState *env, ioreq_t *req)
-{
-       unsigned long tmp1, tmp2;
-
-       if (req->pdata_valid != 0)
-               hw_error("expected scalar value");
-
-       read_physical(req->addr, req->size, &tmp1);
-       if (req->dir == IOREQ_WRITE) {
-               tmp2 = tmp1 & (unsigned long) req->u.data;
-               write_physical(req->addr, req->size, &tmp2);
-       }
-       req->u.data = tmp1;
-}
-
-void
-cpu_ioreq_or(CPUState *env, ioreq_t *req)
-{
-       unsigned long tmp1, tmp2;
-
-       if (req->pdata_valid != 0)
-               hw_error("expected scalar value");
-
-       read_physical(req->addr, req->size, &tmp1);
-       if (req->dir == IOREQ_WRITE) {
-               tmp2 = tmp1 | (unsigned long) req->u.data;
-               write_physical(req->addr, req->size, &tmp2);
-       }
-       req->u.data = tmp1;
-}
-
-void
-cpu_ioreq_xor(CPUState *env, ioreq_t *req)
-{
-       unsigned long tmp1, tmp2;
-
-       if (req->pdata_valid != 0)
-               hw_error("expected scalar value");
-
-       read_physical(req->addr, req->size, &tmp1);
-       if (req->dir == IOREQ_WRITE) {
-               tmp2 = tmp1 ^ (unsigned long) req->u.data;
-               write_physical(req->addr, req->size, &tmp2);
-       }
-       req->u.data = tmp1;
-}
-
-void
-cpu_handle_ioreq(CPUState *env)
-{
-       ioreq_t *req = cpu_get_ioreq();
-
-       if (req) {
-               if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
-                       if (req->size != 4)
-                               req->u.data &= (1UL << (8 * req->size))-1;
-               }
-
-               switch (req->type) {
-               case IOREQ_TYPE_PIO:
-                       cpu_ioreq_pio(env, req);
-                       break;
-               case IOREQ_TYPE_COPY:
-                       cpu_ioreq_move(env, req);
-                       break;
-               case IOREQ_TYPE_AND:
-                       cpu_ioreq_and(env, req);
-                       break;
-               case IOREQ_TYPE_OR:
-                       cpu_ioreq_or(env, req);
-                       break;
-               case IOREQ_TYPE_XOR:
-                       cpu_ioreq_xor(env, req);
-                       break;
-               default:
-                       hw_error("Invalid ioreq type 0x%x", req->type);
-               }
-
-               /* No state change if state = STATE_IORESP_HOOK */
-               if (req->state == STATE_IOREQ_INPROCESS)
-                       req->state = STATE_IORESP_READY;
-               env->send_event = 1;
-       }
+static inline void read_physical(uint64_t addr, unsigned long size, void *val)
+{
+    return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0);
+}
+
+static inline void write_physical(uint64_t addr, unsigned long size, void *val)
+{
+    return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1);
+}
+
+void cpu_ioreq_pio(CPUState *env, ioreq_t *req)
+{
+    int i, sign;
+
+    sign = req->df ? -1 : 1;
+
+    if (req->dir == IOREQ_READ) {
+        if (!req->pdata_valid) {
+            req->u.data = do_inp(env, req->addr, req->size);
+        } else {
+            unsigned long tmp;
+
+            for (i = 0; i < req->count; i++) {
+                tmp = do_inp(env, req->addr, req->size);
+                write_physical((target_phys_addr_t) req->u.pdata
+                  + (sign * i * req->size),
+                  req->size, &tmp);
+            }
+        }
+    } else if (req->dir == IOREQ_WRITE) {
+        if (!req->pdata_valid) {
+            do_outp(env, req->addr, req->size, req->u.data);
+        } else {
+            for (i = 0; i < req->count; i++) {
+                unsigned long tmp;
+
+                read_physical((target_phys_addr_t) req->u.pdata
+                  + (sign * i * req->size),
+                  req->size, &tmp);
+                do_outp(env, req->addr, req->size, tmp);
+            }
+        }
+    }
+}
+
+void cpu_ioreq_move(CPUState *env, ioreq_t *req)
+{
+    int i, sign;
+
+    sign = req->df ? -1 : 1;
+
+    if (!req->pdata_valid) {
+        if (req->dir == IOREQ_READ) {
+            for (i = 0; i < req->count; i++) {
+                read_physical(req->addr
+                  + (sign * i * req->size),
+                  req->size, &req->u.data);
+            }
+        } else if (req->dir == IOREQ_WRITE) {
+            for (i = 0; i < req->count; i++) {
+                write_physical(req->addr
+                  + (sign * i * req->size),
+                  req->size, &req->u.data);
+            }
+        }
+    } else {
+        unsigned long tmp;
+
+        if (req->dir == IOREQ_READ) {
+            for (i = 0; i < req->count; i++) {
+                read_physical(req->addr
+                  + (sign * i * req->size),
+                  req->size, &tmp);
+                write_physical((target_phys_addr_t )req->u.pdata
+                  + (sign * i * req->size),
+                  req->size, &tmp);
+            }
+        } else if (req->dir == IOREQ_WRITE) {
+            for (i = 0; i < req->count; i++) {
+                read_physical((target_phys_addr_t) req->u.pdata
+                  + (sign * i * req->size),
+                  req->size, &tmp);
+                write_physical(req->addr
+                  + (sign * i * req->size),
+                  req->size, &tmp);
+            }
+        }
+    }
+}
+
+void cpu_ioreq_and(CPUState *env, ioreq_t *req)
+{
+    unsigned long tmp1, tmp2;
+
+    if (req->pdata_valid != 0)
+        hw_error("expected scalar value");
+
+    read_physical(req->addr, req->size, &tmp1);
+    if (req->dir == IOREQ_WRITE) {
+        tmp2 = tmp1 & (unsigned long) req->u.data;
+        write_physical(req->addr, req->size, &tmp2);
+    }
+    req->u.data = tmp1;
+}
+
+void cpu_ioreq_or(CPUState *env, ioreq_t *req)
+{
+    unsigned long tmp1, tmp2;
+
+    if (req->pdata_valid != 0)
+        hw_error("expected scalar value");
+
+    read_physical(req->addr, req->size, &tmp1);
+    if (req->dir == IOREQ_WRITE) {
+        tmp2 = tmp1 | (unsigned long) req->u.data;
+        write_physical(req->addr, req->size, &tmp2);
+    }
+    req->u.data = tmp1;
+}
+
+void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
+{
+    unsigned long tmp1, tmp2;
+
+    if (req->pdata_valid != 0)
+        hw_error("expected scalar value");
+
+    read_physical(req->addr, req->size, &tmp1);
+    if (req->dir == IOREQ_WRITE) {
+        tmp2 = tmp1 ^ (unsigned long) req->u.data;
+        write_physical(req->addr, req->size, &tmp2);
+    }
+    req->u.data = tmp1;
+}
+
+void cpu_handle_ioreq(CPUState *env)
+{
+    ioreq_t *req = cpu_get_ioreq();
+
+    if (req) {
+        if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
+            if (req->size != 4)
+                req->u.data &= (1UL << (8 * req->size))-1;
+        }
+
+        switch (req->type) {
+        case IOREQ_TYPE_PIO:
+            cpu_ioreq_pio(env, req);
+            break;
+        case IOREQ_TYPE_COPY:
+            cpu_ioreq_move(env, req);
+            break;
+        case IOREQ_TYPE_AND:
+            cpu_ioreq_and(env, req);
+            break;
+        case IOREQ_TYPE_OR:
+            cpu_ioreq_or(env, req);
+            break;
+        case IOREQ_TYPE_XOR:
+            cpu_ioreq_xor(env, req);
+            break;
+        default:
+            hw_error("Invalid ioreq type 0x%x\n", req->type);
+        }
+
+        /* No state change if state = STATE_IORESP_HOOK */
+        if (req->state == STATE_IOREQ_INPROCESS)
+            req->state = STATE_IORESP_READY;
+        env->send_event = 1;
+    }
 }
 
 int xc_handle;
@@ -393,7 +397,8 @@
 destroy_vmx_domain(void)
 {
     extern FILE* logfile;
-    char destroy_cmd[20];
+    char destroy_cmd[32];
+
     sprintf(destroy_cmd, "xm destroy %d", domid);
     if (system(destroy_cmd) == -1)
         fprintf(logfile, "%s failed.!\n", destroy_cmd);
@@ -403,40 +408,41 @@
 int    highest_fds;
 int main_loop(void)
 {
-       fd_set rfds;
-       struct timeval tv;
-       extern CPUState *global_env;
-        extern int vm_running;
-        extern int shutdown_requested;
-       CPUState *env = global_env;
-       int retval;
-        extern void main_loop_wait(int);
-
-       /* Watch stdin (fd 0) to see when it has input. */
-       FD_ZERO(&wakeup_rfds);
-       FD_SET(evtchn_fd, &wakeup_rfds);
-       highest_fds = evtchn_fd;
-       env->send_event = 0;
-       while (1) {
-                if (vm_running) {
-                    if (shutdown_requested) {
-                        break;
-                    }
-                    if (reset_requested){
-                        qemu_system_reset();
-                        reset_requested = 0;
-                    }
-                }
-
-               /* Wait up to one seconds. */
-               tv.tv_sec = 0;
-               tv.tv_usec = 100000;
-
-               retval = select(highest_fds+1, &wakeup_rfds, NULL, NULL, &tv);
-               if (retval == -1) {
-                       perror("select");
-                       return 0;
-               }
+    fd_set rfds;
+    struct timeval tv;
+    extern CPUState *global_env;
+    extern int vm_running;
+    extern int shutdown_requested;
+    CPUState *env = global_env;
+    int retval;
+    extern void main_loop_wait(int);
+
+    /* Watch stdin (fd 0) to see when it has input. */
+    FD_ZERO(&wakeup_rfds);
+    FD_SET(evtchn_fd, &wakeup_rfds);
+    highest_fds = evtchn_fd;
+    env->send_event = 0;
+
+    while (1) {
+        if (vm_running) {
+            if (shutdown_requested) {
+                break;
+            }
+            if (reset_requested){
+                qemu_system_reset();
+                reset_requested = 0;
+            }
+        }
+
+        /* Wait up to one seconds. */
+        tv.tv_sec = 0;
+        tv.tv_usec = 100000;
+
+        retval = select(highest_fds+1, &wakeup_rfds, NULL, NULL, &tv);
+        if (retval == -1) {
+            fprintf(logfile, "select returned error %d\n", errno);
+            return 0;
+        }
         rfds = wakeup_rfds;
         FD_ZERO(&wakeup_rfds);
         FD_SET(evtchn_fd, &wakeup_rfds);
@@ -451,65 +457,64 @@
         if ( FD_ISSET(evtchn_fd, &rfds) ) {
             cpu_handle_ioreq(env);
         }
-               main_loop_wait(0);
-               if (env->send_event) {
-                   env->send_event = 0;
-                       struct ioctl_evtchn_notify notify;
-                       notify.port = ioreq_local_port;
-                       (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
-               }
-       }
-        destroy_vmx_domain();
-       return 0;
-}
-
-static void
-qemu_vmx_reset(void *unused)
-{
-    char cmd[255];
-
-    /* pause domain first, to avoid repeated reboot request*/ 
-    xc_domain_pause (xc_handle, domid);
-
-    sprintf(cmd,"xm shutdown -R %d", domid);
-    system (cmd);
-}
-
-CPUState *
-cpu_init()
-{
-       CPUX86State *env;
-       struct ioctl_evtchn_bind_interdomain bind;
-       int rc;
-      
-        cpu_exec_init();
-        qemu_register_reset(qemu_vmx_reset, NULL);
-       env = malloc(sizeof(CPUX86State));
-       if (!env)
-               return NULL;
-       memset(env, 0, sizeof(CPUX86State));
-
-       cpu_single_env = env;
-
-       if (evtchn_fd != -1)//the evtchn has been opened by another cpu object
-               return NULL;
-
-       //use nonblock reading not polling, may change in future.
-       evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK); 
-       if (evtchn_fd == -1) {
-               perror("open");
-               return NULL;
-       }
-
-       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;
-}
-
+        main_loop_wait(0);
+
+        if (env->send_event) {
+            struct ioctl_evtchn_notify notify;
+
+            env->send_event = 0;
+            notify.port = ioreq_local_port;
+            (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
+        }
+    }
+    destroy_vmx_domain();
+    return 0;
+}
+
+static void qemu_vmx_reset(void *unused)
+{
+    char cmd[64];
+
+    /* pause domain first, to avoid repeated reboot request*/
+    xc_domain_pause(xc_handle, domid);
+
+    sprintf(cmd, "xm shutdown -R %d", domid);
+    system(cmd);
+}
+
+CPUState * cpu_init()
+{
+    CPUX86State *env;
+    struct ioctl_evtchn_bind_interdomain bind;
+    int rc;
+
+    cpu_exec_init();
+    qemu_register_reset(qemu_vmx_reset, NULL);
+    env = malloc(sizeof(CPUX86State));
+    if (!env)
+        return NULL;
+    memset(env, 0, sizeof(CPUX86State));
+
+    cpu_single_env = env;
+
+    if (evtchn_fd != -1)//the evtchn has been opened by another cpu object
+        return NULL;
+
+    //use nonblock reading not polling, may change in future.
+    evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK);
+    if (evtchn_fd == -1) {
+        fprintf(logfile, "open evtchn device error %d\n", errno);
+        return NULL;
+    }
+
+    bind.remote_domain = domid;
+    bind.remote_port   = ioreq_remote_port;
+    rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+    if (rc == -1) {
+        fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
+        return NULL;
+    }
+    ioreq_local_port = rc;
+
+    return env;
+}
diff -r eae5812f33f1 -r 28bd01c9b596 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Fri Dec  2 18:12:11 2005
+++ b/tools/ioemu/vl.c  Fri Dec  2 18:52:25 2005
@@ -1,8 +1,8 @@
 /*
  * QEMU System Emulator
- * 
+ *
  * Copyright (c) 2003-2004 Fabrice Bellard
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
  * in the Software without restriction, including without limitation the rights
@@ -221,7 +221,7 @@
 }
 
 /* size is the word size in byte */
-int register_ioport_read(int start, int length, int size, 
+int register_ioport_read(int start, int length, int size,
                          IOPortReadFunc *func, void *opaque)
 {
     int i, bsize;
@@ -246,7 +246,7 @@
 }
 
 /* size is the word size in byte */
-int register_ioport_write(int start, int length, int size, 
+int register_ioport_write(int start, int length, int size,
                           IOPortWriteFunc *func, void *opaque)
 {
     int i, bsize;
@@ -307,7 +307,7 @@
 {
     int len;
     len = strlen(buf);
-    if (len < buf_size) 
+    if (len < buf_size)
         pstrcpy(buf + len, buf_size - len, s);
     return buf;
 }
@@ -362,7 +362,7 @@
 #ifdef DEBUG_IOPORT
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "outb: %04x %02x\n", addr, val);
-#endif    
+#endif
     ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
 }
 
@@ -371,7 +371,7 @@
 #ifdef DEBUG_IOPORT
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "outw: %04x %04x\n", addr, val);
-#endif    
+#endif
     ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
 }
 
@@ -465,7 +465,7 @@
 void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
 {
     if (qemu_put_mouse_event) {
-        qemu_put_mouse_event(qemu_put_mouse_event_opaque, 
+        qemu_put_mouse_event(qemu_put_mouse_event_opaque,
                              dx, dy, dz, buttons_state);
     }
 }
@@ -475,14 +475,14 @@
 
 #if defined(__powerpc__)
 
-static inline uint32_t get_tbl(void) 
+static inline uint32_t get_tbl(void)
 {
     uint32_t tbl;
     asm volatile("mftb %0" : "=r" (tbl));
     return tbl;
 }
 
-static inline uint32_t get_tbu(void) 
+static inline uint32_t get_tbu(void)
 {
        uint32_t tbl;
        asm volatile("mftbu %0" : "=r" (tbl));
@@ -604,7 +604,7 @@
             uint32_t high, low;
 #else
             uint32_t low, high;
-#endif            
+#endif
         } l;
     } u, res;
     uint64_t rl, rh;
@@ -707,7 +707,7 @@
         t = *pt;
         if (!t)
             break;
-        if (t->expire_time > expire_time) 
+        if (t->expire_time > expire_time)
             break;
         pt = &t->next;
     }
@@ -736,7 +736,7 @@
 static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
 {
     QEMUTimer *ts;
-    
+
     for(;;) {
         ts = *ptimer_head;
         if (!ts || ts->expire_time > current_time)
@@ -744,7 +744,7 @@
         /* remove timer from the list before calling the callback */
         *ptimer_head = ts->next;
         ts->next = NULL;
-        
+
         /* run the callback (the timer list can be modified) */
         ts->cb(ts->opaque);
     }
@@ -814,17 +814,17 @@
                                host_alarm_handler, // function
                                (DWORD)&count,  // user parameter
                                TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
-       if( !timerID ) {
-            perror("failed timer alarm");
+        if( !timerID ) {
+            fprintf(logfile, "failed timer alarm");
             exit(1);
-       }
+        }
     }
     pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
 #else
     {
         /* get times() syscall frequency */
         timer_freq = sysconf(_SC_CLK_TCK);
-      
+
 #ifndef TARGET_VMX
         /* timer signal */
         sigfillset(&act.sa_mask);
@@ -860,11 +860,11 @@
             sigaction(SIGIO, &act, NULL);
             fcntl(rtc_fd, F_SETFL, O_ASYNC);
             fcntl(rtc_fd, F_SETOWN, getpid());
-        } else 
+        } else
 #endif /* defined(__linux__) */
         {
         use_itimer:
-            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
+            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
                                    PIT_FREQ) / 1000000;
         }
 #endif /* TARGET_VMX */
@@ -903,13 +903,13 @@
         s->chr_send_event(s, event);
 }
 
-void qemu_chr_add_read_handler(CharDriverState *s, 
-                               IOCanRWHandler *fd_can_read, 
+void qemu_chr_add_read_handler(CharDriverState *s,
+                               IOCanRWHandler *fd_can_read,
                                IOReadHandler *fd_read, void *opaque)
 {
     s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);
 }
-             
+
 void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event)
 {
     s->chr_event = chr_event;
@@ -920,8 +920,8 @@
     return len;
 }
 
-static void null_chr_add_read_handler(CharDriverState *chr, 
-                                    IOCanRWHandler *fd_can_read, 
+static void null_chr_add_read_handler(CharDriverState *chr,
+                                    IOCanRWHandler *fd_can_read,
                                     IOReadHandler *fd_read, void *opaque)
 {
 }
@@ -943,7 +943,7 @@
 typedef struct {
     int fd_in, fd_out;
     /* for nographic stdio only */
-    IOCanRWHandler *fd_can_read; 
+    IOCanRWHandler *fd_can_read;
     IOReadHandler *fd_read;
     void *fd_opaque;
 } FDCharDriver;
@@ -979,8 +979,8 @@
     return unix_write(s->fd_out, buf, len);
 }
 
-static void fd_chr_add_read_handler(CharDriverState *chr, 
-                                    IOCanRWHandler *fd_can_read, 
+static void fd_chr_add_read_handler(CharDriverState *chr,
+                                    IOCanRWHandler *fd_can_read,
                                     IOReadHandler *fd_read, void *opaque)
 {
     FDCharDriver *s = chr->opaque;
@@ -1047,7 +1047,7 @@
         case 'x':
             exit(0);
             break;
-        case 's': 
+        case 's':
             {
                 int i;
                 for (i = 0; i < MAX_DISKS; i++) {
@@ -1087,13 +1087,13 @@
             uint8_t buf[1];
             CharDriverState *chr;
             FDCharDriver *s;
-            
+
             chr = stdio_clients[client_index];
             s = chr->opaque;
             buf[0] = ch;
             /* XXX: should queue the char if the device is not
                ready */
-            if (s->fd_can_read(s->fd_opaque) > 0) 
+            if (s->fd_can_read(s->fd_opaque) > 0)
                 s->fd_read(s->fd_opaque, buf, 1);
         }
     }
@@ -1141,7 +1141,7 @@
     tty.c_cflag |= CS8;
     tty.c_cc[VMIN] = 1;
     tty.c_cc[VTIME] = 0;
-    
+
     tcsetattr (0, TCSANOW, &tty);
 
     atexit(term_exit);
@@ -1176,7 +1176,6 @@
 int store_console_dev(int domid, char *pts)
 {
     int xc_handle;
-    unsigned int len = 0;
     struct xs_handle *xs;
     char *path;
 
@@ -1191,7 +1190,7 @@
         fprintf(logfile, "xc_interface_open() error\n");
         return -1;
     }
-    
+
     path = xs_get_domain_path(xs, domid);
     if (path == NULL) {
         fprintf(logfile, "xs_get_domain_path() error\n");
@@ -1207,7 +1206,7 @@
         fprintf(logfile, "xs_write for console fail");
         return -1;
     }
-    
+
     free(path);
     xs_daemon_close(xs);
     close(xc_handle);
@@ -1218,15 +1217,19 @@
 #if defined(__linux__)
 CharDriverState *qemu_chr_open_pty(void)
 {
-    char slave_name[1024];
     int master_fd, slave_fd;
-    
-    /* Not satisfying */
-    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
+    struct termios term;
+
+    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0)
         return NULL;
-    }
-    fprintf(stderr, "char device redirected to %s\n", slave_name);
-    store_console_dev(domid, slave_name);
+
+    /* Set raw attributes on the pty. */
+    cfmakeraw(&term);
+    tcsetattr(slave_fd, TCSAFLUSH, &term);
+
+    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
+    store_console_dev(domid, ptsname(master_fd));
+
     return qemu_chr_open_fd(master_fd, master_fd);
 }
 #else
@@ -1244,13 +1247,13 @@
         return text_console_init(&display_state);
     } else if (!strcmp(filename, "null")) {
         return qemu_chr_open_null();
-    } else 
+    } else
 #ifndef _WIN32
     if (!strcmp(filename, "pty")) {
         return qemu_chr_open_pty();
     } else if (!strcmp(filename, "stdio")) {
         return qemu_chr_open_stdio();
-    } else 
+    } else
 #endif
     {
         return NULL;
@@ -1291,7 +1294,7 @@
     nd->send_packet(nd, buf, size);
 }
 
-void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read, 
+void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
                           IOReadHandler *fd_read, void *opaque)
 {
     nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
@@ -1303,8 +1306,8 @@
 {
 }
 
-static void dummy_add_read_packet(NetDriverState *nd, 
-                                  IOCanRWHandler *fd_can_read, 
+static void dummy_add_read_packet(NetDriverState *nd,
+                                  IOCanRWHandler *fd_can_read,
                                   IOReadHandler *fd_read, void *opaque)
 {
 }
@@ -1349,8 +1352,8 @@
     slirp_input(buf, size);
 }
 
-static void slirp_add_read_packet(NetDriverState *nd, 
-                                  IOCanRWHandler *fd_can_read, 
+static void slirp_add_read_packet(NetDriverState *nd,
+                                  IOCanRWHandler *fd_can_read,
                                   IOReadHandler *fd_read, void *opaque)
 {
     slirp_fd_opaque = opaque;
@@ -1397,7 +1400,7 @@
     const char *p;
     struct in_addr guest_addr;
     int host_port, guest_port;
-    
+
     if (!slirp_inited) {
         slirp_inited = 1;
         slirp_init();
@@ -1427,11 +1430,11 @@
     }
     if (!inet_aton(buf, &guest_addr))
         goto fail;
-    
+
     guest_port = strtol(p, &r, 0);
     if (r == p)
         goto fail;
-    
+
     if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
         fprintf(stderr, "qemu: could not set up redirection\n");
         exit(1);
@@ -1441,7 +1444,7 @@
     fprintf(stderr, "qemu: syntax: -redir 
[tcp|udp]:host-port:[guest-host]:guest-port\n");
     exit(1);
 }
-    
+
 #ifndef _WIN32
 
 char smb_dir[1024];
@@ -1460,7 +1463,7 @@
             break;
         if (strcmp(de->d_name, ".") != 0 &&
             strcmp(de->d_name, "..") != 0) {
-            snprintf(filename, sizeof(filename), "%s/%s", 
+            snprintf(filename, sizeof(filename), "%s/%s",
                      smb_dir, de->d_name);
             unlink(filename);
         }
@@ -1488,13 +1491,13 @@
         exit(1);
     }
     snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
-    
+
     f = fopen(smb_conf, "w");
     if (!f) {
         fprintf(stderr, "qemu: could not create samba server configuration 
file '%s'\n", smb_conf);
         exit(1);
     }
-    fprintf(f, 
+    fprintf(f,
             "[global]\n"
             "pid directory=%s\n"
             "lock directory=%s\n"
@@ -1516,7 +1519,7 @@
 
     snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s",
              smb_conf);
-    
+
     slirp_add_exec(0, smb_cmdline, 4, 139);
 }
 
@@ -1550,7 +1553,7 @@
 {
     struct ifreq ifr;
     int fd, ret;
-    
+
     fd = open("/dev/net/tun", O_RDWR);
     if (fd < 0) {
         fprintf(stderr, "warning: could not open /dev/net/tun: no virtual 
network emulation\n");
@@ -1565,7 +1568,7 @@
         close(fd);
         return -1;
     }
-    printf("Connected to host network interface: %s\n", ifr.ifr_name);
+    fprintf(logfile, "Connected to host network interface: %s\n", 
ifr.ifr_name);
     pstrcpy(ifname, ifname_size, ifr.ifr_name);
     fcntl(fd, F_SETFL, O_NONBLOCK);
     return fd;
@@ -1577,8 +1580,8 @@
     write(nd->fd, buf, size);
 }
 
-static void tun_add_read_packet(NetDriverState *nd, 
-                                IOCanRWHandler *fd_can_read, 
+static void tun_add_read_packet(NetDriverState *nd,
+                                IOCanRWHandler *fd_can_read,
                                 IOReadHandler *fd_read, void *opaque)
 {
     qemu_add_fd_event_read_handler(nd->fd, fd_can_read, fd_read, opaque);
@@ -1660,7 +1663,7 @@
 #if !defined(CONFIG_SOFTMMU)
 /***********************************************************/
 /* cpu signal handler */
-static void host_segv_handler(int host_signum, siginfo_t *info, 
+static void host_segv_handler(int host_signum, siginfo_t *info,
                               void *puc)
 {
     abort();
@@ -1686,7 +1689,7 @@
 static IOHandlerRecord *first_io_handler;
 static IOHandlerRecord *first_eventio_handler;
 
-int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 
+int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
                              IOReadHandler *fd_read, void *opaque)
 {
     IOHandlerRecord *ioh;
@@ -1703,7 +1706,7 @@
     return 0;
 }
 
-int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read, 
+int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read,
                              IOReadHandler *fd_read, void *opaque)
 {
     IOHandlerRecord *ioh;
@@ -1835,8 +1838,8 @@
 
 static SaveStateEntry *first_se;
 
-int register_savevm(const char *idstr, 
-                    int instance_id, 
+int register_savevm(const char *idstr,
+                    int instance_id,
                     int version_id,
                     SaveStateHandler *save_state,
                     LoadStateHandler *load_state,
@@ -1896,7 +1899,7 @@
         /* record size: filled later */
         len_pos = ftell(f);
         qemu_put_be32(f, 0);
-        
+
         se->save_state(f, se->opaque);
 
         /* fill record size */
@@ -1920,7 +1923,7 @@
     SaveStateEntry *se;
 
     for(se = first_se; se != NULL; se = se->next) {
-        if (!strcmp(se->idstr, idstr) && 
+        if (!strcmp(se->idstr, idstr) &&
             instance_id == se->instance_id)
             return se;
     }
@@ -1935,7 +1938,7 @@
     int saved_vm_running;
     unsigned int v;
     char idstr[256];
-    
+
     saved_vm_running = vm_running;
     vm_stop(0);
 
@@ -1968,18 +1971,18 @@
         version_id = qemu_get_be32(f);
         record_len = qemu_get_be32(f);
 #if 0
-        printf("idstr=%s instance=0x%x version=%d len=%d\n", 
+        printf("idstr=%s instance=0x%x version=%d len=%d\n",
                idstr, instance_id, version_id, record_len);
 #endif
         cur_pos = ftell(f);
         se = find_se(idstr, instance_id);
         if (!se) {
-            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not 
present in current VM\n", 
+            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not 
present in current VM\n",
                     instance_id, idstr);
         } else {
             ret = se->load_state(f, se->opaque, version_id);
             if (ret < 0) {
-                fprintf(stderr, "qemu: warning: error while loading state for 
instance 0x%x of device '%s'\n", 
+                fprintf(stderr, "qemu: warning: error while loading state for 
instance 0x%x of device '%s'\n",
                         instance_id, idstr);
             }
         }
@@ -2042,7 +2045,7 @@
             }
             ioh->max_size = max_size;
         }
-        
+
         ret = poll(ufds, pf - ufds, timeout);
         if (ret > 0) {
             /* XXX: better handling of removal */
@@ -2096,7 +2099,7 @@
     }
 }
 
-void vm_stop(int reason) 
+void vm_stop(int reason)
 {
     if (vm_running) {
         cpu_disable_ticks();
@@ -2160,14 +2163,14 @@
 void main_loop_wait(int timeout)
 {
         if (vm_running) {
-            qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
+            qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
                             qemu_get_clock(vm_clock));
             /* run dma transfers, if any */
             DMA_run();
         }
 
         /* real time timers */
-        qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
+        qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
                         qemu_get_clock(rt_clock));
 }
 
@@ -2184,19 +2187,19 @@
            "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
            "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 
master)\n"
            "-boot [a|c|d]   boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
-          "-snapshot       write to temporary files instead of disk image 
files\n"
+           "-snapshot       write to temporary files instead of disk image 
files\n"
            "-m megs         set virtual RAM size to megs MB [default=%d]\n"
            "-nographic      disable graphical output and redirect serial I/Os 
to console\n"
            "-vcpus          set CPU number of guest platform\n"
 #ifdef CONFIG_VNC
-          "-vnc port             use vnc instead of sdl\n"
-          "-vncport port         use a different port\n"
-          "-vncconnect host:port do a reverse connect\n"
+           "-vnc port             use vnc instead of sdl\n"
+           "-vncport port         use a different port\n"
+           "-vncconnect host:port do a reverse connect\n"
 #ifdef CONFIG_SDL
-          "-vnc-and-sdl    use vnc and sdl simultaneously\n"
-#endif
-#endif
-          "-k <language>   use keyboard layout (for example \"fr\" for 
french)\n"
+           "-vnc-and-sdl    use vnc and sdl simultaneously\n"
+#endif
+#endif
+           "-k <language>   use keyboard layout (for example \"fr\" for 
french)\n"
            "-enable-audio   enable audio support\n"
            "-localtime      set the real time clock to local time 
[default=utc]\n"
            "-full-screen    start in full screen\n"
@@ -2234,7 +2237,7 @@
            "-S              freeze CPU at startup (use 'c' to start 
execution)\n"
            "-s              wait gdb connection to port %d\n"
            "-p port         ioreq port for xen\n"
-           "-d domain      domain that we're serving\n"
+           "-d domain       domain that we're serving\n"
            "-hdachs c,h,s   force hard disk 0 geometry (usually qemu can guess 
it)\n"
            "-L path         set the directory for the BIOS and VGA BIOS\n"
 #ifdef USE_CODE_COPY
@@ -2408,7 +2411,7 @@
     { "serial", 1, QEMU_OPTION_serial },
     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
     { "full-screen", 0, QEMU_OPTION_full_screen },
-    
+
     /* temporary options */
     { "pci", 0, QEMU_OPTION_pci },
     { "nic-ne2000", 0, QEMU_OPTION_nic_ne2000 },
@@ -2460,7 +2463,9 @@
 }
 
 int
-setup_mapping(int xc_handle, uint32_t dom, unsigned long toptab, unsigned long 
 *mem_page_array, unsigned long *page_table_array, unsigned long v_start, 
unsigned long v_end)
+setup_mapping(int xc_handle, uint32_t dom, unsigned long toptab,
+              unsigned long  *mem_page_array, unsigned long *page_table_array,
+              unsigned long v_start, unsigned long v_end)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
     l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL};
@@ -2472,23 +2477,24 @@
 #if _LEVEL_3_
     l3_pgentry_t *vl3tab = NULL;
     unsigned long l2tab;
-    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
-                                        PROT_READ|PROT_WRITE, 
+
+    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                        PROT_READ|PROT_WRITE,
                                         toptab >> PAGE_SHIFT)) == NULL )
         goto error_out;
     for (i = 0; i < 4 ; i++) {
         l2tab = vl3tab[i] & PAGE_MASK;
         vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
-          PROT_READ|PROT_WRITE,
-          l2tab >> PAGE_SHIFT);
+                                         PROT_READ|PROT_WRITE,
+                                         l2tab >> PAGE_SHIFT);
         if(vl2tab[i] == NULL)
             goto error_out;
     }
     munmap(vl3tab, PAGE_SIZE);
     vl3tab = NULL;
 #else
-    if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
-                                           PROT_READ|PROT_WRITE, 
+    if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                           PROT_READ|PROT_WRITE,
                                            toptab >> PAGE_SHIFT)) == NULL )
         goto error_out;
 #endif
@@ -2498,8 +2504,8 @@
         if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
         {
             vl2_table = vl2tab[get_vl2_table(count, v_start)];
-            vl2e = &vl2_table[l2_table_offset(
-                v_start + (count << PAGE_SHIFT))];
+            vl2e = &vl2_table[l2_table_offset(v_start +
+                                              (count << PAGE_SHIFT))];
 
             l1tab = page_table_array[ppt_alloc++] << PAGE_SHIFT;
             if ( vl1tab != NULL )
@@ -2520,14 +2526,16 @@
         vl1e++;
     }
 error_out:
-    if(vl1tab)  munmap(vl1tab, PAGE_SIZE);
+    if (vl1tab)
+        munmap(vl1tab, PAGE_SIZE);
     for(i = 0; i < 4; i++)
         if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
     return ppt_alloc;
 }
 
 void
-unsetup_mapping(int xc_handle, uint32_t dom, unsigned long toptab, unsigned 
long v_start, unsigned long v_end)
+unsetup_mapping(int xc_handle, uint32_t dom, unsigned long toptab,
+                unsigned long v_start, unsigned long v_end)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
     l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
@@ -2537,28 +2545,29 @@
 #if _LEVEL_3_
     l3_pgentry_t *vl3tab = NULL;
     unsigned long l2tab;
-    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
-                                        PROT_READ|PROT_WRITE, 
+
+    if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                        PROT_READ|PROT_WRITE,
                                         toptab >> PAGE_SHIFT)) == NULL )
         goto error_out;
-    for (i = 0; i < 4 ; i ++){
+    for (i = 0; i < 4 ; i ++) {
         l2tab = vl3tab[i] & PAGE_MASK;
         vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
-          PROT_READ|PROT_WRITE,
-          l2tab >> PAGE_SHIFT);
-        if(vl2tab[i] == NULL)
+                                         PROT_READ|PROT_WRITE,
+                                         l2tab >> PAGE_SHIFT);
+        if (vl2tab[i] == NULL)
             goto error_out;
     }
     munmap(vl3tab, PAGE_SIZE);
     vl3tab = NULL;
 #else
-    if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
-                                        PROT_READ|PROT_WRITE, 
-                                        toptab >> PAGE_SHIFT)) == NULL )
+    if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                           PROT_READ|PROT_WRITE,
+                                           toptab >> PAGE_SHIFT)) == NULL )
         goto error_out;
 #endif
 
-    for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ){
+    for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ) {
         if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
         {
             vl2_table = vl2tab[get_vl2_table(count, v_start)];
@@ -2571,8 +2580,8 @@
                 munmap(vl1tab, PAGE_SIZE);
 
             if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
-                      PROT_READ|PROT_WRITE,
-                      l1tab >> PAGE_SHIFT)) == NULL )
+                                                PROT_READ|PROT_WRITE,
+                                                l1tab >> PAGE_SHIFT)) == NULL )
             {
                 goto error_out;
             }
@@ -2583,17 +2592,20 @@
         *vl1e = 0;
         vl1e++;
     }
+
 error_out:
-    if(vl1tab)  munmap(vl1tab, PAGE_SIZE);
+    if (vl1tab)
+        munmap(vl1tab, PAGE_SIZE);
     for(i = 0; i < 4; i++)
-        if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
+        if (vl2tab[i])
+            munmap(vl2tab[i], PAGE_SIZE);
 }
 
 void set_vram_mapping(unsigned long addr, unsigned long end)
 {
     end = addr + VGA_RAM_SIZE;
     setup_mapping(xc_handle, domid, toptab,
-      vgapage_array, freepage_array, addr, end);
+                  vgapage_array, freepage_array, addr, end);
 }
 
 void unset_vram_mapping(unsigned long addr, unsigned long end)
@@ -2633,9 +2645,7 @@
     unsigned long nr_pages, extra_pages, ram_pages, *page_array;
     extern void *shared_page;
     extern void *shared_vram;
-    /* change the qemu-dm to daemon, just like bochs dm */
-//    daemon(0, 0);
-    
+
 #if !defined(CONFIG_SOFTMMU)
     /* we never want that malloc() uses mmap() */
     mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
@@ -2668,7 +2678,7 @@
     for(i = 1; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i][0] = '\0';
     serial_device_index = 0;
-    
+
     nb_tun_fds = 0;
     net_if_type = -1;
     nb_nics = 1;
@@ -2679,7 +2689,7 @@
     macaddr[3] = 0x12;
     macaddr[4] = 0x34;
     macaddr[5] = 0x56;
-    
+
     /* init debug */
     cpu_set_log(0);
 
@@ -2697,7 +2707,7 @@
             popt = qemu_options;
             for(;;) {
                 if (!popt->name) {
-                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
+                    fprintf(stderr, "%s: invalid option -- '%s'\n",
                             argv[0], r);
                     exit(1);
                 }
@@ -2756,25 +2766,23 @@
                 nographic = 1;
                 break;
 #ifdef CONFIG_VNC
-           case QEMU_OPTION_vnc:
-            usevnc = 1;
-            break;  
-           case QEMU_OPTION_vncport:
-        {
-            const char *p;
-            p = optarg;
-            vncport= strtol(optarg, (char **)&p, 0);
-        }
-        break;
-           case QEMU_OPTION_vncconnect:
-        {
-            vncconnect=optarg;
-        }
-        break;
+            case QEMU_OPTION_vnc:
+                usevnc = 1;
+                break;
+            case QEMU_OPTION_vncport:
+                {
+                    const char *p;
+                    p = optarg;
+                    vncport= strtol(optarg, (char **)&p, 0);
+                }
+                break;
+            case QEMU_OPTION_vncconnect:
+                vncconnect = optarg;
+                break;
 #ifdef CONFIG_SDL
-           case QEMU_OPTION_vnc_and_sdl:
-               usevnc = 2;
-               break;
+            case QEMU_OPTION_vnc_and_sdl:
+                usevnc = 2;
+                break;
 #endif
 #endif
             case QEMU_OPTION_kernel:
@@ -2783,21 +2791,23 @@
             case QEMU_OPTION_append:
                 kernel_cmdline = optarg;
                 break;
-           case QEMU_OPTION_tun_fd:
+            case QEMU_OPTION_tun_fd:
                 {
                     const char *p;
                     int fd;
                     net_if_type = NET_IF_TUN;
-                    if (nb_tun_fds < MAX_NICS) {
+                    if ( nb_tun_fds < MAX_NICS ) {
                         fd = strtol(optarg, (char **)&p, 0);
                         if (*p != '\0') {
-                            fprintf(stderr, "qemu: invalid fd for network 
interface %d\n", nb_tun_fds);
+                            fprintf(stderr,
+                                    "qemu: invalid fd for network interface 
%d\n",
+                                    nb_tun_fds);
                             exit(1);
                         }
                         tun_fds[nb_tun_fds++] = fd;
                     }
                 }
-               break;
+                break;
             case QEMU_OPTION_hdc:
                 hd_filename[2] = optarg;
                 has_cdrom = 0;
@@ -2811,9 +2821,11 @@
                 break;
             case QEMU_OPTION_boot:
                 boot_device = optarg[0];
-                if (boot_device != 'a' && 
-                    boot_device != 'c' && boot_device != 'd') {
-                    fprintf(stderr, "qemu: invalid boot device '%c'\n", 
boot_device);
+                if ( boot_device != 'a' &&
+                     boot_device != 'c' &&
+                     boot_device != 'd' ) {
+                    fprintf(stderr, "qemu: invalid boot device '%c'\n",
+                                    boot_device);
                     exit(1);
                 }
                 break;
@@ -2826,7 +2838,8 @@
             case QEMU_OPTION_nics:
                 nb_nics = atoi(optarg);
                 if (nb_nics < 0 || nb_nics > MAX_NICS) {
-                    fprintf(stderr, "qemu: invalid number of network 
interfaces\n");
+                    fprintf(stderr,
+                            "qemu: invalid number of network interfaces\n");
                     exit(1);
                 }
                 break;
@@ -2837,16 +2850,18 @@
                 {
                     const char *p;
                     int i;
+
                     p = optarg;
-                    for(i = 0; i < 6; i++) {
+                    for (i = 0; i < 6; i++) {
                         macaddr[i] = strtol(p, (char **)&p, 16);
                         if (i == 5) {
-                            if (*p != '\0') 
+                            if (*p != '\0')
                                 goto macaddr_error;
                         } else {
                             if (*p != ':') {
                             macaddr_error:
-                                fprintf(stderr, "qemu: invalid syntax for 
ethernet address\n");
+                                fprintf(stderr, "qemu: invalid syntax "
+                                                "for ethernet address\n");
                                 exit(1);
                             }
                             p++;
@@ -2856,18 +2871,18 @@
                 break;
 #ifdef CONFIG_SLIRP
             case QEMU_OPTION_tftp:
-               tftp_prefix = optarg;
+                tftp_prefix = optarg;
                 break;
 #ifndef _WIN32
             case QEMU_OPTION_smb:
-               net_slirp_smb(optarg);
+                net_slirp_smb(optarg);
                 break;
 #endif
             case QEMU_OPTION_user_net:
                 net_if_type = NET_IF_USER;
                 break;
             case QEMU_OPTION_redir:
-                net_slirp_redir(optarg);                
+                net_slirp_redir(optarg);
                 break;
 #endif
             case QEMU_OPTION_dummy_net:
@@ -2886,24 +2901,23 @@
                 break;
             case QEMU_OPTION_d:
                 {
-                  domid = atoi(optarg);
-                  printf("domid: %d\n", domid);
+                    domid = atoi(optarg);
+                    fprintf(logfile, "domid: %d\n", domid);
                 }
                 break;
-
             case QEMU_OPTION_p:
                 {
-                  extern uint16_t ioreq_remote_port;
-                  ioreq_remote_port = atoi(optarg);
-                  printf("port: %d\n", ioreq_remote_port);
+                    extern evtchn_port_t ioreq_remote_port;
+                    ioreq_remote_port = atoi(optarg);
+                    fprintf(logfile, "eport: %d\n", ioreq_remote_port);
                 }
                 break;
             case QEMU_OPTION_l:
                 {
-                  int mask;
-                  mask = cpu_str_to_log_mask(optarg);
-                  printf("mask: %x\n", mask);
-                  cpu_set_log(mask);
+                    int mask;
+                    mask = cpu_str_to_log_mask(optarg);
+                    fprintf(logfile, "mask: %x\n", mask);
+                    cpu_set_log(mask);
                 }
                 break;
             case QEMU_OPTION_n:
@@ -2935,9 +2949,9 @@
             case QEMU_OPTION_prep:
                 prep_enabled = 1;
                 break;
-           case QEMU_OPTION_k:
-               keyboard_layout = optarg;
-               break;
+            case QEMU_OPTION_k:
+                keyboard_layout = optarg;
+                break;
             case QEMU_OPTION_localtime:
                 rtc_utc = 0;
                 break;
@@ -2953,8 +2967,8 @@
                         fprintf(stderr, "qemu: invalid vgaacc option\n");
                         exit(1);
                     }
-                    break;
                 }
+                break;
             case QEMU_OPTION_std_vga:
                 cirrus_vga_enabled = 0;
                 break;
@@ -2978,7 +2992,7 @@
                     if (*p == 'x') {
                         p++;
                         depth = strtol(p, (char **)&p, 10);
-                        if (depth != 8 && depth != 15 && depth != 16 && 
+                        if (depth != 8 && depth != 15 && depth != 16 &&
                             depth != 24 && depth != 32)
                             goto graphic_error;
                     } else if (*p == '\0') {
@@ -2986,7 +3000,7 @@
                     } else {
                         goto graphic_error;
                     }
-                    
+
                     graphic_width = w;
                     graphic_height = h;
                     graphic_depth = depth;
@@ -3000,13 +3014,13 @@
                     fprintf(stderr, "qemu: too many serial ports\n");
                     exit(1);
                 }
-                pstrcpy(serial_devices[serial_device_index], 
+                pstrcpy(serial_devices[serial_device_index],
                         sizeof(serial_devices[0]), optarg);
                 serial_device_index++;
                 break;
-           case QEMU_OPTION_loadvm:
-               loadvm = optarg;
-               break;
+            case QEMU_OPTION_loadvm:
+                loadvm = optarg;
+                break;
             case QEMU_OPTION_full_screen:
                 full_screen = 1;
                 break;
@@ -3015,11 +3029,11 @@
     }
 
     linux_boot = (kernel_filename != NULL);
-        
-    if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
-        fd_filename[0] == '\0')
+
+    if ( !linux_boot && hd_filename[0] == '\0' &&
+         hd_filename[2] == '\0' && fd_filename[0] == '\0' )
         help();
-    
+
     /* boot to cd by default if no hard disk */
     if (hd_filename[0] == '\0' && boot_device == 'c') {
         if (fd_filename[0] != '\0')
@@ -3102,89 +3116,96 @@
     nr_pages = info.nr_pages + extra_pages;
 
     if ( xc_domain_setmaxmem(xc_handle, domid,
-            (nr_pages) * PAGE_SIZE/1024 ) != 0)
+                             (nr_pages) * PAGE_SIZE/1024 ) != 0)
     {
-        perror("set maxmem");
+        fprintf(logfile, "set maxmem returned error %d\n", errno);
         exit(-1);
     }
-   
+
     if ( (page_array = (unsigned long *)
-         malloc(nr_pages * sizeof(unsigned long))) == NULL)
+                        malloc(nr_pages * sizeof(unsigned long))) == NULL)
     {
-           perror("malloc");
-           exit(-1);
-    }
-
-    if (xc_domain_memory_increase_reservation(xc_handle, domid, 
-          extra_pages , 0, 0, NULL) != 0) {
-        perror("increase reservation");
+        fprintf(logfile, "malloc returned error %d\n", errno);
+        exit(-1);
+    }
+
+    if (xc_domain_memory_increase_reservation(xc_handle, domid,
+                                              extra_pages , 0, 0, NULL) != 0)
+    {
+        fprintf(logfile, "increase reservation returned error %d\n", errno);
         exit(-1);
     }
 
 #if defined(__i386__) || defined(__x86_64__)
     if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
     {
-           perror("xc_get_pfn_list");
-           exit(-1);
-    }
-
-    if ((phys_ram_base =  xc_map_foreign_batch(xc_handle, domid,
-                                                PROT_READ|PROT_WRITE,
-                                                page_array,
-                                                ram_pages - 1)) == 0) {
-           perror("xc_map_foreign_batch");
-           exit(-1);
+        fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
+        exit(-1);
+    }
+
+    if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
+                          PROT_READ|PROT_WRITE,
+                          page_array,
+                          ram_pages - 1)) == 0 )
+    {
+        fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
+        exit(-1);
     }
 
     shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                      PROT_READ|PROT_WRITE,
-                                      page_array[ram_pages - 1]);
+                                       PROT_READ|PROT_WRITE,
+                                       page_array[ram_pages - 1]);
 
     vgapage_array = &page_array[nr_pages - vgaram_pages];
 
-    if ((shared_vram =  xc_map_foreign_batch(xc_handle, domid,
-                                                PROT_READ|PROT_WRITE,
-                                                vgapage_array,
-                                                vgaram_pages)) == 0) {
-           perror("xc_map_foreign_batch vgaram ");
-           exit(-1);
-     }
+    if ( (shared_vram =  xc_map_foreign_batch(xc_handle, domid,
+                                              PROT_READ|PROT_WRITE,
+                                              vgapage_array,
+                                              vgaram_pages)) == 0)
+    {
+        fprintf(logfile,
+                "xc_map_foreign_batch vgaram returned error %d\n", errno);
+        exit(-1);
+    }
 
     memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
     toptab = page_array[ram_pages] << PAGE_SHIFT;
 
     vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                      PROT_READ|PROT_WRITE,
-                                      page_array[ram_pages]);
+                                      PROT_READ|PROT_WRITE,
+                                      page_array[ram_pages]);
 
     freepage_array = &page_array[nr_pages - extra_pages];
 #elif defined(__ia64__)
-    if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, ram_pages) != 
ram_pages)
+    if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, ram_pages)
+         != ram_pages )
     {
-        perror("xc_ia64_get_pfn_list");
+        fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
         exit(-1);
     }
 
-    if ((phys_ram_base =  xc_map_foreign_batch(xc_handle, domid,
-                                                PROT_READ|PROT_WRITE,
-                                                page_array,
-                                                ram_pages)) == 0) {
-           perror("xc_map_foreign_batch");
-           exit(-1);
-    }
-
-    if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 
IO_PAGE_START>>PAGE_SHIFT, 1) != 1)
+    if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
+                          PROT_READ|PROT_WRITE,
+                          page_array,
+                          ram_pages)) == 0 )
     {
-        perror("xc_ia64_get_pfn_list");
+        fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
         exit(-1);
     }
 
+    if ( xc_ia64_get_pfn_list(xc_handle, domid,
+                              page_array, IO_PAGE_START >> PAGE_SHIFT, 1) != 1 
)
+    {
+        fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
+        exit(-1);
+    }
+
     shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                      PROT_READ|PROT_WRITE,
-                                      page_array[0]);
-#endif 
-
-    fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1), 
+                                       PROT_READ|PROT_WRITE,
+                                       page_array[0]);
+#endif
+
+    fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1),
            (page_array[nr_pages - 1]));
 
     /* we always create the cdrom drive, even if no disk is there */
@@ -3207,7 +3228,7 @@
                         hd_filename[i]);
                 exit(1);
             }
-            if (i == 0 && cyls != 0) 
+            if (i == 0 && cyls != 0)
                 bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
         }
     }
@@ -3246,23 +3267,23 @@
     if (nographic) {
         dumb_display_init(ds);
     } else {
-       if (usevnc) {
+        if (usevnc) {
 #ifdef CONFIG_VNC
-           vnc_display_init(ds, (usevnc==2), vncport, vncconnect);
+            vnc_display_init(ds, (usevnc==2), vncport, vncconnect);
 #else
-           perror("qemu not configured with vnc support");
-#endif
-       } else {
+            fprintf(logfile, "qemu not configured with vnc support\n");
+#endif
+        } else {
 #ifdef CONFIG_SDL
-        sdl_display_init(ds, full_screen);
+            sdl_display_init(ds, full_screen);
 #else
-        dumb_display_init(ds);
-#endif
-    }
+            dumb_display_init(ds);
+#endif
+        }
     }
 
     vga_console = graphic_console_init(ds);
-    
+
     monitor_hd = qemu_chr_open(monitor_device);
     if (!monitor_hd) {
         fprintf(stderr, "qemu: could not open monitor device '%s'\n", 
monitor_device);
@@ -3274,7 +3295,7 @@
         if (serial_devices[i][0] != '\0') {
             serial_hds[i] = qemu_chr_open(serial_devices[i]);
             if (!serial_hds[i]) {
-                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
+                fprintf(stderr, "qemu: could not open serial device '%s'\n",
                         serial_devices[i]);
                 exit(1);
             }
@@ -3285,7 +3306,7 @@
 
     /* setup cpu signal handlers for MMU / self modifying code handling */
 #if !defined(CONFIG_SOFTMMU)
-    
+
 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
     {
         stack_t stk;
@@ -3295,14 +3316,14 @@
         stk.ss_flags = 0;
 
         if (sigaltstack(&stk, NULL) < 0) {
-            perror("sigaltstack");
+            fprintf(logfile, "sigaltstack returned error %d\n", errno);
             exit(1);
         }
     }
 #endif
     {
         struct sigaction act;
-        
+
         sigfillset(&act.sa_mask);
         act.sa_flags = SA_SIGINFO;
 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
@@ -3334,8 +3355,8 @@
             kernel_filename, kernel_cmdline, initrd_filename);
 #elif defined(TARGET_PPC)
     ppc_init(ram_size, vga_ram_size, boot_device,
-            ds, fd_filename, snapshot,
-            kernel_filename, kernel_cmdline, initrd_filename);
+            ds, fd_filename, snapshot,
+            kernel_filename, kernel_cmdline, initrd_filename);
 #elif defined(TARGET_SPARC)
     sun4m_init(ram_size, vga_ram_size, boot_device,
             ds, fd_filename, snapshot,
@@ -3351,13 +3372,13 @@
 #ifdef CONFIG_GDBSTUB
     if (use_gdbstub) {
         if (gdbserver_start(gdbstub_port) < 0) {
-            fprintf(stderr, "Could not open gdbserver socket on port %d\n", 
+            fprintf(stderr, "Could not open gdbserver socket on port %d\n",
                     gdbstub_port);
             exit(1);
         } else {
-            printf("Waiting gdb connection on port %d\n", gdbstub_port);
+            fprintf(logfile, "Waiting gdb connection on port %d\n", 
gdbstub_port);
         }
-    } else 
+    } else
 #endif
     if (loadvm)
         qemu_loadvm(loadvm);
@@ -3389,7 +3410,7 @@
                 n = read(ioh->fd, buf, max_size);
                 if (n >= 0) {
                     ioh->fd_read(ioh->opaque, buf, n);
-                } 
+                }
             }
         }
     }
@@ -3411,5 +3432,3 @@
         }
     }
 }
-
-
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/Makefile      Fri Dec  2 18:52:25 2005
@@ -49,6 +49,11 @@
 CFLAGS   += -O3
 CFLAGS   += -fno-strict-aliasing
 CFLAGS   += $(INCLUDES) -I.
+
+# Define this to make it possible to run valgrind on code linked with these
+# libraries.
+#CFLAGS   += -DVALGRIND -O0 -ggdb3
+
 # Get gcc to generate the dependencies for us.
 CFLAGS   += -Wp,-MD,.$(@F).d
 LDFLAGS  += -L.
@@ -77,17 +82,6 @@
        echo "***********************************************************"; \
        false; \
        fi
-
-LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
-mk-symlinks:
-       [ -e xen/linux ] || mkdir -p xen/linux
-       [ -e xen/io ]    || mkdir -p xen/io
-       ( cd xen >/dev/null ; \
-         ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
-       ( cd xen/io >/dev/null ; \
-          ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
-       ( cd xen/linux >/dev/null ; \
-         ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
 
 install: build
        [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) 
$(DESTDIR)/usr/$(LIBDIR)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_bvtsched.c
--- a/tools/libxc/xc_bvtsched.c Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_bvtsched.c Fri Dec  2 18:52:25 2005
@@ -11,7 +11,7 @@
 int xc_bvtsched_global_set(int xc_handle,
                            unsigned long ctx_allow)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
 
     op.cmd = DOM0_SCHEDCTL;
     op.u.schedctl.sched_id = SCHED_BVT;
@@ -24,7 +24,7 @@
 int xc_bvtsched_global_get(int xc_handle,
                            unsigned long *ctx_allow)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     int ret;
     
     op.cmd = DOM0_SCHEDCTL;
@@ -46,7 +46,7 @@
                            long long warpl,
                            long long warpu)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     struct bvt_adjdom *bvtadj = &op.u.adjustdom.u.bvt;
 
     op.cmd = DOM0_ADJUSTDOM;
@@ -72,7 +72,7 @@
                            long long *warpu)
 {
     
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     int ret;
     struct bvt_adjdom *adjptr = &op.u.adjustdom.u.bvt;
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_domain.c   Fri Dec  2 18:52:25 2005
@@ -15,7 +15,7 @@
                      uint32_t *pdomid)
 {
     int err;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
 
     op.cmd = DOM0_CREATEDOMAIN;
     op.u.createdomain.domain = (domid_t)*pdomid;
@@ -32,7 +32,7 @@
 int xc_domain_pause(int xc_handle, 
                     uint32_t domid)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_PAUSEDOMAIN;
     op.u.pausedomain.domain = (domid_t)domid;
     return do_dom0_op(xc_handle, &op);
@@ -42,7 +42,7 @@
 int xc_domain_unpause(int xc_handle,
                       uint32_t domid)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_UNPAUSEDOMAIN;
     op.u.unpausedomain.domain = (domid_t)domid;
     return do_dom0_op(xc_handle, &op);
@@ -52,7 +52,7 @@
 int xc_domain_destroy(int xc_handle,
                       uint32_t domid)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_DESTROYDOMAIN;
     op.u.destroydomain.domain = (domid_t)domid;
     return do_dom0_op(xc_handle, &op);
@@ -63,7 +63,7 @@
                      int vcpu,
                      cpumap_t cpumap)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_PINCPUDOMAIN;
     op.u.pincpudomain.domain  = (domid_t)domid;
     op.u.pincpudomain.vcpu    = vcpu;
@@ -79,7 +79,7 @@
 {
     unsigned int nr_doms;
     uint32_t next_domid = first_domid;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     int rc = 0; 
 
     memset(info, 0, max_doms*sizeof(xc_dominfo_t));
@@ -134,7 +134,7 @@
                           xc_domaininfo_t *info)
 {
     int ret = 0;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
 
     if ( mlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
         return -1;
@@ -161,7 +161,7 @@
                                vcpu_guest_context_t *ctxt)
 {
     int rc;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
 
     op.cmd = DOM0_GETVCPUCONTEXT;
     op.u.getvcpucontext.domain = (domid_t)domid;
@@ -187,7 +187,7 @@
                       xc_shadow_control_stats_t *stats )
 {
     int rc;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_SHADOW_CONTROL;
     op.u.shadow_control.domain = (domid_t)domid;
     op.u.shadow_control.op     = sop;
@@ -250,7 +250,7 @@
                         uint32_t domid, 
                         unsigned int max_memkb)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_SETDOMAINMAXMEM;
     op.u.setdomainmaxmem.domain = (domid_t)domid;
     op.u.setdomainmaxmem.max_memkb = max_memkb;
@@ -328,7 +328,7 @@
 
 int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_MAX_VCPUS;
     op.u.max_vcpus.domain = (domid_t)domid;
     op.u.max_vcpus.max    = max;
@@ -338,7 +338,7 @@
 int xc_domain_sethandle(int xc_handle, uint32_t domid, 
                         xen_domain_handle_t handle)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_SETDOMAINHANDLE;
     op.u.setdomainhandle.domain = (domid_t)domid;
     memcpy(op.u.setdomainhandle.handle, handle, sizeof(xen_domain_handle_t));
@@ -351,8 +351,7 @@
                             xc_vcpuinfo_t *info)
 {
     int rc;
-    dom0_op_t op;
-
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_GETVCPUINFO;
     op.u.getvcpuinfo.domain = (domid_t)domid;
     op.u.getvcpuinfo.vcpu   = (uint16_t)vcpu;
@@ -366,11 +365,11 @@
 
 int xc_domain_ioport_permission(int xc_handle,
                                 uint32_t domid,
-                                uint16_t first_port,
-                                uint16_t nr_ports,
-                                uint16_t allow_access)
-{
-    dom0_op_t op;
+                                uint32_t first_port,
+                                uint32_t nr_ports,
+                                uint32_t allow_access)
+{
+    DECLARE_DOM0_OP;
 
     op.cmd = DOM0_IOPORT_PERMISSION;
     op.u.ioport_permission.domain = (domid_t)domid;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_evtchn.c
--- a/tools/libxc/xc_evtchn.c   Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_evtchn.c   Fri Dec  2 18:52:25 2005
@@ -12,7 +12,7 @@
 static int do_evtchn_op(int xc_handle, evtchn_op_t *op)
 {
     int ret = -1;
-    privcmd_hypercall_t hypercall;
+    DECLARE_HYPERCALL;
 
     hypercall.op     = __HYPERVISOR_event_channel_op;
     hypercall.arg[0] = (unsigned long)op;
@@ -51,7 +51,7 @@
 
 int xc_evtchn_status(int xc_handle,
                      uint32_t dom,
-                     int port,
+                     evtchn_port_t port,
                      xc_evtchn_status_t *status)
 {
     int         rc;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_gnttab.c
--- a/tools/libxc/xc_gnttab.c   Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_gnttab.c   Fri Dec  2 18:52:25 2005
@@ -17,7 +17,7 @@
              unsigned long count)
 {
     int ret = -1;
-    privcmd_hypercall_t hypercall;
+    DECLARE_HYPERCALL;
 
     hypercall.op     = __HYPERVISOR_grant_table_op;
     hypercall.arg[0] = cmd;
@@ -42,9 +42,10 @@
 int xc_gnttab_map_grant_ref(int         xc_handle,
                             uint64_t    host_virt_addr,
                             uint32_t    dom,
-                            uint16_t    ref,
+                            grant_ref_t ref,
                             uint16_t    flags,
-                            int16_t    *handle,
+                            int16_t    *status,
+                            grant_handle_t *handle,
                             uint64_t   *dev_bus_addr)
 {
     struct gnttab_map_grant_ref op;
@@ -58,6 +59,7 @@
     if ( (rc = do_gnttab_op(xc_handle, GNTTABOP_map_grant_ref,
                             &op, 1)) == 0 )
     {
+        *status         = op.status;
         *handle         = op.handle;
         *dev_bus_addr   = op.dev_bus_addr;
     }
@@ -69,7 +71,7 @@
 int xc_gnttab_unmap_grant_ref(int       xc_handle,
                               uint64_t  host_virt_addr,
                               uint64_t  dev_bus_addr,
-                              uint16_t  handle,
+                              grant_handle_t handle,
                               int16_t  *status)
 {
     struct gnttab_unmap_grant_ref op;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_linux_build.c      Fri Dec  2 18:52:25 2005
@@ -657,7 +657,7 @@
     memset(shared_info, 0, sizeof(shared_info_t));
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
     munmap(shared_info, PAGE_SIZE);
 
@@ -692,7 +692,8 @@
                    unsigned int console_evtchn,
                    unsigned long *console_mfn)
 {
-    dom0_op_t launch_op, op;
+    dom0_op_t launch_op;
+    DECLARE_DOM0_OP;
     int initrd_fd = -1;
     gzFile initrd_gfd = NULL;
     int rc, i;
@@ -727,6 +728,10 @@
             goto error_out;
         }
     }
+
+#ifdef VALGRIND
+    memset(&st_ctxt, 0, sizeof(st_ctxt));
+#endif
 
     if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
     {   
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_linux_restore.c    Fri Dec  2 18:52:25 2005
@@ -78,6 +78,7 @@
             pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
             
             if(pfn >= max_pfn) { 
+                /* This "page table page" is probably not one; bail. */
                 ERR("Frame number in type %lu page table is out of range: "
                     "i=%d pfn=0x%lx max_pfn=%lu", 
                     type >> 28, i, pfn, max_pfn);
@@ -106,11 +107,12 @@
                      unsigned int store_evtchn, unsigned long *store_mfn,
                      unsigned int console_evtchn, unsigned long *console_mfn)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     int rc = 1, i, n;
     unsigned long mfn, pfn; 
     unsigned int prev_pc, this_pc;
     int verify = 0;
+    int nraces = 0; 
 
     /* The new domain's shared-info frame number. */
     unsigned long shared_info_frame;
@@ -219,7 +221,7 @@
     
     if(xc_domain_memory_increase_reservation(
            xc_handle, dom, max_pfn, 0, 0, NULL) != 0) { 
-        ERR("Failed to increase reservation by %lx KB\n", PFN_TO_KB(max_pfn));
+        ERR("Failed to increase reservation by %lx KB", PFN_TO_KB(max_pfn));
         errno = ENOMEM;
         goto out;
     }
@@ -344,8 +346,15 @@
                 if(pt_levels != 3 || pagetype != L1TAB) { 
 
                     if(!uncanonicalize_pagetable(pagetype, page)) {
-                        ERR("failed uncanonicalize pt!\n"); 
-                        goto out; 
+                        /* 
+                        ** Failing to uncanonicalize a page table can be ok
+                        ** under live migration since the pages type may have
+                        ** changed by now (and we'll get an update later). 
+                        */
+                        DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n", 
+                                pagetype >> 28, pfn, mfn); 
+                        nraces++; 
+                        continue; 
                     }
 
                 } 
@@ -394,7 +403,7 @@
         n+= j; /* crude stats */
     }
 
-    DPRINTF("Received all pages\n");
+    DPRINTF("Received all pages (%d races)\n", nraces);
 
     if(pt_levels == 3) { 
 
@@ -478,7 +487,7 @@
                 for(k = 0; k < j; k++) {
                     if(!uncanonicalize_pagetable(L1TAB, 
                                                  region_base + k*PAGE_SIZE)) {
-                        ERR("failed uncanonicalize pt!\n"); 
+                        ERR("failed uncanonicalize pt!"); 
                         goto out; 
                     } 
                 }
@@ -662,7 +671,7 @@
     memset(&(shared_info->evtchn_pending[0]), 0,
            sizeof (shared_info->evtchn_pending));
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_data[i].evtchn_pending_sel = 0;
+        shared_info->vcpu_info[i].evtchn_pending_sel = 0;
 
     /* Copy saved contents of shared-info page. No checking needed. */
     page = xc_map_foreign_range(
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_linux_save.c       Fri Dec  2 18:52:25 2005
@@ -44,6 +44,9 @@
 /* Live mapping of system MFN to PFN table. */
 static unsigned long *live_m2p = NULL;
 
+/* grep fodder: machine_to_phys */
+
+#define mfn_to_pfn(_mfn) live_m2p[(_mfn)]
 
 /*
  * Returns TRUE if the given machine frame number has a unique mapping
@@ -51,8 +54,8 @@
  */
 #define MFN_IS_IN_PSEUDOPHYS_MAP(_mfn)          \
 (((_mfn) < (max_mfn)) &&                        \
- ((live_m2p[_mfn] < (max_pfn)) &&               \
-  (live_p2m[live_m2p[_mfn]] == (_mfn))))
+ ((mfn_to_pfn(_mfn) < (max_pfn)) &&               \
+  (live_p2m[mfn_to_pfn(_mfn)] == (_mfn))))
     
  
 /* Returns TRUE if MFN is successfully converted to a PFN. */
@@ -63,7 +66,7 @@
     if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )                       \
         _res = 0;                                               \
     else                                                        \
-        *(_pmfn) = live_m2p[mfn];                               \
+        *(_pmfn) = mfn_to_pfn(mfn);                             \
     _res;                                                       \
 })
 
@@ -454,6 +457,15 @@
             xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; 
     }
 
+    if (pt_levels == 4 && type == L4TAB) { 
+        /*
+        ** XXX SMH: should compute these from hvirt_start (which we have) 
+        ** and hvirt_end (which we don't) 
+        */
+        xen_start = 256; 
+        xen_end   = 272; 
+    }
+
     /* Now iterate through the page table, canonicalizing each PTE */
     for (i = 0; i < pte_last; i++ ) {
 
@@ -470,19 +482,14 @@
         if (pte & _PAGE_PRESENT) {
             
             mfn = (pte >> PAGE_SHIFT) & 0xfffffff;      
-            pfn = live_m2p[mfn];
-            
             if (!MFN_IS_IN_PSEUDOPHYS_MAP(mfn)) {
-                /* I don't think this should ever happen */
-                DPRINTF("FNI: [%08lx,%d] pte=%llx,"
-                        " mfn=%08lx, pfn=%08lx [mfn]=%08lx\n",
-                        type, i, (unsigned long long)pte, mfn, 
-                        live_m2p[mfn],
-                        (live_m2p[mfn] < max_pfn) ? 
-                        live_p2m[live_m2p[mfn]] : 0xdeadbeaf);
-                
-                pfn = 0; /* be suspicious */
-            }
+                /* This will happen if the type info is stale which 
+                   is quite feasible under live migration */
+                DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n",
+                        type, i, (unsigned long long)pte, mfn); 
+                pfn = 0; /* zap it - we'll retransmit this page later */
+            } else 
+                pfn = mfn_to_pfn(mfn);
             
             pte &= 0xffffff0000000fffULL;
             pte |= (uint64_t)pfn << PAGE_SHIFT;
@@ -504,7 +511,7 @@
                                  unsigned long max_mfn, 
                                  int prot) 
 { 
-    privcmd_m2pmfns_t m2p_mfns; 
+    struct xen_machphys_mfn_list xmml;
     privcmd_mmap_t ioctlx; 
     privcmd_mmap_entry_t *entries; 
     unsigned long m2p_chunks, m2p_size; 
@@ -514,50 +521,45 @@
     m2p_size   = M2P_SIZE(max_mfn); 
     m2p_chunks = M2P_CHUNKS(max_mfn); 
 
-
-    m2p_mfns.num = m2p_chunks; 
-
-    if(!(m2p_mfns.arr = malloc(m2p_chunks * sizeof(unsigned long)))) { 
-        ERR("failed to allocate space for m2p mfns!\n"); 
+    xmml.max_extents = m2p_chunks;
+    if (!(xmml.extent_start = malloc(m2p_chunks * sizeof(unsigned long)))) { 
+        ERR("failed to allocate space for m2p mfns"); 
         return NULL; 
     } 
 
-    if (ioctl(xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS, &m2p_mfns) < 0) {
-        ERR("xc_get_m2p_mfns:"); 
+    if (xc_memory_op(xc_handle, XENMEM_machphys_mfn_list, &xmml) ||
+        (xmml.nr_extents != m2p_chunks)) {
+        ERR("xc_get_m2p_mfns"); 
         return NULL;
     }
 
-    if((m2p = mmap(NULL, m2p_size, prot, 
-                   MAP_SHARED, xc_handle, 0)) == MAP_FAILED) {
+    if ((m2p = mmap(NULL, m2p_size, prot, 
+                    MAP_SHARED, xc_handle, 0)) == MAP_FAILED) {
         ERR("failed to mmap m2p"); 
         return NULL; 
     } 
-    
-
-    if(!(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t)))) { 
-        ERR("failed to allocate space for mmap entries!\n"); 
+
+    if (!(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t)))) { 
+        ERR("failed to allocate space for mmap entries"); 
         return NULL; 
     } 
-
 
     ioctlx.num   = m2p_chunks;
     ioctlx.dom   = DOMID_XEN; 
     ioctlx.entry = entries; 
     
-    for(i=0; i < m2p_chunks; i++) { 
-        
+    for (i=0; i < m2p_chunks; i++) { 
         entries[i].va = (unsigned long)(((void *)m2p) + (i * M2P_CHUNK_SIZE)); 
-        entries[i].mfn = m2p_mfns.arr[i]; 
+        entries[i].mfn = xmml.extent_start[i];
         entries[i].npages = M2P_CHUNK_SIZE >> PAGE_SHIFT;
-
-    }
-
-    if((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
+    }
+
+    if ((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
         ERR("ioctl_mmap failed (rc = %d)", rc); 
         return NULL; 
     }
-        
-    free(m2p_mfns.arr); 
+
+    free(xmml.extent_start);
     free(entries); 
 
     return m2p; 
@@ -675,7 +677,7 @@
                              live_shinfo->arch.pfn_to_mfn_frame_list_list);
 
     if (!live_p2m_frame_list_list) {
-        ERR("Couldn't map p2m_frame_list_list");
+        ERR("Couldn't map p2m_frame_list_list (errno %d)", errno);
         goto out;
     }
 
@@ -728,12 +730,6 @@
     }
 
     /* Domain is still running at this point */
-
-    if (live && (pt_levels != 2)) {
-        ERR("Live migration supported only for 32-bit non-pae");
-        goto out;
-    }
-
     if (live) {
 
         if (xc_shadow_control(xc_handle, dom, 
@@ -798,6 +794,7 @@
     pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(unsigned long));
 
     if ((pfn_type == NULL) || (pfn_batch == NULL)) {
+        ERR("failed to alloc memory for pfn_type and/or pfn_batch arrays"); 
         errno = ENOMEM;
         goto out;
     }
@@ -817,9 +814,9 @@
         for (i = 0; i < max_pfn; i++) {
 
             mfn = live_p2m[i];
-            if((live_m2p[mfn] != i) && (mfn != 0xffffffffUL)) { 
+            if((mfn != INVALID_P2M_ENTRY) && (mfn_to_pfn(mfn) != i)) { 
                 DPRINTF("i=0x%x mfn=%lx live_m2p=%lx\n", i, 
-                        mfn, live_m2p[mfn]);
+                        mfn, mfn_to_pfn(mfn));
                 err++;
             }
         }
@@ -884,7 +881,7 @@
                     DPRINTF("%d pfn= %08lx mfn= %08lx %d  [mfn]= %08lx\n",
                             iter, (unsigned long)n, live_p2m[n],
                             test_bit(n, to_send), 
-                            live_m2p[live_p2m[n]&0xFFFFF]);
+                            mfn_to_pfn(live_p2m[n]&0xFFFFF));
                 }
                 
                 if (!last_iter && test_bit(n, to_send)&& test_bit(n, to_skip)) 
@@ -912,7 +909,7 @@
                        unless its sent sooner anyhow */
 
                     set_bit(n, to_fix);
-                    if(iter > 1)
+                    if( (iter > 1) && IS_REAL_PFN(n) )
                         DPRINTF("netbuf race: iter %d, pfn %x. mfn %lx\n",
                                 iter, n, pfn_type[batch]);
                     continue;
@@ -956,7 +953,7 @@
                             iter, 
                             (pfn_type[j] & LTAB_MASK) | pfn_batch[j],
                             pfn_type[j],
-                            live_m2p[pfn_type[j]&(~LTAB_MASK)],
+                            mfn_to_pfn(pfn_type[j]&(~LTAB_MASK)),
                             csum_page(region_base + (PAGE_SIZE*j)));
                 
                 /* canonicalise mfn->pfn */
@@ -1030,7 +1027,7 @@
 
         if (last_iter && debug){
             int minusone = -1;
-            memset( to_send, 0xff, (max_pfn+8)/8 );
+            memset(to_send, 0xff, BITMAP_SIZE); 
             debug = 0;
             fprintf(stderr, "Entering debug resend-all mode\n");
     
@@ -1143,7 +1140,7 @@
         ERR("PT base is not in range of pseudophys map");
         goto out;
     }
-    ctxt.ctrlreg[3] = live_m2p[ctxt.ctrlreg[3] >> PAGE_SHIFT] <<
+    ctxt.ctrlreg[3] = mfn_to_pfn(ctxt.ctrlreg[3] >> PAGE_SHIFT) <<
         PAGE_SHIFT;
 
     if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
@@ -1157,6 +1154,13 @@
 
  out:
 
+    if (live) {
+        if(xc_shadow_control(xc_handle, dom, DOM0_SHADOW_CONTROL_OP_OFF, 
+                             NULL, 0, NULL ) < 0) { 
+            DPRINTF("Warning - couldn't disable shadow mode");
+        }
+    }
+    
     if (live_shinfo)
         munmap(live_shinfo, PAGE_SIZE);
     
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c     Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_misc.c     Fri Dec  2 18:52:25 2005
@@ -25,7 +25,7 @@
                        int clear)
 {
     int ret;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     char *buffer = *pbuffer;
     unsigned int nr_chars = *pnr_chars;
 
@@ -52,7 +52,7 @@
                 xc_physinfo_t *put_info)
 {
     int ret;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     
     op.cmd = DOM0_PHYSINFO;
     op.interface_version = DOM0_INTERFACE_VERSION;
@@ -69,7 +69,7 @@
                 int *sched_id)
 {
     int ret;
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     
     op.cmd = DOM0_SCHED_ID;
     op.interface_version = DOM0_INTERFACE_VERSION;
@@ -83,25 +83,25 @@
 }
 
 int xc_perfc_control(int xc_handle,
-                     uint32_t op,
+                     uint32_t opcode,
                      xc_perfc_desc_t *desc)
 {
     int rc;
-    dom0_op_t dop;
+    DECLARE_DOM0_OP;
 
-    dop.cmd = DOM0_PERFCCONTROL;
-    dop.u.perfccontrol.op   = op;
-    dop.u.perfccontrol.desc = desc;
+    op.cmd = DOM0_PERFCCONTROL;
+    op.u.perfccontrol.op   = opcode;
+    op.u.perfccontrol.desc = desc;
 
-    rc = do_dom0_op(xc_handle, &dop);
+    rc = do_dom0_op(xc_handle, &op);
 
-    return (rc == 0) ? dop.u.perfccontrol.nr_counters : rc;
+    return (rc == 0) ? op.u.perfccontrol.nr_counters : rc;
 }
 
 long long xc_msr_read(int xc_handle, int cpu_mask, int msr)
 {
     int rc;    
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     
     op.cmd = DOM0_MSR;
     op.u.msr.write = 0;
@@ -117,7 +117,7 @@
                   unsigned int high)
 {
     int rc;    
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     
     op.cmd = DOM0_MSR;
     op.u.msr.write = 1;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_private.c  Fri Dec  2 18:52:25 2005
@@ -68,7 +68,7 @@
 int xc_get_pfn_type_batch(int xc_handle, 
                           uint32_t dom, int num, unsigned long *arr)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_GETPAGEFRAMEINFO2;
     op.u.getpageframeinfo2.domain = (domid_t)dom;
     op.u.getpageframeinfo2.num    = num;
@@ -81,7 +81,7 @@
                           unsigned long mfn, 
                           uint32_t dom)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_GETPAGEFRAMEINFO;
     op.u.getpageframeinfo.pfn    = mfn;
     op.u.getpageframeinfo.domain = (domid_t)dom;
@@ -99,7 +99,7 @@
     unsigned int nr_ops,
     domid_t dom)
 {
-    privcmd_hypercall_t hypercall;
+    DECLARE_HYPERCALL;
     long ret = -EINVAL;
 
     hypercall.op     = __HYPERVISOR_mmuext_op;
@@ -125,7 +125,7 @@
 static int flush_mmu_updates(int xc_handle, xc_mmu_t *mmu)
 {
     int err = 0;
-    privcmd_hypercall_t hypercall;
+    DECLARE_HYPERCALL;
 
     if ( mmu->idx == 0 )
         return 0;
@@ -188,8 +188,9 @@
                  int cmd,
                  void *arg)
 {
-    privcmd_hypercall_t hypercall;
+    DECLARE_HYPERCALL;
     struct xen_memory_reservation *reservation = arg;
+    struct xen_machphys_mfn_list *xmml = arg;
     long ret = -EINVAL;
 
     hypercall.op     = __HYPERVISOR_memory_op;
@@ -214,10 +215,17 @@
             goto out1;
         }
         break;
-    case XENMEM_maximum_ram_page:
-        if ( mlock(arg, sizeof(unsigned long)) != 0 )
+    case XENMEM_machphys_mfn_list:
+        if ( mlock(xmml, sizeof(*xmml)) != 0 )
         {
             PERROR("Could not mlock");
+            goto out1;
+        }
+        if ( mlock(xmml->extent_start,
+                   xmml->max_extents * sizeof(unsigned long)) != 0 )
+        {
+            PERROR("Could not mlock");
+            safe_munlock(xmml, sizeof(*xmml));
             goto out1;
         }
         break;
@@ -234,8 +242,10 @@
             safe_munlock(reservation->extent_start,
                          reservation->nr_extents * sizeof(unsigned long));
         break;
-    case XENMEM_maximum_ram_page:
-        safe_munlock(arg, sizeof(unsigned long));
+    case XENMEM_machphys_mfn_list:
+        safe_munlock(xmml, sizeof(*xmml));
+        safe_munlock(xmml->extent_start,
+                     xmml->max_extents * sizeof(unsigned long));
         break;
     }
 
@@ -246,7 +256,7 @@
 
 long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
 
     op.cmd = DOM0_GETVCPUINFO;
     op.u.getvcpuinfo.domain = (domid_t)domid;
@@ -265,13 +275,16 @@
                     unsigned long *pfn_buf, 
                     unsigned long max_pfns)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     int ret;
     op.cmd = DOM0_GETMEMLIST;
     op.u.getmemlist.domain   = (domid_t)domid;
     op.u.getmemlist.max_pfns = max_pfns;
     op.u.getmemlist.buffer   = pfn_buf;
 
+#ifdef VALGRIND
+    memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
+#endif
 
     if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
     {
@@ -303,7 +316,7 @@
 
 long xc_get_tot_pages(int xc_handle, uint32_t domid)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)domid;
     return (do_dom0_op(xc_handle, &op) < 0) ? 
@@ -412,6 +425,11 @@
         PERROR("Could not lock memory for version hypercall");
         return -ENOMEM;
     }
+
+#ifdef VALGRIND
+    if (argsize != 0)
+        memset(arg, 0, argsize);
+#endif
 
     rc = do_xen_version(xc_handle, cmd, arg);
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_private.h  Fri Dec  2 18:52:25 2005
@@ -16,6 +16,18 @@
 #include "xenctrl.h"
 
 #include <xen/linux/privcmd.h>
+
+/* valgrind cannot see when a hypercall has filled in some values.  For this
+   reason, we must zero the privcmd_hypercall_t or dom0_op_t instance before a
+   call, if using valgrind.  */
+#ifdef VALGRIND
+#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall = { 0 }
+#define DECLARE_DOM0_OP dom0_op_t op = { 0 }
+#else
+#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall
+#define DECLARE_DOM0_OP dom0_op_t op
+#endif
+
 
 #define PAGE_SHIFT              XC_PAGE_SHIFT
 #define PAGE_SIZE               (1UL << PAGE_SHIFT)
@@ -61,7 +73,7 @@
 
 static inline int do_xen_version(int xc_handle, int cmd, void *dest)
 {
-    privcmd_hypercall_t hypercall;
+    DECLARE_HYPERCALL;
 
     hypercall.op     = __HYPERVISOR_xen_version;
     hypercall.arg[0] = (unsigned long) cmd;
@@ -73,7 +85,7 @@
 static inline int do_dom0_op(int xc_handle, dom0_op_t *op)
 {
     int ret = -1;
-    privcmd_hypercall_t hypercall;
+    DECLARE_HYPERCALL;
 
     op->interface_version = DOM0_INTERFACE_VERSION;
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_ptrace.c   Fri Dec  2 18:52:25 2005
@@ -283,7 +283,7 @@
     int *status,
     int options)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     int retval;
     struct timespec ts;
     ts.tv_sec = 0;
@@ -323,7 +323,7 @@
     long eaddr,
     long edata)
 {
-    dom0_op_t       op;
+    DECLARE_DOM0_OP;
     int             status = 0;
     struct gdb_regs pt;
     long            retval = 0;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_sedf.c
--- a/tools/libxc/xc_sedf.c     Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_sedf.c     Fri Dec  2 18:52:25 2005
@@ -13,7 +13,7 @@
 int xc_sedf_domain_set(int xc_handle,
                           uint32_t domid, uint64_t period, uint64_t 
slice,uint64_t latency, uint16_t extratime,uint16_t weight)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     struct sedf_adjdom *p = &op.u.adjustdom.u.sedf;
 
     op.cmd = DOM0_ADJUSTDOM;
@@ -31,7 +31,7 @@
 
 int xc_sedf_domain_get(int xc_handle, uint32_t domid, uint64_t *period, 
uint64_t *slice, uint64_t* latency, uint16_t* extratime, uint16_t* weight)
 {
-    dom0_op_t op;
+    DECLARE_DOM0_OP;
     int ret;
     struct sedf_adjdom *p = &op.u.adjustdom.u.sedf;
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_tbuf.c
--- a/tools/libxc/xc_tbuf.c     Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_tbuf.c     Fri Dec  2 18:52:25 2005
@@ -10,7 +10,7 @@
 
 int xc_tbuf_enable(int xc_handle, int enable)
 {
-  dom0_op_t op;
+  DECLARE_DOM0_OP;
 
   op.cmd = DOM0_TBUFCONTROL;
   op.interface_version = DOM0_INTERFACE_VERSION;
@@ -24,7 +24,7 @@
 
 int xc_tbuf_set_size(int xc_handle, uint32_t size)
 {
-  dom0_op_t op;
+  DECLARE_DOM0_OP;
 
   op.cmd = DOM0_TBUFCONTROL;
   op.interface_version = DOM0_INTERFACE_VERSION;
@@ -37,7 +37,7 @@
 int xc_tbuf_get_size(int xc_handle, uint32_t *size)
 {
   int rc;
-  dom0_op_t op;
+  DECLARE_DOM0_OP;
 
   op.cmd = DOM0_TBUFCONTROL;
   op.interface_version = DOM0_INTERFACE_VERSION;
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c        Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xc_vmx_build.c        Fri Dec  2 18:52:25 2005
@@ -524,7 +524,7 @@
     memset(shared_info, 0, sizeof(shared_info_t));
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
     munmap(shared_info, PAGE_SIZE);
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xenctrl.h     Fri Dec  2 18:52:25 2005
@@ -13,6 +13,7 @@
 #include <sys/ptrace.h>
 #include <xen/xen.h>
 #include <xen/dom0_ops.h>
+#include <xen/grant_table.h>
 #include <xen/version.h>
 #include <xen/event_channel.h>
 #include <xen/sched.h>
@@ -333,7 +334,7 @@
 
 int xc_evtchn_status(int xc_handle,
                      uint32_t dom, /* may be DOMID_SELF */
-                     int port,
+                     evtchn_port_t port,
                      xc_evtchn_status_t *status);
 
 int xc_physdev_pci_access_modify(int xc_handle,
@@ -374,9 +375,9 @@
 
 int xc_domain_ioport_permission(int xc_handle,
                                 uint32_t domid,
-                                uint16_t first_port,
-                                uint16_t nr_ports,
-                                uint16_t allow_access);
+                                uint32_t first_port,
+                                uint32_t nr_ports,
+                                uint32_t allow_access);
 
 unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, 
                                    unsigned long mfn);
@@ -475,15 +476,16 @@
 int xc_gnttab_map_grant_ref(int      xc_handle,
                             uint64_t host_virt_addr,
                             uint32_t dom,
-                            uint16_t ref,
+                            grant_ref_t ref,
                             uint16_t flags,
-                            int16_t *handle,
+                            int16_t *status,
+                            grant_handle_t *handle,
                             uint64_t *dev_bus_addr);
 
 int xc_gnttab_unmap_grant_ref(int  xc_handle,
                               uint64_t  host_virt_addr,
                               uint64_t  dev_bus_addr,
-                              uint16_t  handle,
+                              grant_handle_t handle,
                               int16_t *status);
 
 int xc_gnttab_setup_table(int        xc_handle,
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xg_private.h  Fri Dec  2 18:52:25 2005
@@ -15,6 +15,16 @@
 
 #include <xen/linux/privcmd.h>
 #include <xen/memory.h>
+
+/* valgrind cannot see when a hypercall has filled in some values.  For this
+   reason, we must zero the dom0_op_t instance before a call, if using
+   valgrind.  */
+#ifdef VALGRIND
+#define DECLARE_DOM0_OP dom0_op_t op = { 0 }
+#else
+#define DECLARE_DOM0_OP dom0_op_t op
+#endif
+
 
 char *xc_read_kernel_image(const char *filename, unsigned long *size);
 unsigned long csum_page (void * page);
diff -r eae5812f33f1 -r 28bd01c9b596 tools/libxc/xg_save_restore.h
--- a/tools/libxc/xg_save_restore.h     Fri Dec  2 18:12:11 2005
+++ b/tools/libxc/xg_save_restore.h     Fri Dec  2 18:52:25 2005
@@ -10,7 +10,7 @@
 #define PROGRESS 0
 
 #define ERR(_f, _a...) do {                     \
-    fprintf(stderr, _f "\n" , ## _a);           \
+    fprintf(stderr, _f ": %d\n" , ## _a, errno);\
     fflush(stderr); }                           \
 while (0)
 
@@ -64,7 +64,6 @@
 { 
     xen_capabilities_info_t xen_caps = "";
     xen_platform_parameters_t xen_params;
-    
 
     if (xc_version(xc_handle, XENVER_platform_parameters, &xen_params) != 0)
         return 0;
@@ -72,8 +71,7 @@
     if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
         return 0;
 
-    if (xc_memory_op(xc_handle, XENMEM_maximum_ram_page, max_mfn) != 0)
-        return 0; 
+    *max_mfn = xc_memory_op(xc_handle, XENMEM_maximum_ram_page, NULL);
     
     *hvirt_start = xen_params.virt_start;
 
@@ -125,6 +123,12 @@
 /* Number of entries in the pfn_to_mfn_frame_list_list */
 #define P2M_FLL_ENTRIES (((max_pfn)+(ulpp*ulpp)-1)/(ulpp*ulpp))
 
+/* Current guests allow 8MB 'slack' in their P2M */
+#define NR_SLACK_ENTRIES   ((8 * 1024 * 1024) / PAGE_SIZE)
+
+/* Is the given PFN within the 'slack' region at the top of the P2M? */
+#define IS_REAL_PFN(_pfn)  ((max_pfn - (_pfn)) > NR_SLACK_ENTRIES) 
+
 /* Returns TRUE if the PFN is currently mapped */
 #define is_mapped(pfn_type) (!((pfn_type) & 0x80000000UL))
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/misc/Makefile
--- a/tools/misc/Makefile       Fri Dec  2 18:12:11 2005
+++ b/tools/misc/Makefile       Fri Dec  2 18:52:25 2005
@@ -16,7 +16,7 @@
 TARGETS  = xenperf xc_shadow
 
 INSTALL_BIN  = $(TARGETS) xencons
-INSTALL_SBIN = netfix xm xend xenperf
+INSTALL_SBIN = netfix xm xen-bugtool xend xenperf
 
 all: build
 build: $(TARGETS)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/setup.py
--- a/tools/python/setup.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/setup.py     Fri Dec  2 18:52:25 2005
@@ -45,6 +45,7 @@
                          'xen.sv',
 
                          'xen.xend.tests',
+                         'xen.xend.server.tests',
                          'xen.xm.tests'
                          ],
       ext_package = "xen.lowlevel",
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Dec  2 18:52:25 2005
@@ -23,7 +23,8 @@
 #define PyMODINIT_FUNC DL_EXPORT(void)
 #endif
 
-#define XENPKG "xen.lowlevel.xc"
+#define PKG "xen.lowlevel.xc"
+#define CLS "xc"
 
 static PyObject *xc_error, *zero;
 
@@ -32,48 +33,38 @@
     int xc_handle;
 } XcObject;
 
-/*
- * Definitions for the 'xc' object type.
- */
-
-static PyObject *pyxc_domain_dumpcore(PyObject *self,
-                                     PyObject *args,
-                                     PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
+
+static PyObject *dom_op(XcObject *self, PyObject *args,
+                        int (*fn)(int, uint32_t));
+
+
+static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
+{
     uint32_t dom;
     char *corefile;
 
-    static char *kwd_list[] = { "dom", "corefile", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
-                                      &dom, &corefile) )
+    if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
         return NULL;
 
     if ( (corefile == NULL) || (corefile[0] == '\0') )
         return NULL;
 
-    if ( xc_domain_dumpcore(xc->xc_handle, dom, corefile) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_handle(PyObject *self)
-{
-    XcObject *xc = (XcObject *)self;
-
-    return PyInt_FromLong(xc->xc_handle);
-}
-
-static PyObject *pyxc_domain_create(PyObject *self,
+    if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
+        return PyErr_SetFromErrno(xc_error);
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_handle(XcObject *self)
+{
+    return PyInt_FromLong(self->xc_handle);
+}
+
+static PyObject *pyxc_domain_create(XcObject *self,
                                     PyObject *args,
                                     PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom = 0;
     int      ret, i;
     uint32_t ssidref = 0;
@@ -103,7 +94,7 @@
         }
     }
 
-    if ( (ret = xc_domain_create(xc->xc_handle, ssidref, handle, &dom)) < 0 )
+    if ( (ret = xc_domain_create(self->xc_handle, ssidref, handle, &dom)) < 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return PyInt_FromLong(dom);
@@ -114,92 +105,40 @@
     return NULL;
 }
 
-static PyObject *pyxc_domain_max_vcpus(PyObject *self,
-                                            PyObject *args,
-                                            PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
+static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
+{
     uint32_t dom, max;
 
-    static char *kwd_list[] = { "dom", "max", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, &dom, &max) )
-        return NULL;
-
-    if ( xc_domain_max_vcpus(xc->xc_handle, dom, max) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_domain_pause(PyObject *self,
-                                   PyObject *args,
-                                   PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    uint32_t dom;
-
-    static char *kwd_list[] = { "dom", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
-        return NULL;
-
-    if ( xc_domain_pause(xc->xc_handle, dom) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_domain_unpause(PyObject *self,
-                                     PyObject *args,
-                                     PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    uint32_t dom;
-
-    static char *kwd_list[] = { "dom", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
-        return NULL;
-
-    if ( xc_domain_unpause(xc->xc_handle, dom) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_domain_destroy(PyObject *self,
-                                     PyObject *args,
-                                     PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    uint32_t dom;
-
-    static char *kwd_list[] = { "dom", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
-        return NULL;
-
-    if ( xc_domain_destroy(xc->xc_handle, dom) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_domain_pincpu(PyObject *self,
+    if (!PyArg_ParseTuple(args, "ii", &dom, &max))
+      return NULL;
+
+    if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
+        return PyErr_SetFromErrno(xc_error);
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
+{
+    return dom_op(self, args, xc_domain_pause);
+}
+
+static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
+{
+    return dom_op(self, args, xc_domain_unpause);
+}
+
+static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
+{
+    return dom_op(self, args, xc_domain_destroy);
+}
+
+
+static PyObject *pyxc_domain_pincpu(XcObject *self,
                                     PyObject *args,
                                     PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom;
     int vcpu = 0, i;
     cpumap_t cpumap = ~0ULL;
@@ -218,19 +157,17 @@
             cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
     }
   
-    if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, cpumap) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_domain_setcpuweight(PyObject *self,
+    if ( xc_domain_pincpu(self->xc_handle, dom, vcpu, cpumap) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_domain_setcpuweight(XcObject *self,
                                          PyObject *args,
                                          PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom;
     float cpuweight = 1;
 
@@ -240,28 +177,21 @@
                                       &dom, &cpuweight) )
         return NULL;
 
-    if ( xc_domain_setcpuweight(xc->xc_handle, dom, cpuweight) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_domain_sethandle(PyObject *self,
-                                       PyObject *args,
-                                       PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
+    if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
+{
     int i;
     uint32_t dom;
     PyObject *pyhandle;
     xen_domain_handle_t handle;
 
-    static char *kwd_list[] = { "dom", "handle", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iO", kwd_list, 
-                                      &dom, &pyhandle) )
+    if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
         return NULL;
 
     if ( !PyList_Check(pyhandle) || 
@@ -278,7 +208,7 @@
         handle[i] = (uint8_t)PyInt_AsLong(p);
     }
 
-    if ( xc_domain_sethandle(xc->xc_handle, dom, handle) < 0 )
+    if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
         return PyErr_SetFromErrno(xc_error);
     
     Py_INCREF(zero);
@@ -291,11 +221,10 @@
 }
 
 
-static PyObject *pyxc_domain_getinfo(PyObject *self,
+static PyObject *pyxc_domain_getinfo(XcObject *self,
                                      PyObject *args,
                                      PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
     PyObject *list, *info_dict;
 
     uint32_t first_dom = 0;
@@ -311,7 +240,7 @@
     if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
         return PyErr_NoMemory();
 
-    nr_doms = xc_domain_getinfo(xc->xc_handle, first_dom, max_doms, info);
+    nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
 
     if (nr_doms < 0)
     {
@@ -351,11 +280,10 @@
     return list;
 }
 
-static PyObject *pyxc_vcpu_getinfo(PyObject *self,
+static PyObject *pyxc_vcpu_getinfo(XcObject *self,
                                    PyObject *args,
                                    PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
     PyObject *info_dict, *cpulist;
 
     uint32_t dom, vcpu = 0;
@@ -369,7 +297,7 @@
                                       &dom, &vcpu) )
         return NULL;
 
-    rc = xc_domain_get_vcpu_info(xc->xc_handle, dom, vcpu, &info);
+    rc = xc_domain_get_vcpu_info(self->xc_handle, dom, vcpu, &info);
     if ( rc < 0 )
         return PyErr_SetFromErrno(xc_error);
 
@@ -393,12 +321,10 @@
     return info_dict;
 }
 
-static PyObject *pyxc_linux_build(PyObject *self,
+static PyObject *pyxc_linux_build(XcObject *self,
                                   PyObject *args,
                                   PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom;
     char *image, *ramdisk = NULL, *cmdline = "";
     int flags = 0;
@@ -418,7 +344,7 @@
                                      &ramdisk, &cmdline, &flags) )
         return NULL;
 
-    if ( xc_linux_build(xc->xc_handle, dom, image,
+    if ( xc_linux_build(self->xc_handle, dom, image,
                         ramdisk, cmdline, flags,
                         store_evtchn, &store_mfn, 
                        console_evtchn, &console_mfn) != 0 )
@@ -429,12 +355,10 @@
                         "console_mfn", console_mfn);
 }
 
-static PyObject *pyxc_vmx_build(PyObject *self,
+static PyObject *pyxc_vmx_build(XcObject *self,
                                 PyObject *args,
                                 PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom;
     char *image;
     int control_evtchn, store_evtchn;
@@ -451,56 +375,41 @@
                                       &memsize, &image, &lapic, &vcpus) )
         return NULL;
 
-    if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn,
+    if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
                       lapic, vcpus, store_evtchn, &store_mfn) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
 }
 
-static PyObject *pyxc_bvtsched_global_set(PyObject *self,
+static PyObject *pyxc_bvtsched_global_set(XcObject *self, PyObject *args)
+{
+    unsigned long ctx_allow;
+
+    if (!PyArg_ParseTuple(args, "l", &ctx_allow))
+        return NULL;
+
+    if (xc_bvtsched_global_set(self->xc_handle, ctx_allow) != 0)
+        return PyErr_SetFromErrno(xc_error);
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_bvtsched_global_get(XcObject *self)
+{
+    unsigned long ctx_allow;
+    
+    if (xc_bvtsched_global_get(self->xc_handle, &ctx_allow) != 0)
+        return PyErr_SetFromErrno(xc_error);
+    
+    return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
+}
+
+static PyObject *pyxc_bvtsched_domain_set(XcObject *self,
                                           PyObject *args,
                                           PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
-    unsigned long ctx_allow;
-
-    static char *kwd_list[] = { "ctx_allow", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "l", kwd_list, &ctx_allow) )
-        return NULL;
-
-    if ( xc_bvtsched_global_set(xc->xc_handle, ctx_allow) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_bvtsched_global_get(PyObject *self,
-                                          PyObject *args,
-                                          PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-    
-    unsigned long ctx_allow;
-    
-    if ( !PyArg_ParseTuple(args, "") )
-        return NULL;
-    
-    if ( xc_bvtsched_global_get(xc->xc_handle, &ctx_allow) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
-}
-
-static PyObject *pyxc_bvtsched_domain_set(PyObject *self,
-                                          PyObject *args,
-                                          PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom;
     uint32_t mcuadv;
     int warpback; 
@@ -516,7 +425,7 @@
                                       &warpl, &warpu) )
         return NULL;
 
-    if ( xc_bvtsched_domain_set(xc->xc_handle, dom, mcuadv, 
+    if ( xc_bvtsched_domain_set(self->xc_handle, dom, mcuadv, 
                                 warpback, warpvalue, warpl, warpu) != 0 )
         return PyErr_SetFromErrno(xc_error);
     
@@ -524,11 +433,9 @@
     return zero;
 }
 
-static PyObject *pyxc_bvtsched_domain_get(PyObject *self,
-                                          PyObject *args,
-                                          PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
+static PyObject *pyxc_bvtsched_domain_get(XcObject *self,
+                                          PyObject *args)
+{
     uint32_t dom;
     uint32_t mcuadv;
     int warpback; 
@@ -536,13 +443,11 @@
     long long warpl;
     long long warpu;
     
-    static char *kwd_list[] = { "dom", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
-        return NULL;
-    
-    if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warpback,
-                            &warpvalue, &warpl, &warpu) != 0 )
+    if (!PyArg_ParseTuple(args, "i", &dom))
+        return NULL;
+    
+    if (xc_bvtsched_domain_get(self->xc_handle, dom, &mcuadv, &warpback,
+                               &warpvalue, &warpl, &warpu) != 0)
         return PyErr_SetFromErrno(xc_error);
 
     return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
@@ -554,12 +459,10 @@
                          "warpu", warpu);
 }
 
-static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self,
+static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
                                            PyObject *args,
                                            PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom, remote_dom;
     int port;
 
@@ -569,17 +472,16 @@
                                       &dom, &remote_dom) )
         return NULL;
 
-    if ( (port = xc_evtchn_alloc_unbound(xc->xc_handle, dom, remote_dom)) < 0 )
+    if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 
0 )
         return PyErr_SetFromErrno(xc_error);
 
     return PyInt_FromLong(port);
 }
 
-static PyObject *pyxc_evtchn_status(PyObject *self,
+static PyObject *pyxc_evtchn_status(XcObject *self,
                                     PyObject *args,
                                     PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
     PyObject *dict;
 
     uint32_t dom = DOMID_SELF;
@@ -592,7 +494,7 @@
                                       &port, &dom) )
         return NULL;
 
-    ret = xc_evtchn_status(xc->xc_handle, dom, port, &status);
+    ret = xc_evtchn_status(self->xc_handle, dom, port, &status);
     if ( ret != 0 )
         return PyErr_SetFromErrno(xc_error);
 
@@ -630,11 +532,10 @@
     return dict;
 }
 
-static PyObject *pyxc_physdev_pci_access_modify(PyObject *self,
+static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
                                                 PyObject *args,
                                                 PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
     uint32_t dom;
     int bus, dev, func, enable, ret;
 
@@ -645,7 +546,7 @@
         return NULL;
 
     ret = xc_physdev_pci_access_modify(
-        xc->xc_handle, dom, bus, dev, func, enable);
+        self->xc_handle, dom, bus, dev, func, enable);
     if ( ret != 0 )
         return PyErr_SetFromErrno(xc_error);
 
@@ -653,12 +554,10 @@
     return zero;
 }
 
-static PyObject *pyxc_readconsolering(PyObject *self,
+static PyObject *pyxc_readconsolering(XcObject *self,
                                       PyObject *args,
                                       PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     unsigned int clear = 0;
     char         _str[32768], *str = _str;
     unsigned int count = 32768;
@@ -669,26 +568,38 @@
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
         return NULL;
 
-    ret = xc_readconsolering(xc->xc_handle, &str, &count, clear);
+    ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
     if ( ret < 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return PyString_FromStringAndSize(str, count);
 }
 
-static PyObject *pyxc_physinfo(PyObject *self,
-                               PyObject *args,
-                               PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
+
+static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
+{
+    unsigned long pages;
+
+    if (!PyArg_ParseTuple(args, "l", &pages))
+        return NULL;
+
+    return PyLong_FromUnsignedLong(pages * (XC_PAGE_SIZE / 1024));
+}
+
+
+static unsigned long pages_to_mb(unsigned long pages)
+{
+    return (pages * (XC_PAGE_SIZE / 1024) + 1023) / 1024;
+}
+
+
+static PyObject *pyxc_physinfo(XcObject *self)
+{
     xc_physinfo_t info;
     char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
     int i;
     
-    if ( !PyArg_ParseTuple(args, "") )
-        return NULL;
-
-    if ( xc_physinfo(xc->xc_handle, &info) != 0 )
+    if ( xc_physinfo(self->xc_handle, &info) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
     *q=0;
@@ -706,17 +617,14 @@
                          "cores_per_socket", info.cores_per_socket,
                          "sockets_per_node", info.sockets_per_node,
                          "nr_nodes",         info.nr_nodes,
-                         "total_pages",      info.total_pages,
-                         "free_pages",       info.free_pages,
+                         "total_memory",     pages_to_mb(info.total_pages),
+                         "free_memory",      pages_to_mb(info.free_pages),
                          "cpu_khz",          info.cpu_khz,
                          "hw_caps",          cpu_cap);
 }
 
-static PyObject *pyxc_xeninfo(PyObject *self,
-                              PyObject *args,
-                              PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
+static PyObject *pyxc_xeninfo(XcObject *self)
+{
     xen_extraversion_t xen_extra;
     xen_compile_info_t xen_cc;
     xen_changeset_info_t xen_chgset;
@@ -725,21 +633,21 @@
     long xen_version;
     char str[128];
 
-    xen_version = xc_version(xc->xc_handle, XENVER_version, NULL);
-
-    if ( xc_version(xc->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    if ( xc_version(xc->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    if ( xc_version(xc->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    if ( xc_version(xc->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-
-    if ( xc_version(xc->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
+    xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
+
+    if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 
0 )
         return PyErr_SetFromErrno(xc_error);
 
     sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
@@ -758,11 +666,10 @@
 }
 
 
-static PyObject *pyxc_sedf_domain_set(PyObject *self,
+static PyObject *pyxc_sedf_domain_set(XcObject *self,
                                       PyObject *args,
                                       PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
     uint32_t domid;
     uint64_t period, slice, latency;
     uint16_t extratime, weight;
@@ -773,7 +680,7 @@
                                      &domid, &period, &slice,
                                      &latency, &extratime, &weight) )
         return NULL;
-   if ( xc_sedf_domain_set(xc->xc_handle, domid, period,
+   if ( xc_sedf_domain_set(self->xc_handle, domid, period,
                            slice, latency, extratime,weight) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
@@ -781,22 +688,17 @@
     return zero;
 }
 
-static PyObject *pyxc_sedf_domain_get(PyObject *self,
-                                      PyObject *args,
-                                      PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
+static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
+{
     uint32_t domid;
     uint64_t period, slice,latency;
     uint16_t weight, extratime;
     
-    static char *kwd_list[] = { "dom", NULL };
-
-    if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) )
-        return NULL;
-    
-    if ( xc_sedf_domain_get( xc->xc_handle, domid, &period,
-                                &slice,&latency,&extratime,&weight) )
+    if(!PyArg_ParseTuple(args, "i", &domid))
+        return NULL;
+    
+    if (xc_sedf_domain_get(self->xc_handle, domid, &period,
+                           &slice,&latency,&extratime,&weight))
         return PyErr_SetFromErrno(xc_error);
 
     return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
@@ -808,34 +710,25 @@
                          "weight",    weight);
 }
 
-static PyObject *pyxc_domain_setmaxmem(PyObject *self,
-                                       PyObject *args,
-                                       PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
+static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
+{
     uint32_t dom;
     unsigned int maxmem_kb;
 
-    static char *kwd_list[] = { "dom", "maxmem_kb", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
-                                      &dom, &maxmem_kb) )
-        return NULL;
-
-    if ( xc_domain_setmaxmem(xc->xc_handle, dom, maxmem_kb) != 0 )
-        return PyErr_SetFromErrno(xc_error);
-    
-    Py_INCREF(zero);
-    return zero;
-}
-
-static PyObject *pyxc_domain_memory_increase_reservation(PyObject *self,
+    if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
+        return NULL;
+
+    if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
+        return PyErr_SetFromErrno(xc_error);
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
+static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
                                                         PyObject *args,
                                                         PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
-
     uint32_t dom;
     unsigned long mem_kb;
     unsigned int extent_order = 0 , address_bits = 0;
@@ -850,7 +743,7 @@
     /* round down to nearest power of 2. Assume callers using extent_order>0
        know what they are doing */
     nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
-    if ( xc_domain_memory_increase_reservation(xc->xc_handle, dom, 
+    if ( xc_domain_memory_increase_reservation(self->xc_handle, dom, 
                                               nr_extents, extent_order, 
                                               address_bits, NULL) )
         return PyErr_SetFromErrno(xc_error);
@@ -859,11 +752,10 @@
     return zero;
 }
 
-static PyObject *pyxc_domain_ioport_permission(PyObject *self,
+static PyObject *pyxc_domain_ioport_permission(XcObject *self,
                                                PyObject *args,
                                                PyObject *kwds)
 {
-    XcObject *xc = (XcObject *)self;
     uint32_t dom;
     int first_port, nr_ports, allow_access, ret;
 
@@ -874,18 +766,35 @@
         return NULL;
 
     ret = xc_domain_ioport_permission(
-        xc->xc_handle, dom, first_port, nr_ports, allow_access);
+        self->xc_handle, dom, first_port, nr_ports, allow_access);
     if ( ret != 0 )
         return PyErr_SetFromErrno(xc_error);
 
     Py_INCREF(zero);
     return zero;
 }
+
+
+static PyObject *dom_op(XcObject *self, PyObject *args,
+                        int (*fn)(int, uint32_t))
+{
+    uint32_t dom;
+
+    if (!PyArg_ParseTuple(args, "i", &dom))
+        return NULL;
+
+    if (fn(self->xc_handle, dom) != 0)
+        return PyErr_SetFromErrno(xc_error);
+
+    Py_INCREF(zero);
+    return zero;
+}
+
 
 static PyMethodDef pyxc_methods[] = {
     { "handle",
       (PyCFunction)pyxc_handle,
-      0, "\n"
+      METH_NOARGS, "\n"
       "Query the xc control interface file descriptor.\n\n"
       "Returns: [int] file descriptor\n" },
 
@@ -898,7 +807,7 @@
 
     { "domain_max_vcpus", 
       (PyCFunction)pyxc_domain_max_vcpus,
-      METH_VARARGS | METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Set the maximum number of VCPUs a domain may create.\n"
       " dom       [int, 0]:      Domain identifier to use.\n"
       " max     [int, 0]:      New maximum number of VCPUs in domain.\n"
@@ -906,7 +815,7 @@
 
     { "domain_dumpcore", 
       (PyCFunction)pyxc_domain_dumpcore, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Dump core of a domain.\n"
       " dom [int]: Identifier of domain to dump core of.\n"
       " corefile [string]: Name of corefile to be created.\n\n"
@@ -914,21 +823,21 @@
 
     { "domain_pause", 
       (PyCFunction)pyxc_domain_pause, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Temporarily pause execution of a domain.\n"
       " dom [int]: Identifier of domain to be paused.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
     { "domain_unpause", 
       (PyCFunction)pyxc_domain_unpause, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "(Re)start execution of a domain.\n"
       " dom [int]: Identifier of domain to be unpaused.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
     { "domain_destroy", 
       (PyCFunction)pyxc_domain_destroy, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Destroy a domain.\n"
       " dom [int]:    Identifier of domain to be destroyed.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
@@ -952,7 +861,7 @@
 
     { "domain_sethandle", 
       (PyCFunction)pyxc_domain_sethandle,
-      METH_VARARGS | METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Set domain's opaque handle.\n"
       " dom [int]:            Identifier of domain.\n"
       " handle [list of 16 ints]: New opaque handle.\n"
@@ -1026,7 +935,7 @@
 
     { "bvtsched_global_get",
       (PyCFunction)pyxc_bvtsched_global_get,
-      METH_KEYWORDS, "\n"
+      METH_NOARGS, "\n"
       "Get global tuning parameters for BVT scheduler.\n"
       "Returns: [dict]:\n"
       " ctx_allow [int]: context switch allowance\n" },
@@ -1045,7 +954,7 @@
 
     { "bvtsched_domain_get",
       (PyCFunction)pyxc_bvtsched_domain_get,
-      METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Get per-domain tuning parameters under the BVT scheduler.\n"
       " dom [int]: Identifier of domain to be queried.\n"
       "Returns [dict]:\n"
@@ -1069,7 +978,7 @@
 
     { "sedf_domain_get",
       (PyCFunction)pyxc_sedf_domain_get,
-      METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Get the current scheduling parameters for a domain when running with\n"
       "the Atropos scheduler."
       " dom       [int]: domain to query\n"
@@ -1123,21 +1032,21 @@
 
     { "physinfo",
       (PyCFunction)pyxc_physinfo,
-      METH_VARARGS, "\n"
+      METH_NOARGS, "\n"
       "Get information about the physical host machine\n"
       "Returns [dict]: information about the hardware"
       "        [None]: on failure.\n" },
 
     { "xeninfo",
       (PyCFunction)pyxc_xeninfo,
-      METH_VARARGS, "\n"
+      METH_NOARGS, "\n"
       "Get information about the Xen host\n"
       "Returns [dict]: information about Xen"
       "        [None]: on failure.\n" },
 
     { "domain_setmaxmem", 
       (PyCFunction)pyxc_domain_setmaxmem, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
+      METH_VARARGS, "\n"
       "Set a domain's memory limit\n"
       " dom [int]: Identifier of domain.\n"
       " maxmem_kb [int]: .\n"
@@ -1161,83 +1070,125 @@
       " allow_access [int]: Non-zero means enable access; else disable 
access\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
+    { "pages_to_kib",
+      (PyCFunction)pyxc_pages_to_kib,
+      METH_VARARGS, "\n"
+      "Returns: [int]: The size in KiB of memory spanning the given number "
+      "of pages.\n" },
+
     { NULL, NULL, 0, NULL }
 };
 
 
-/*
- * Definitions for the 'Xc' module wrapper.
- */
-
-staticforward PyTypeObject PyXcType;
-
-static PyObject *PyXc_new(PyObject *self, PyObject *args)
-{
-    XcObject *xc;
-
-    if ( !PyArg_ParseTuple(args, ":new") )
-        return NULL;
-
-    xc = PyObject_New(XcObject, &PyXcType);
-
-    if ( (xc->xc_handle = xc_interface_open()) == -1 )
-    {
-        PyObject_Del((PyObject *)xc);
-        return PyErr_SetFromErrno(xc_error);
+static PyObject *PyXc_getattr(PyObject *obj, char *name)
+{
+    return Py_FindMethod(pyxc_methods, obj, name);
+}
+
+static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    XcObject *self = (XcObject *)type->tp_alloc(type, 0);
+
+    if (self == NULL)
+        return NULL;
+
+    self->xc_handle = -1;
+
+    return (PyObject *)self;
+}
+
+static int
+PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
+{
+    if ((self->xc_handle = xc_interface_open()) == -1) {
+        PyErr_SetFromErrno(PyExc_RuntimeError);
+        return -1;
     }
 
-    return (PyObject *)xc;
-}
-
-static PyObject *PyXc_getattr(PyObject *obj, char *name)
-{
-    return Py_FindMethod(pyxc_methods, obj, name);
-}
-
-static void PyXc_dealloc(PyObject *self)
-{
-    XcObject *xc = (XcObject *)self;
-    (void)xc_interface_close(xc->xc_handle);
-    PyObject_Del(self);
+    return 0;
+}
+
+static void PyXc_dealloc(XcObject *self)
+{
+    if (self->xc_handle != -1) {
+        xc_interface_close(self->xc_handle);
+        self->xc_handle = -1;
+    }
+
+    self->ob_type->tp_free((PyObject *)self);
 }
 
 static PyTypeObject PyXcType = {
-    PyObject_HEAD_INIT(&PyType_Type)
+    PyObject_HEAD_INIT(NULL)
     0,
-    "Xc",
+    PKG "." CLS,
     sizeof(XcObject),
     0,
-    PyXc_dealloc,    /* tp_dealloc     */
-    NULL,            /* tp_print       */
-    PyXc_getattr,    /* tp_getattr     */
-    NULL,            /* tp_setattr     */
-    NULL,            /* tp_compare     */
-    NULL,            /* tp_repr        */
-    NULL,            /* tp_as_number   */
-    NULL,            /* tp_as_sequence */
-    NULL,            /* tp_as_mapping  */
-    NULL             /* tp_hash        */
+    (destructor)PyXc_dealloc,     /* tp_dealloc        */
+    NULL,                         /* tp_print          */
+    PyXc_getattr,                 /* tp_getattr        */
+    NULL,                         /* tp_setattr        */
+    NULL,                         /* tp_compare        */
+    NULL,                         /* tp_repr           */
+    NULL,                         /* tp_as_number      */
+    NULL,                         /* tp_as_sequence    */
+    NULL,                         /* tp_as_mapping     */
+    NULL,                         /* tp_hash           */
+    NULL,                         /* tp_call           */
+    NULL,                         /* tp_str            */
+    NULL,                         /* tp_getattro       */
+    NULL,                         /* tp_setattro       */
+    NULL,                         /* tp_as_buffer      */
+    Py_TPFLAGS_DEFAULT,           /* tp_flags          */
+    "Xen client connections",     /* tp_doc            */
+    NULL,                         /* tp_traverse       */
+    NULL,                         /* tp_clear          */
+    NULL,                         /* tp_richcompare    */
+    0,                            /* tp_weaklistoffset */
+    NULL,                         /* tp_iter           */
+    NULL,                         /* tp_iternext       */
+    pyxc_methods,                 /* tp_methods        */
+    NULL,                         /* tp_members        */
+    NULL,                         /* tp_getset         */
+    NULL,                         /* tp_base           */
+    NULL,                         /* tp_dict           */
+    NULL,                         /* tp_descr_get      */
+    NULL,                         /* tp_descr_set      */
+    0,                            /* tp_dictoffset     */
+    (initproc)PyXc_init,          /* tp_init           */
+    NULL,                         /* tp_alloc          */
+    PyXc_new,                     /* tp_new            */
 };
 
-static PyMethodDef PyXc_methods[] = {
-    { "new", PyXc_new, METH_VARARGS, "Create a new " XENPKG " object." },
-    { NULL, NULL, 0, NULL }
-};
+static PyMethodDef xc_methods[] = { { NULL } };
 
 PyMODINIT_FUNC initxc(void)
 {
-    PyObject *m, *d;
-
-    m = Py_InitModule(XENPKG, PyXc_methods);
-
-    d = PyModule_GetDict(m);
-    xc_error = PyErr_NewException(XENPKG ".error", NULL, NULL);
-    PyDict_SetItemString(d, "error", xc_error);
-    PyDict_SetItemString(d, "VIRQ_DOM_EXC", PyInt_FromLong(VIRQ_DOM_EXC));
-
+    PyObject *m;
+
+    if (PyType_Ready(&PyXcType) < 0)
+        return;
+
+    m = Py_InitModule(PKG, xc_methods);
+
+    if (m == NULL)
+      return;
+
+    xc_error = PyErr_NewException(PKG ".error", NULL, NULL);
     zero = PyInt_FromLong(0);
 
     /* KAF: This ensures that we get debug output in a timely manner. */
     setbuf(stdout, NULL);
     setbuf(stderr, NULL);
-}
+
+    Py_INCREF(&PyXcType);
+    PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ */
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/lowlevel/xs/xs.c Fri Dec  2 18:52:25 2005
@@ -41,7 +41,8 @@
 #define PyMODINIT_FUNC DL_EXPORT(void)
 #endif
 
-#define PYPKG    "xen.lowlevel.xs"
+#define PKG "xen.lowlevel.xs"
+#define CLS "xs"
 
 /** Python wrapper round an xs handle.
  */
@@ -51,47 +52,35 @@
     PyObject *watches;
 } XsHandle;
 
-static inline struct xs_handle *xshandle(PyObject *self)
-{
-    struct xs_handle *xh = ((XsHandle*)self)->xh;
+static inline struct xs_handle *xshandle(XsHandle *self)
+{
+    struct xs_handle *xh = self->xh;
     if (!xh)
         PyErr_SetString(PyExc_RuntimeError, "invalid xenstore daemon handle");
     return xh;
 }
 
-static inline PyObject *pyvalue_int(int val) {
-    return (val
-            ? PyInt_FromLong(val)
-            : PyErr_SetFromErrno(PyExc_RuntimeError));
-}
-
-static inline PyObject *pyvalue_str(char *val) {
-    return (val
-            ? PyString_FromString(val)
-            : PyErr_SetFromErrno(PyExc_RuntimeError));
-}
-
 static void remove_watch(XsHandle *xsh, PyObject *token);
 
 static PyObject *none(bool result);
 
-static int parse_transaction_path(PyObject *self, PyObject *args,
-                                  PyObject *kwds,
+static int parse_transaction_path(XsHandle *self, PyObject *args,
                                   struct xs_handle **xh,
                                   struct xs_transaction_handle **th,
                                   char **path);
 
 
-#define xspy_read_doc "\n"                     \
-       "Read data from a path.\n"              \
-       " path [string]: xenstore path\n"       \
-       "\n"                                    \
-       "Returns: [string] data read.\n"        \
-       "         None if key doesn't exist.\n" \
-       "Raises RuntimeError on error.\n"       \
-       "\n"
-
-static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
+#define xspy_read_doc "\n"                              \
+       "Read data from a path.\n"                      \
+       " transaction [string]: transaction handle\n"   \
+       " path [string]:        xenstore path\n"        \
+       "\n"                                            \
+       "Returns: [string] data read.\n"                \
+       "         None if key doesn't exist.\n"         \
+       "Raises RuntimeError on error.\n"               \
+       "\n"
+
+static PyObject *xspy_read(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
     struct xs_transaction_handle *th;
@@ -100,7 +89,7 @@
     char *xsval;
     unsigned int xsval_n;
 
-    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
+    if (!parse_transaction_path(self, args, &xh, &th, &path))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -119,6 +108,7 @@
 
 #define xspy_write_doc "\n"                                    \
        "Write data to a path.\n"                               \
+       " transaction [string]: transaction handle\n"           \
        " path   [string] : xenstore path to write to\n."       \
        " data   [string] : data to write.\n"                   \
        "\n"                                                    \
@@ -126,24 +116,20 @@
        "Raises RuntimeError on error.\n"                       \
        "\n"
 
-static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwd_spec[] = { "transaction", "path", "data", NULL };
+static PyObject *xspy_write(XsHandle *self, PyObject *args)
+{
     static char *arg_spec = "sss#";
-    char *path = NULL;
-    char *data = NULL;
-    int data_n = 0;
-
-    struct xs_handle *xh = xshandle(self);
-    bool result;
-
+    struct xs_handle *xh = xshandle(self);
     struct xs_transaction_handle *th;
     char *thstr;
-
-    if (!xh)
-        return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &thstr, &path, &data, &data_n))
+    char *path;
+    char *data;
+    int data_n;
+    bool result;
+
+    if (!xh)
+        return NULL;
+    if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path, &data, &data_n))
         return NULL;
 
     th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
@@ -158,23 +144,24 @@
 
 #define xspy_ls_doc "\n"                                       \
        "List a directory.\n"                                   \
-       " path [string]: path to list.\n"                       \
+       " transaction [string]: transaction handle\n"           \
+       " path [string]:        path to list.\n"                \
        "\n"                                                    \
        "Returns: [string array] list of subdirectory names.\n" \
        "         None if key doesn't exist.\n"                 \
        "Raises RuntimeError on error.\n"                       \
        "\n"
 
-static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
+static PyObject *xspy_ls(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
     struct xs_transaction_handle *th;
     char *path;
 
     char **xsval;
-    int xsval_n;
-
-    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
+    unsigned int xsval_n;
+
+    if (!parse_transaction_path(self, args, &xh, &th, &path))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -203,7 +190,7 @@
        "Raises RuntimeError on error.\n"                       \
        "\n"
 
-static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
+static PyObject *xspy_mkdir(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
     struct xs_transaction_handle *th;
@@ -211,7 +198,7 @@
 
     bool result;
 
-    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
+    if (!parse_transaction_path(self, args, &xh, &th, &path))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -222,15 +209,16 @@
 }
 
 
-#define xspy_rm_doc "\n"                       \
-       "Remove a path.\n"                      \
-       " path [string] : path to remove\n"     \
-       "\n"                                    \
-       "Returns None on success.\n"            \
-       "Raises RuntimeError on error.\n"       \
-       "\n"
-
-static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
+#define xspy_rm_doc "\n"                                \
+       "Remove a path.\n"                              \
+       " transaction [string]: transaction handle\n"   \
+       " path [string] : path to remove\n"             \
+       "\n"                                            \
+       "Returns None on success.\n"                    \
+       "Raises RuntimeError on error.\n"               \
+       "\n"
+
+static PyObject *xspy_rm(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
     struct xs_transaction_handle *th;
@@ -238,7 +226,7 @@
 
     bool result;
 
-    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
+    if (!parse_transaction_path(self, args, &xh, &th, &path))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -249,18 +237,17 @@
 }
 
 
-#define xspy_get_permissions_doc "\n"          \
-       "Get the permissions for a path\n"      \
-       " path [string]: xenstore path.\n"      \
-       "\n"                                    \
-       "Returns: permissions array.\n"         \
-       "Raises RuntimeError on error.\n"       \
-       "\n"
-
-static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
-                                      PyObject *kwds)
-{
-    static char *kwd_spec[] = { "transaction", "path", NULL };
+#define xspy_get_permissions_doc "\n"                   \
+       "Get the permissions for a path\n"              \
+       " transaction [string]: transaction handle\n"   \
+       " path [string]:        xenstore path.\n"       \
+       "\n"                                            \
+       "Returns: permissions array.\n"                 \
+       "Raises RuntimeError on error.\n"               \
+       "\n"
+
+static PyObject *xspy_get_permissions(XsHandle *self, PyObject *args)
+{
     static char *arg_spec = "ss";
     char *path = NULL;
 
@@ -274,8 +261,7 @@
 
     if (!xh)
         return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &thstr, &path))
+    if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path))
         return NULL;
 
     th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
@@ -303,39 +289,35 @@
     }
 }
 
-#define xspy_set_permissions_doc "\n"          \
-       "Set the permissions for a path\n"      \
-       " path  [string] : xenstore path.\n"    \
-       " perms          : permissions.\n"      \
-       "\n"                                    \
-       "Returns None on success.\n"            \
-       "Raises RuntimeError on error.\n"       \
-       "\n"
-
-static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
-                                      PyObject *kwds)
-{
-    static char *kwd_spec[] = { "transaction", "path", "perms", NULL };
-    static char *arg_spec = "ssO";
-    char *path = NULL;
-    PyObject *perms = NULL;
+#define xspy_set_permissions_doc "\n"                   \
+       "Set the permissions for a path\n"              \
+       " transaction [string]: transaction handle\n"   \
+       " path  [string]      : xenstore path.\n"       \
+       " perms               : permissions.\n"         \
+       "\n"                                            \
+       "Returns None on success.\n"                    \
+       "Raises RuntimeError on error.\n"               \
+       "\n"
+
+static PyObject *xspy_set_permissions(XsHandle *self, PyObject *args)
+{
+    char *path;
+    PyObject *perms;
     static char *perm_names[] = { "dom", "read", "write", NULL };
-    static char *perm_spec = "i|iiii";
+    static char *perm_spec = "i|ii";
 
     struct xs_handle *xh = xshandle(self);
     int i, result;
     struct xs_permissions *xsperms = NULL;
-    int xsperms_n = 0;
+    int xsperms_n;
     PyObject *tuple0 = NULL;
-    PyObject *val = NULL;
 
     struct xs_transaction_handle *th;
     char *thstr;
 
     if (!xh)
         goto exit;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &thstr, &path, &perms))
+    if (!PyArg_ParseTuple(args, "ssO", &thstr, &path, &perms))
         goto exit;
 
     th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
@@ -354,15 +336,12 @@
     if (!tuple0)
         goto exit;
     for (i = 0; i < xsperms_n; i++) {
-        /* Domain the permissions apply to. */
-        int dom = 0;
         /* Read/write perms. Set these. */
         int p_read = 0, p_write = 0;
         PyObject *p = PyList_GetItem(perms, i);
         if (!PyArg_ParseTupleAndKeywords(tuple0, p, perm_spec, perm_names,
-                                         &dom, &p_read, &p_write))
+                                         &xsperms[i].id, &p_read, &p_write))
             goto exit;
-        xsperms[i].id = dom;
         if (p_read)
             xsperms[i].perms |= XS_PERM_READ;
         if (p_write)
@@ -375,12 +354,14 @@
         PyErr_SetFromErrno(PyExc_RuntimeError);
         goto exit;
     }
+
     Py_INCREF(Py_None);
-    val = Py_None;
+    return Py_None;
+
  exit:
     Py_XDECREF(tuple0);
     free(xsperms);
-    return val;
+    return NULL;
 }
 
 #define xspy_watch_doc "\n"                                            \
@@ -395,23 +376,18 @@
 /* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */
 #define MAX_STRLEN(x) ((sizeof(x) * CHAR_BIT + CHAR_BIT-1) / 10 * 3 + 2)
 
-static PyObject *xspy_watch(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwd_spec[] = { "path", "token", NULL };
-    static char *arg_spec = "sO";
-    char *path = NULL;
+static PyObject *xspy_watch(XsHandle *self, PyObject *args)
+{
+    struct xs_handle *xh = xshandle(self);
+    char *path;
     PyObject *token;
     char token_str[MAX_STRLEN(unsigned long) + 1];
+    int result;
     int i;
 
-    XsHandle *xsh = (XsHandle *)self;
-    struct xs_handle *xh = xshandle(self);
-    int result = 0;
-
-    if (!xh)
-        return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 
-                                     &path, &token))
+    if (!xh)
+        return NULL;
+    if (!PyArg_ParseTuple(args, "sO", &path, &token))
         return NULL;
 
     /* Note that we have to store the watch token in the xs->watches list
@@ -419,14 +395,14 @@
        races with xs_read_watch.
     */
 
-    for (i = 0; i < PyList_Size(xsh->watches); i++) {
-        if (PyList_GetItem(xsh->watches, i) == Py_None) {
-            PySequence_SetItem(xsh->watches, i, token);
+    for (i = 0; i < PyList_Size(self->watches); i++) {
+        if (PyList_GetItem(self->watches, i) == Py_None) {
+            PySequence_SetItem(self->watches, i, token);
             break;
         }
     }
-    if (i == PyList_Size(xsh->watches))
-        PyList_Append(xsh->watches, token);
+    if (i == PyList_Size(self->watches))
+        PyList_Append(self->watches, token);
 
     sprintf(token_str, "%li", (unsigned long)token);
     Py_BEGIN_ALLOW_THREADS
@@ -434,7 +410,7 @@
     Py_END_ALLOW_THREADS
 
     if (!result)
-        remove_watch(xsh, token);
+        remove_watch(self, token);
 
     return none(result);
 }
@@ -447,24 +423,17 @@
        "Raises RuntimeError on error.\n"                       \
        "\n"
 
-static PyObject *xspy_read_watch(PyObject *self, PyObject *args,
-                                 PyObject *kwds)
-{
-    static char *kwd_spec[] = { NULL };
-    static char *arg_spec = "";
-
-    XsHandle *xsh = (XsHandle *)self;
+static PyObject *xspy_read_watch(XsHandle *self, PyObject *args)
+{
     struct xs_handle *xh = xshandle(self);
     PyObject *val = NULL;
-    char **xsval = NULL;
+    char **xsval;
     PyObject *token;
     int i;
     unsigned int num;
 
     if (!xh)
         return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
-        return NULL;
 
 again:
     Py_BEGIN_ALLOW_THREADS
@@ -478,11 +447,11 @@
         PyErr_SetString(PyExc_RuntimeError, "invalid token");
         goto exit;
     }
-    for (i = 0; i < PyList_Size(xsh->watches); i++) {
-        if (token == PyList_GetItem(xsh->watches, i))
+    for (i = 0; i < PyList_Size(self->watches); i++) {
+        if (token == PyList_GetItem(self->watches, i))
             break;
     }
-    if (i == PyList_Size(xsh->watches)) {
+    if (i == PyList_Size(self->watches)) {
       /* We do not have a registered watch for the one that has just fired.
          Ignore this -- a watch that has been recently deregistered can still
          have watches in transit.  This is a blocking method, so go back to
@@ -507,22 +476,17 @@
        "Raises RuntimeError on error.\n"               \
        "\n"
 
-static PyObject *xspy_unwatch(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwd_spec[] = { "path", "token", NULL };
-    static char *arg_spec = "sO";
-    char *path = NULL;
+static PyObject *xspy_unwatch(XsHandle *self, PyObject *args)
+{
+    struct xs_handle *xh = xshandle(self);
+    char *path;
     PyObject *token;
     char token_str[MAX_STRLEN(unsigned long) + 1];
-
-    XsHandle *xsh = (XsHandle *)self;
-    struct xs_handle *xh = xshandle(self);
-    int result = 0;
-
-    if (!xh)
-        return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path,
-                                     &token))
+    int result;
+
+    if (!xh)
+        return NULL;
+    if (!PyArg_ParseTuple(args, "sO", &path, &token))
         return NULL;
 
     sprintf(token_str, "%li", (unsigned long)token);
@@ -530,7 +494,7 @@
     result = xs_unwatch(xh, path, token_str);
     Py_END_ALLOW_THREADS
 
-    remove_watch(xsh, token);
+    remove_watch(self, token);
 
     return none(result);
 }
@@ -542,20 +506,13 @@
        "Raises RuntimeError on error.\n"                       \
        "\n"
 
-static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
-                                        PyObject *kwds)
-{
-    static char *kwd_spec[] = { NULL };
-    static char *arg_spec = "";
-    char *path = NULL;
-
+static PyObject *xspy_transaction_start(XsHandle *self)
+{
     struct xs_handle *xh = xshandle(self);
     struct xs_transaction_handle *th;
-    char thstr[20];
-
-    if (!xh)
-        return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
+    char thstr[MAX_STRLEN(unsigned long) + 1];
+
+    if (!xh)
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -580,7 +537,7 @@
        "Raises RuntimeError on error.\n"                               \
        "\n"
 
-static PyObject *xspy_transaction_end(PyObject *self, PyObject *args,
+static PyObject *xspy_transaction_end(XsHandle *self, PyObject *args,
                                       PyObject *kwds)
 {
     static char *kwd_spec[] = { "transaction", "abort", NULL };
@@ -630,22 +587,18 @@
        "Raises RuntimeError on error.\n"                               \
        "\n"
 
-static PyObject *xspy_introduce_domain(PyObject *self, PyObject *args,
-                                       PyObject *kwds)
-{
-    static char *kwd_spec[] = { "dom", "page", "port", NULL };
-    static char *arg_spec = "ili";
-    domid_t dom = 0;
-    unsigned long page = 0;
-    unsigned int port = 0;
+static PyObject *xspy_introduce_domain(XsHandle *self, PyObject *args)
+{
+    domid_t dom;
+    unsigned long page;
+    unsigned int port;
 
     struct xs_handle *xh = xshandle(self);
     bool result = 0;
 
     if (!xh)
         return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &dom, &page, &port))
+    if (!PyArg_ParseTuple(args, "ili", &dom, &page, &port))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -665,11 +618,8 @@
        "Raises RuntimeError on error.\n"                               \
        "\n"
 
-static PyObject *xspy_release_domain(PyObject *self, PyObject *args,
-                                     PyObject *kwds)
-{
-    static char *kwd_spec[] = { "dom", NULL };
-    static char *arg_spec = "i";
+static PyObject *xspy_release_domain(XsHandle *self, PyObject *args)
+{
     domid_t dom;
 
     struct xs_handle *xh = xshandle(self);
@@ -677,8 +627,7 @@
 
     if (!xh)
         return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &dom))
+    if (!PyArg_ParseTuple(args, "i", &dom))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -696,27 +645,21 @@
        "Raises RuntimeError on error.\n"       \
        "\n"
 
-static PyObject *xspy_close(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwd_spec[] = { NULL };
-    static char *arg_spec = "";
+static PyObject *xspy_close(XsHandle *self)
+{
+    struct xs_handle *xh = xshandle(self);
     int i;
 
-    XsHandle *xsh = (XsHandle *)self;
-    struct xs_handle *xh = xshandle(self);
-
-    if (!xh)
-        return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
-        return NULL;
-
-    for (i = 0; i < PyList_Size(xsh->watches); i++) {
+    if (!xh)
+        return NULL;
+
+    for (i = 0; i < PyList_Size(self->watches); i++) {
         /* TODO: xs_unwatch watches */
-        PySequence_SetItem(xsh->watches, i, Py_None);
+        PySequence_SetItem(self->watches, i, Py_None);
     }
 
     xs_daemon_close(xh);
-    xsh->xh = NULL;
+    self->xh = NULL;
 
     Py_INCREF(Py_None);
     return Py_None;
@@ -731,20 +674,15 @@
        "Raises RuntimeError on error.\n"               \
        "\n"
 
-static PyObject *xspy_get_domain_path(PyObject *self, PyObject *args,
-                                     PyObject *kwds)
-{
-    static char *kwd_spec[] = { "domid", NULL };
-    static char *arg_spec = "i";
-    int domid = 0;
-
-    struct xs_handle *xh = xshandle(self);
-    char *xsval = NULL;
-
-    if (!xh)
-        return NULL;
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &domid))
+static PyObject *xspy_get_domain_path(XsHandle *self, PyObject *args)
+{
+    struct xs_handle *xh = xshandle(self);
+    int domid;
+    char *xsval;
+
+    if (!xh)
+        return NULL;
+    if (!PyArg_ParseTuple(args, "i", &domid))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
@@ -766,13 +704,13 @@
  * Remove the given token from the watches list belonging to the given
  * XsHandle, if present.
  */
-static void remove_watch(XsHandle *xsh, PyObject *token)
+static void remove_watch(XsHandle *self, PyObject *token)
 {
     int i;
 
-    for (i = 0; i < PyList_Size(xsh->watches); i++) {
-        if (PyList_GetItem(xsh->watches, i) == token) {
-            PySequence_SetItem(xsh->watches, i, Py_None);
+    for (i = 0; i < PyList_Size(self->watches); i++) {
+        if (PyList_GetItem(self->watches, i) == token) {
+            PySequence_SetItem(self->watches, i, Py_None);
             return;
         }
     }
@@ -787,14 +725,11 @@
  * @return 1 on success, in which case *xh, *th, and *path are valid, or 0 on
  * failure.
  */
-static int parse_transaction_path(PyObject *self, PyObject *args,
-                                  PyObject *kwds,
+static int parse_transaction_path(XsHandle *self, PyObject *args,
                                   struct xs_handle **xh,
                                   struct xs_transaction_handle **th,
                                   char **path)
 {
-    static char *arg_spec = "ss";
-    static char *kwd_spec[] = { "transaction", "path", NULL };
     char *thstr;
 
     *xh = xshandle(self);
@@ -802,8 +737,7 @@
     if (!xh)
         return 0;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &thstr, path))
+    if (!PyArg_ParseTuple(args, "ss", &thstr, path))
         return 0;
 
     *th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
@@ -825,30 +759,30 @@
 }
 
 
-#define XSPY_METH(_name) {                     \
+#define XSPY_METH(_name, _args) {               \
     .ml_name  = #_name,                                \
     .ml_meth  = (PyCFunction) xspy_ ## _name,  \
-    .ml_flags = (METH_VARARGS | METH_KEYWORDS),        \
+    .ml_flags = _args,                          \
     .ml_doc   = xspy_ ## _name ## _doc }
 
 static PyMethodDef xshandle_methods[] = {
-     XSPY_METH(read),
-     XSPY_METH(write),
-     XSPY_METH(ls),
-     XSPY_METH(mkdir),
-     XSPY_METH(rm),
-     XSPY_METH(get_permissions),
-     XSPY_METH(set_permissions),
-     XSPY_METH(watch),
-     XSPY_METH(read_watch),
-     XSPY_METH(unwatch),
-     XSPY_METH(transaction_start),
-     XSPY_METH(transaction_end),
-     XSPY_METH(introduce_domain),
-     XSPY_METH(release_domain),
-     XSPY_METH(close),
-     XSPY_METH(get_domain_path),
-     { /* Terminator. */ },
+    XSPY_METH(read,              METH_VARARGS),
+    XSPY_METH(write,             METH_VARARGS),
+    XSPY_METH(ls,                METH_VARARGS),
+    XSPY_METH(mkdir,             METH_VARARGS),
+    XSPY_METH(rm,                METH_VARARGS),
+    XSPY_METH(get_permissions,   METH_VARARGS),
+    XSPY_METH(set_permissions,   METH_VARARGS),
+    XSPY_METH(watch,             METH_VARARGS),
+    XSPY_METH(read_watch,        METH_NOARGS),
+    XSPY_METH(unwatch,           METH_VARARGS),
+    XSPY_METH(transaction_start, METH_NOARGS),
+    XSPY_METH(transaction_end,   METH_VARARGS | METH_KEYWORDS),
+    XSPY_METH(introduce_domain,  METH_VARARGS),
+    XSPY_METH(release_domain,    METH_VARARGS),
+    XSPY_METH(close,             METH_NOARGS),
+    XSPY_METH(get_domain_path,   METH_VARARGS),
+    { NULL /* Sentinel. */ },
 };
 
 static PyObject *xshandle_getattr(PyObject *self, char *name)
@@ -856,84 +790,119 @@
     return Py_FindMethod(xshandle_methods, self, name);
 }
 
-static void xshandle_dealloc(PyObject *self)
-{
-    XsHandle *xh = (XsHandle*)self;
-    if (xh->xh) {
-        xs_daemon_close(xh->xh);
-        xh->xh = NULL;
-    }
-    PyObject_Del(self);
-}
-
-static PyTypeObject xshandle_type = {
-    PyObject_HEAD_INIT(&PyType_Type)
-    0,
-    "xshandle",
-    sizeof(XsHandle),
-    0,
-    xshandle_dealloc,   /* tp_dealloc     */
-    NULL,               /* tp_print       */
-    xshandle_getattr,   /* tp_getattr     */
-    NULL,               /* tp_setattr     */
-    NULL,               /* tp_compare     */
-    NULL,               /* tp_repr        */
-    NULL,               /* tp_as_number   */
-    NULL,               /* tp_as_sequence */
-    NULL,               /* tp_as_mapping  */
-    NULL                /* tp_hash        */
-};
-
-static PyObject *xshandle_open(PyObject *self, PyObject *args, PyObject *kwds)
+static PyObject *
+xshandle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    XsHandle *self = (XsHandle *)type->tp_alloc(type, 0);
+
+    if (self == NULL)
+        return NULL;
+
+    self->xh = NULL;
+    self->watches = PyList_New(0);
+    if (!self->watches)
+        goto fail;
+
+    return (PyObject *)self;
+fail:
+    /* Decreasing the object's reference to 0 will result in xshandle_dealloc
+       being called. */
+    Py_DECREF(self);
+    return NULL;
+}
+
+static int
+xshandle_init(XsHandle *self, PyObject *args, PyObject *kwds)
 {
     static char *kwd_spec[] = { "readonly", NULL };
     static char *arg_spec = "|i";
     int readonly = 0;
 
-    XsHandle *xsh = NULL;
-    PyObject *val = NULL;
-
     if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
                                      &readonly))
-        return NULL;
-
-    xsh = PyObject_New(XsHandle, &xshandle_type);
-    if (!xsh)
-        return NULL;
-    xsh->watches = PyList_New(0);
-    if (!xsh->watches)
-        goto exit;
-    xsh->xh = (readonly ? xs_daemon_open_readonly() : xs_daemon_open());
-    if (!xsh->xh) {
-        Py_DECREF(xsh->watches);
-        PyErr_SetFromErrno(PyExc_RuntimeError);
-        goto exit;
-    }
-    val = (PyObject *)xsh;
-    return val;
- exit:
-    PyObject_Del(xsh);
-    return NULL;
-}
-
-static PyMethodDef xs_methods[] = {
-    { .ml_name  = "open",
-      .ml_meth  = (PyCFunction)xshandle_open,
-      .ml_flags = (METH_VARARGS | METH_KEYWORDS), 
-      .ml_doc   = "\n"
-      "Open a connection to the xenstore daemon.\n"
-      "Returns: xs connection object.\n"
-      "Raises RuntimeError on error.\n"
-      "\n"
-    },
-    { /* Terminator. */ }
+        goto fail;
+
+    self->xh = (readonly ? xs_daemon_open_readonly() : xs_daemon_open());
+    if (!self->xh)
+        goto fail;
+
+    return 0;
+
+ fail:
+    PyErr_SetFromErrno(PyExc_RuntimeError);
+    return -1;
+}
+
+static void xshandle_dealloc(XsHandle *self)
+{
+    if (self->xh) {
+        xs_daemon_close(self->xh);
+        self->xh = NULL;
+    }
+
+    Py_XDECREF(self->watches);
+
+    self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyTypeObject xshandle_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    PKG "." CLS,
+    sizeof(XsHandle),
+    0,
+    (destructor)xshandle_dealloc, /* tp_dealloc        */
+    NULL,                         /* tp_print          */
+    xshandle_getattr,             /* tp_getattr        */
+    NULL,                         /* tp_setattr        */
+    NULL,                         /* tp_compare        */
+    NULL,                         /* tp_repr           */
+    NULL,                         /* tp_as_number      */
+    NULL,                         /* tp_as_sequence    */
+    NULL,                         /* tp_as_mapping     */
+    NULL,                         /* tp_hash           */
+    NULL,                         /* tp_call           */
+    NULL,                         /* tp_str            */
+    NULL,                         /* tp_getattro       */
+    NULL,                         /* tp_setattro       */
+    NULL,                         /* tp_as_buffer      */
+    Py_TPFLAGS_DEFAULT,           /* tp_flags          */
+    "Xenstore connections",       /* tp_doc            */
+    NULL,                         /* tp_traverse       */
+    NULL,                         /* tp_clear          */
+    NULL,                         /* tp_richcompare    */
+    0,                            /* tp_weaklistoffset */
+    NULL,                         /* tp_iter           */
+    NULL,                         /* tp_iternext       */
+    xshandle_methods,             /* tp_methods        */
+    NULL,                         /* tp_members        */
+    NULL,                         /* tp_getset         */
+    NULL,                         /* tp_base           */
+    NULL,                         /* tp_dict           */
+    NULL,                         /* tp_descr_get      */
+    NULL,                         /* tp_descr_set      */
+    0,                            /* tp_dictoffset     */
+    (initproc)xshandle_init,      /* tp_init           */
+    NULL,                         /* tp_alloc          */
+    xshandle_new,                 /* tp_new            */
 };
 
-PyMODINIT_FUNC initxs (void)
-{
-    PyObject *module;
-
-    module = Py_InitModule(PYPKG, xs_methods);
+static PyMethodDef xs_methods[] = { { NULL } };
+
+PyMODINIT_FUNC initxs(void)
+{
+    PyObject* m;
+
+    if (PyType_Ready(&xshandle_type) < 0)
+        return;
+
+    m = Py_InitModule(PKG, xs_methods);
+
+    if (m == NULL)
+      return;
+
+    Py_INCREF(&xshandle_type);
+    PyModule_AddObject(m, CLS, (PyObject *)&xshandle_type);
 }
 
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/web/connection.py
--- a/tools/python/xen/web/connection.py        Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/web/connection.py        Fri Dec  2 18:52:25 2005
@@ -14,6 +14,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd.
 #============================================================================
 
 import sys
@@ -46,13 +47,10 @@
         self.server = server
         self.buffer_n = 1024
         self.thread = None
-        self.connected = True
-        protocol.setTransport(self)
-        protocol.connectionMade(addr)
+        self.protocol.setTransport(self)
 
     def run(self):
         self.thread = threading.Thread(target=self.main)
-        #self.thread.setDaemon(True)
         self.thread.start()
 
     def main(self):
@@ -91,10 +89,6 @@
                 return True
 
     def dataReceived(self, data):
-        if not self.connected:
-            return True
-        if not self.protocol:
-            return True
         try:
             self.protocol.dataReceived(data)
         except SystemExit:
@@ -110,7 +104,6 @@
     def loseConnection(self, reason=None):
         self.thread = None
         self.closeSocket(reason)
-        self.closeProtocol(reason)
 
     def closeSocket(self, reason):
         try:
@@ -119,33 +112,16 @@
             raise
         except:
             pass
-
-    def closeProtocol(self, reason):
-        try:
-            if self.connected:
-                self.connected = False
-                if self.protocol:
-                    self.protocol.connectionLost(reason)
-        except SystemExit:
-            raise
-        except:
-            pass
-
-    def getHost(self):
-        return self.sock.getsockname()
-
-    def getPeer(self):
-        return self.addr
 
 class SocketListener:
     """A server socket, running listen in a thread.
     Accepts connections and runs a thread for each one.
     """
 
-    def __init__(self, factory, backlog=None):
+    def __init__(self, protocol_class, backlog=None):
         if backlog is None:
             backlog = 5
-        self.factory = factory
+        self.protocol_class = protocol_class
         self.sock = None
         self.backlog = backlog
         self.thread = None
@@ -171,9 +147,7 @@
         self.loseConnection(reason)
 
     def run(self):
-        self.factory.doStart()
         self.thread = threading.Thread(target=self.main)
-        #self.thread.setDaemon(True)
         self.thread.start()
 
     def main(self):
@@ -206,18 +180,12 @@
                 return True
 
     def accepted(self, sock, addr):
-        protocol = self.factory.buildProtocol(addr)
-        if protocol is None:
-            self.loseConnection()
-            return True
-        connection = self.acceptConnection(sock, protocol, addr)
-        connection.run()
+        self.acceptConnection(sock, self.protocol_class(), addr).run()
         return False
 
     def loseConnection(self, reason=None):
         self.thread = None
         self.closeSocket(reason)
-        self.closeFactory(reason)
 
     def closeSocket(self, reason):
         try:
@@ -227,13 +195,6 @@
         except Exception, ex:
             pass
 
-    def closeFactory(self, reason):
-        try:
-            self.factory.doStop()
-        except SystemExit:
-            raise
-        except:
-            pass
 
 class SocketClientConnection:
     """A connection to a server from a client.
@@ -246,7 +207,6 @@
         self.addr = None
         self.connector = connector
         self.buffer_n = 1024
-        self.connected = False
 
     def createSocket (self):
         raise NotImplementedError()
@@ -263,8 +223,7 @@
             sock = self.createSocket()
             sock.connect(self.addr)
             self.sock = sock
-            self.connected = True
-            self.protocol = self.connector.buildProtocol(self.addr)
+            self.protocol = self.connector.protocol_class()
             self.protocol.setTransport(self)
         except SystemExit:
             raise
@@ -335,8 +294,6 @@
     def loseConnection(self, reason=None):
         self.thread = None
         self.closeSocket(reason)
-        self.closeProtocol(reason)
-        self.closeConnector(reason)
 
     def closeSocket(self, reason):
         try:
@@ -347,71 +304,14 @@
         except:
             pass
 
-    def closeProtocol(self, reason):
-        try:
-            if self.connected:
-                self.connected = False
-                if self.protocol:
-                    self.protocol.connectionLost(reason)
-        except SystemExit:
-            raise
-        except:
-            pass
-        self.protocol = None
-
-    def closeConnector(self, reason):
-        try:
-            self.connector.connectionLost(reason)
-        except SystemExit:
-            raise
-        except:
-            pass
-        
 class SocketConnector:
     """A client socket. Connects to a server and runs the client protocol
     in a thread.
     """
 
-    def __init__(self, factory):
-        self.factoryStarted = False
-        self.clientLost = False
-        self.clientFailed = False
-        self.factory = factory
-        self.state = "disconnected"
+    def __init__(self, protocol_class):
+        self.protocol_class = protocol_class
         self.transport = None
 
-    def connectTransport(self):
-        raise NotImplementedError()
-
     def connect(self):
-        if self.state != "disconnected":
-            raise socket.error(EINVAL, "cannot connect in state " + self.state)
-        self.state = "connecting"
-        self.clientLost = False
-        self.clientFailed = False
-        if not self.factoryStarted:
-            self.factoryStarted = True
-            self.factory.doStart()
-        self.factory.startedConnecting(self)
-        self.connectTransport()
-        self.state = "connected"
-
-    def stopConnecting(self):
-        if self.state != "connecting":
-            return
-        self.state = "disconnected"
-        self.transport.disconnect()
-
-    def buildProtocol(self, addr):
-        return self.factory.buildProtocol(addr)
-
-    def connectionLost(self, reason=None):
-        if not self.clientLost:
-            self.clientLost = True
-            self.factory.clientConnectionLost(self, reason)
-
-    def connectionFailed(self, reason=None):
-        if not self.clientFailed:
-            self.clientFailed = True
-            self.factory.clientConnectionFailed(self, reason)
-        
+        pass
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/web/protocol.py
--- a/tools/python/xen/web/protocol.py  Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/web/protocol.py  Fri Dec  2 18:52:25 2005
@@ -13,85 +13,19 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd.
 #============================================================================
-
-class Factory:
-    """Generic protocol factory.
-    """
-
-    starts = 0
-
-    def __init__(self):
-        pass
-
-    def doStart(self):
-        if self.starts == 0:
-            self.startFactory()
-        self.starts += 1
-
-    def doStop(self):
-        if self.starts > 0:
-            self.starts -= 1
-        else:
-            return
-        if self.starts == 0:
-            self.stopFactory()
-
-    def buildProtocol(self, addr):
-        return Protocol(self)
-
-    def startFactory(self):
-        pass
-
-    def stopFactory(self):
-        pass
-
-class ServerFactory(Factory):
-    """Factory for server protocols.
-    """
-    pass
-    
-class ClientFactory(Factory):
-    """Factory for client protocols.
-    """
-    
-    def startedConnecting(self, connector):
-        pass
-
-    def clientConnectionLost(self, connector, reason):
-        pass
-
-    def clientConnectionFailed(self, connector, reason):
-        pass
-
 
 class Protocol:
 
-    factory = None
-    transport = None
-    connected = False
-
-    def __init__(self, factory):
-        self.factory = factory
+    def __init__(self):
+        self.transport = None
 
     def setTransport(self, transport):
         self.transport = transport
-        self.connected = bool(transport)
-
-    def getTransport(self):
-        return self.transport
-
-    def connectionMade(self, addr):
-        print 'Protocol>connectionMade>', addr
-        pass
-
-    def connectionLost(self, reason=None):
-        print 'Protocol>connectionLost>', reason
-        pass
 
     def dataReceived(self, data):
         print 'Protocol>dataReceived>'
-        pass
 
     def write(self, data):
         if self.transport:
@@ -104,40 +38,3 @@
             return self.transport.read()
         else:
             return None
-
-class TestClientFactory(ClientFactory):
-
-    def buildProtocol(self, addr):
-        print 'TestClientFactory>buildProtocol>', addr
-        return TestClientProtocol(self)
-    
-    def startedConnecting(self, connector):
-        print 'TestClientFactory>startedConnecting>', connector
-
-    def clientConnectionLost(self, connector, reason):
-        print 'TestClientFactory>clientConnectionLost>', connector, reason
-
-    def clientConnectionFailed(self, connector, reason):
-        print 'TestClientFactory>clientConnectionFailed>', connector, reason
-
-class TestClientProtocol(Protocol):
-
-    def connectionMade(self, addr):
-        print 'TestClientProtocol>connectionMade>', addr
-        self.write("hello")
-        self.write("there")
-
-class TestServerFactory(Factory):
-
-    def buildProtocol(self, addr):
-        print 'TestServerFactory>buildProtocol>', addr
-        return TestServerProtocol(self)
-    
-class TestServerProtocol(Protocol):
-
-    def dataReceived(self, data):
-        print 'TestServerProtocol>dataReceived>', len(data), data
-        #sys.exit(0)
-        import os
-        os._exit(0)
-        
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/web/tcp.py
--- a/tools/python/xen/web/tcp.py       Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/web/tcp.py       Fri Dec  2 18:52:25 2005
@@ -24,13 +24,10 @@
 from connection import *
 from protocol import *
 
-class TCPServerConnection(SocketServerConnection):
-    pass
-
 class TCPListener(SocketListener):
 
-    def __init__(self, port, factory, backlog=None, interface=''):
-        SocketListener.__init__(self, factory, backlog=backlog)
+    def __init__(self, port, protocol, backlog=None, interface=''):
+        SocketListener.__init__(self, protocol, backlog=backlog)
         self.port = port
         self.interface = interface
         
@@ -53,7 +50,7 @@
                     raise
 
     def acceptConnection(self, sock, protocol, addr):
-        return TCPServerConnection(sock, protocol, addr, self)
+        return SocketServerConnection(sock, protocol, addr, self)
 
 class TCPClientConnection(SocketClientConnection):
 
@@ -70,8 +67,8 @@
     
 class TCPConnector(SocketConnector):
 
-    def __init__(self, host, port, factory, timeout=None, bindAddress=None):
-        SocketConnector.__init__(self, factory)
+    def __init__(self, host, port, protocol, timeout=None, bindAddress=None):
+        SocketConnector.__init__(self, protocol)
         self.host = host
         self.port = self.servicePort(port)
         self.bindAddress = bindAddress
@@ -85,33 +82,18 @@
                 raise IOError("unknown service: " + ex)
         return port
 
-    def connectTransport(self):
+    def connect(self):
         self.transport = TCPClientConnection(
             self.host, self.port, self.bindAddress, self)
         self.transport.connect(self.timeout)
 
-def listenTCP(port, factory, interface='', backlog=None):
-    l = TCPListener(port, factory, interface=interface, backlog=backlog)
+def listenTCP(port, protocol, interface='', backlog=None):
+    l = TCPListener(port, protocol, interface=interface, backlog=backlog)
     l.startListening()
     return l
 
-def connectTCP(host, port, factory, timeout=None, bindAddress=None):
-    c = TCPConnector(host, port, factory, timeout=timeout, 
bindAddress=bindAddress)
+def connectTCP(host, port, protocol, timeout=None, bindAddress=None):
+    c = TCPConnector(host, port, protocol, timeout=timeout,
+                     bindAddress=bindAddress)
     c.connect()
     return c
-
-def main(argv):
-    host = 'localhost'
-    port = 8005
-    if argv[1] == "client":
-        c = connectTCP(host, port, TestClientFactory())
-        print 'client:', c
-    else:
-        s = listenTCP(port, TestServerFactory())
-        print 'server:', s
-        
-if __name__ == "__main__":
-    main(sys.argv)
-
-        
-
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/web/unix.py
--- a/tools/python/xen/web/unix.py      Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/web/unix.py      Fri Dec  2 18:52:25 2005
@@ -13,6 +13,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd.
 #============================================================================
 
 import sys
@@ -23,13 +24,10 @@
 from connection import *
 from protocol import *
 
-class UnixServerConnection(SocketServerConnection):
-    pass
-
 class UnixListener(SocketListener):
 
-    def __init__(self, path, factory, backlog=None):
-        SocketListener.__init__(self, factory, backlog=backlog)
+    def __init__(self, path, protocol, backlog=None):
+        SocketListener.__init__(self, protocol, backlog=backlog)
         self.path = path
         
     def createSocket(self):
@@ -48,7 +46,7 @@
         return sock
 
     def acceptConnection(self, sock, protocol, addr):
-        return UnixServerConnection(sock, protocol, self.path, self)
+        return SocketServerConnection(sock, protocol, self.path, self)
 
 class UnixClientConnection(SocketClientConnection):
 
@@ -62,34 +60,21 @@
     
 class UnixConnector(SocketConnector):
 
-    def __init__(self, path, factory, timeout=None):
-        SocketConnector.__init__(self, factory)
+    def __init__(self, path, protocol, timeout=None):
+        SocketConnector.__init__(self, protocol)
         self.addr = path
         self.timeout = timeout
 
-    def connectTransport(self):
+    def connect(self):
         self.transport = UnixClientConnection(self.addr, self)
         self.transport.connect(self.timeout)
 
-def listenUNIX(path, factory, backlog=None):
-    l = UnixListener(path, factory, backlog=backlog)
+def listenUNIX(path, protocol, backlog=None):
+    l = UnixListener(path, protocol, backlog=backlog)
     l.startListening()
     return l
 
-def connectUNIX(path, factory, timeout=None):
-    c = UnixConnector(path, factory, timeout=timeout)
+def connectUNIX(path, protocol, timeout=None):
+    c = UnixConnector(path, protocol, timeout=timeout)
     c.connect()
     return c
-
-def main(argv):
-    path = "/tmp/test-foo"
-    if argv[1] == "client":
-        c = connectUNIX(path, TestClientFactory())
-        print "client:", c
-    else:
-        s = listenUNIX(path, TestServeractory())
-        print "server:", s
-
-if __name__ == "__main__":
-    main(sys.argv)
-
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Fri Dec  2 18:52:25 2005
@@ -18,8 +18,7 @@
 
 import xen.lowlevel.xc
 
-from xen.xend.xenstore.xsutil import IntroduceDomain
-
+import balloon
 from XendError import XendError
 from XendLogging import log
 
@@ -33,7 +32,7 @@
 sizeof_unsigned_long = calcsize("L")
 
 
-xc = xen.lowlevel.xc.new()
+xc = xen.lowlevel.xc.xc()
 
 
 def write_exact(fd, buf, errmsg):
@@ -41,10 +40,18 @@
         raise XendError(errmsg)
 
 def read_exact(fd, size, errmsg):
-    buf = os.read(fd, size)
-    if len(buf) != size:
-        raise XendError(errmsg)
+    buf  = '' 
+    while size != 0: 
+        str = os.read(fd, size)
+        if not len(str):
+            log.error("read_exact: EOF trying to read %d (buf='%s')" % \
+                      (size, buf))
+            raise XendError(errmsg)
+        size = size - len(str)
+        buf  = buf + str
     return buf
+
+
 
 def save(fd, dominfo, live):
     write_exact(fd, SIGNATURE, "could not write guest state file: signature")
@@ -128,10 +135,12 @@
     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
+        nr_pfns = unpack("L", l)[0]    # native sizeof long
         if nr_pfns > 16*1024*1024:     # XXX 
             raise XendError(
                 "not a valid guest state file: pfn count out of range")
+
+        balloon.free(xc.pages_to_kib(nr_pfns))
 
         cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
                         xc.handle(), fd, dominfo.getDomid(), nr_pfns,
@@ -215,4 +224,4 @@
         if line == "":
             break
         else:
-            log.error('%s', line)
+            log.error('%s', line.strip())
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendClient.py       Fri Dec  2 18:52:25 2005
@@ -231,6 +231,11 @@
     def xend_domain_pause(self, id):
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'pause' })
+
+    def xend_domain_rename(self, id, name):
+        return self.xendPost(self.domainurl(id),
+                             {'op'      : 'rename',
+                              'name'    : name})
 
     def xend_domain_shutdown(self, id, reason):
         return self.xendPost(self.domainurl(id),
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendDmesg.py
--- a/tools/python/xen/xend/XendDmesg.py        Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendDmesg.py        Fri Dec  2 18:52:25 2005
@@ -22,7 +22,7 @@
 
 class XendDmesg:
     def __init__(self):
-        self.xc = xen.lowlevel.xc.new()
+        self.xc = xen.lowlevel.xc.xc()
 
     def info(self):
         return self.xc.readconsolering()
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendDomain.py       Fri Dec  2 18:52:25 2005
@@ -24,6 +24,7 @@
 
 import logging
 import os
+import socket
 import sys
 import threading
 
@@ -35,11 +36,10 @@
 from xen.xend import XendCheckpoint
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
-from xen.xend.server import relocate
 from xen.xend.xenstore.xswatch import xswatch
 
 
-xc = xen.lowlevel.xc.new()
+xc = xen.lowlevel.xc.xc()
 xroot = XendRoot.instance()
 
 
@@ -54,15 +54,16 @@
     ## public:
     
     def __init__(self):
-        # Hack alert. Python does not support mutual imports, but 
XendDomainInfo
-        # needs access to the XendDomain instance to look up domains. 
Attempting
-        # 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 = {}
         self.domains_lock = threading.RLock()
 
+
+    # This must be called only the once, by instance() below.  It is separate
+    # from the constructor because XendDomainInfo calls back into this class
+    # in order to check the uniqueness of domain names.  This means that
+    # instance() must be able to return a valid instance of this class even
+    # during this initialisation.
+    def init(self):
         self.domains_lock.acquire()
         try:
             self._add_domain(
@@ -114,7 +115,7 @@
 
     ## private:
 
-    def onReleaseDomain(self):
+    def onReleaseDomain(self, _):
         self.domains_lock.acquire()
         try:
             self.refresh()
@@ -201,7 +202,7 @@
                             "%d.  Destroying it in the hope of "
                             "recovery.", d)
                         try:
-                            xc.domain_destroy(dom = d)
+                            xc.domain_destroy(d)
                         except:
                             log.exception('Destruction of %d failed.', d)
 
@@ -378,7 +379,7 @@
             val = dominfo.destroy()
         else:
             try:
-                val = xc.domain_destroy(dom=domid)
+                val = xc.domain_destroy(domid)
             except Exception, ex:
                 raise XendError(str(ex))
         return val       
@@ -389,10 +390,16 @@
         dominfo = self.domain_lookup(domid)
 
         port = xroot.get_xend_relocation_port()
-        sock = relocate.setupRelocation(dst, port)
-
+        try:
+            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            sock.connect((dst, port))
+        except socket.error, err:
+            raise XendError("can't connect: %s" % err[1])
+
+        sock.send("receive\n")
+        sock.recv(80) 
         XendCheckpoint.save(sock.fileno(), dominfo, live)
-        
+
 
     def domain_save(self, domid, dst):
         """Start saving a domain to file.
@@ -480,8 +487,7 @@
         dominfo = self.domain_lookup(domid)
         maxmem = int(mem) * 1024
         try:
-            return xc.domain_setmaxmem(dominfo.getDomid(),
-                                       maxmem_kb = maxmem)
+            return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
         except Exception, ex:
             raise XendError(str(ex))
 
@@ -528,4 +534,5 @@
         inst
     except:
         inst = XendDomain()
+        inst.init()
     return inst
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Dec  2 18:52:25 2005
@@ -33,15 +33,15 @@
 from xen.util import asserts
 from xen.util.blkif import blkdev_uname_to_file
 
-from xen.xend import image
-from xen.xend import scheduler
-from xen.xend import sxp
-from xen.xend import XendRoot
+import balloon
+import image
+import sxp
+import uuid
+import XendDomain
+import XendRoot
+
 from xen.xend.XendBootloader import bootloader
 from xen.xend.XendError import XendError, VmError
-from xen.xend.XendRoot import get_component
-
-import uuid
 
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
@@ -94,7 +94,7 @@
 RESTART_IN_PROGRESS = 'xend/restart_in_progress'
 
 
-xc = xen.lowlevel.xc.new()
+xc = xen.lowlevel.xc.xc()
 xroot = XendRoot.instance()
 
 log = logging.getLogger("xend.XendDomainInfo")
@@ -227,13 +227,13 @@
                 'Uuid in store does not match uuid for existing domain %d: '
                 '%s != %s' % (domid, uuid2_str, xeninfo['uuid']))
 
-        vm = XendDomainInfo(xeninfo, domid, dompath, True)
+        vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
 
     except Exception, exn:
         if priv:
             log.warn(str(exn))
 
-        vm = XendDomainInfo(xeninfo, domid, dompath, True)
+        vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
         vm.removeDom()
         vm.removeVm()
         vm.storeVmDetails()
@@ -339,9 +339,8 @@
 
 
 def domain_by_name(name):
-    # See comment in XendDomain constructor.
-    xd = get_component('xen.xend.XendDomain')
-    return xd.domain_lookup_by_name_nr(name)
+    return XendDomain.instance().domain_lookup_by_name_nr(name)
+
 
 def shutdown_reason(code):
     """Get a shutdown reason from a code.
@@ -371,7 +370,8 @@
 
 class XendDomainInfo:
 
-    def __init__(self, info, domid = None, dompath = None, augment = False):
+    def __init__(self, info, domid = None, dompath = None, augment = False,
+                 priv = False):
 
         self.info = info
 
@@ -389,7 +389,7 @@
         self.dompath = dompath
 
         if augment:
-            self.augmentInfo()
+            self.augmentInfo(priv)
 
         self.validateInfo()
 
@@ -425,8 +425,8 @@
             return []
 
 
-    def storeChanged(self):
-        log.debug("XendDomainInfo.storeChanged");
+    def storeChanged(self, _):
+        log.trace("XendDomainInfo.storeChanged");
 
         changed = False
         
@@ -445,7 +445,7 @@
         return 1
 
 
-    def augmentInfo(self):
+    def augmentInfo(self, priv):
         """Augment self.info, as given to us through {@link #recreate}, with
         values taken from the store.  This recovers those values known to xend
         but not to the hypervisor.
@@ -454,8 +454,15 @@
             if not self.infoIsSet(name) and val is not None:
                 self.info[name] = val
 
-        map(lambda x, y: useIfNeeded(x[0], y), VM_STORE_ENTRIES,
-            self.readVMDetails(VM_STORE_ENTRIES))
+        if priv:
+            entries = VM_STORE_ENTRIES[:]
+            entries.remove(('memory', int))
+            entries.remove(('maxmem', int))
+        else:
+            entries = VM_STORE_ENTRIES
+
+        map(lambda x, y: useIfNeeded(x[0], y), entries,
+            self.readVMDetails(entries))
 
         device = []
         for c in controllerClasses:
@@ -790,7 +797,7 @@
                         log.debug(
                             "Scheduling refreshShutdown on domain %d in %ds.",
                             self.domid, timeout)
-                        scheduler.later(timeout, self.refreshShutdown)
+                        threading.Timer(timeout, self.refreshShutdown).start()
         finally:
             self.refresh_shutdown_lock.release()
 
@@ -831,7 +838,7 @@
         try:
             corefile = "/var/xen/dump/%s.%s.core" % (self.info['name'],
                                                      self.domid)
-            xc.domain_dumpcore(dom = self.domid, corefile = corefile)
+            xc.domain_dumpcore(self.domid, corefile)
 
         except:
             log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
@@ -844,6 +851,9 @@
         """Set the memory target of this domain.
         @param target In MiB.
         """
+        log.debug("Setting memory target of domain %s (%d) to %d MiB.",
+                  self.info['name'], self.domid, target)
+        
         self.info['memory'] = target
         self.storeVm("memory", target)
         self.storeDom("memory/target", target << 10)
@@ -1099,36 +1109,41 @@
         if not self.infoIsSet('image'):
             raise VmError('Missing image in configuration')
 
-        self.image = image.create(self,
-                                  self.info['image'],
-                                  self.info['device'])
-
-        xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
-
-        m = self.image.getDomainMemory(self.info['memory'] * 1024)
-        xc.domain_setmaxmem(self.domid, maxmem_kb = m)
-        xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
-
-        cpu = self.info['cpu']
-        if cpu is not None and cpu != -1:
-            xc.domain_pincpu(self.domid, 0, 1 << cpu)
-
-        self.createChannels()
-
-        channel_details = self.image.createImage()
-
-        self.store_mfn = channel_details['store_mfn']
-        if 'console_mfn' in channel_details:
-            self.console_mfn = channel_details['console_mfn']
-
-        self.introduceDomain()
-
-        self.createDevices()
-
-        if self.info['bootloader']:
-            self.image.cleanupBootloading()
-
-        self.info['start_time'] = time.time()
+        try:
+            self.image = image.create(self,
+                                      self.info['image'],
+                                      self.info['device'])
+
+            xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
+
+            m = self.image.getDomainMemory(self.info['memory'] * 1024)
+            balloon.free(m)
+            xc.domain_setmaxmem(self.domid, m)
+            xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
+
+            cpu = self.info['cpu']
+            if cpu is not None and cpu != -1:
+                xc.domain_pincpu(self.domid, 0, 1 << cpu)
+
+            self.createChannels()
+
+            channel_details = self.image.createImage()
+
+            self.store_mfn = channel_details['store_mfn']
+            if 'console_mfn' in channel_details:
+                self.console_mfn = channel_details['console_mfn']
+
+            self.introduceDomain()
+
+            self.createDevices()
+
+            if self.info['bootloader']:
+                self.image.cleanupBootloading()
+
+            self.info['start_time'] = time.time()
+
+        except RuntimeError, exn:
+            raise VmError(str(exn))
 
 
     ## public:
@@ -1192,7 +1207,7 @@
 
         try:
             if self.domid is not None:
-                xc.domain_destroy(dom=self.domid)
+                xc.domain_destroy(self.domid)
         except:
             log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
 
@@ -1269,7 +1284,7 @@
         dev_type = sxp.name(dev_config)
         devid = self.createDevice(dev_type, dev_config)
         self.waitForDevice(dev_type, devid)
-#        self.config.append(['device', dev.getConfig()])
+        self.info['device'].append((dev_type, dev_config))
         return self.getDeviceController(dev_type).sxpr(devid)
 
 
@@ -1340,8 +1355,7 @@
 
             new_dom = None
             try:
-                xd = get_component('xen.xend.XendDomain')
-                new_dom = xd.domain_create(config)
+                new_dom = XendDomain.instance().domain_create(config)
                 new_dom.unpause()
                 new_dom.removeVm(RESTART_IN_PROGRESS)
             except:
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendNode.py Fri Dec  2 18:52:25 2005
@@ -28,7 +28,7 @@
 class XendNode:
 
     def __init__(self):
-        self.xc = xen.lowlevel.xc.new()
+        self.xc = xen.lowlevel.xc.xc()
 
     def shutdown(self):
         return 0
@@ -40,7 +40,7 @@
         return 0
     
     def cpu_bvt_slice_set(self, ctx_allow):
-        return self.xc.bvtsched_global_set(ctx_allow=ctx_allow)
+        return self.xc.bvtsched_global_set(ctx_allow)
 
     def cpu_bvt_slice_get(self):
         return self.xc.bvtsched_global_get()
@@ -57,30 +57,45 @@
                 ['machine', mch]]
 
     def physinfo(self):
-        pinfo = self.xc.physinfo()
-        info = [['nr_cpus',          
pinfo['nr_nodes']*pinfo['sockets_per_node']*pinfo['cores_per_socket']*pinfo['threads_per_core']],
-                ['nr_nodes',         pinfo['nr_nodes']],
-                ['sockets_per_node', pinfo['sockets_per_node']],
-                ['cores_per_socket', pinfo['cores_per_socket']],
-                ['threads_per_core', pinfo['threads_per_core']],
-                ['cpu_mhz',          pinfo['cpu_khz']/1000],
-                ['hw_caps',          pinfo['hw_caps']],
-                ['memory',           pinfo['total_pages']/256],
-                ['free_memory',      pinfo['free_pages']/256]]
-        return info
-        
+        info = self.xc.physinfo()
+
+        info['nr_cpus'] = (info['nr_nodes'] *
+                           info['sockets_per_node'] *
+                           info['cores_per_socket'] *
+                           info['threads_per_core'])
+        info['cpu_mhz'] = info['cpu_khz'] / 1000
+
+        ITEM_ORDER = ['nr_cpus',
+                      'nr_nodes',
+                      'sockets_per_node',
+                      'cores_per_socket',
+                      'threads_per_core',
+                      'cpu_mhz',
+                      'hw_caps',
+                      'total_memory',
+                      'free_memory',
+                      ]
+
+        return [[k, info[k]] for k in ITEM_ORDER]
+
+
     def xeninfo(self):
-        xinfo = self.xc.xeninfo()
-        return [['xen_major', xinfo['xen_major']],
-                ['xen_minor', xinfo['xen_minor']],
-                ['xen_extra', xinfo['xen_extra']],
-                ['xen_caps',  xinfo['xen_caps']],
-                ['platform_params',xinfo['platform_params']],
-                ['xen_changeset', xinfo['xen_changeset']],
-                ['cc_compiler', xinfo['cc_compiler']],
-                ['cc_compile_by', xinfo['cc_compile_by']],
-                ['cc_compile_domain', xinfo['cc_compile_domain']],
-                ['cc_compile_date', xinfo['cc_compile_date']]]
+        info = self.xc.xeninfo()
+
+        ITEM_ORDER = ['xen_major',
+                      'xen_minor',
+                      'xen_extra',
+                      'xen_caps',
+                      'platform_params',
+                      'xen_changeset',
+                      'cc_compiler',
+                      'cc_compile_by',
+                      'cc_compile_domain',
+                      'cc_compile_date',
+                      ]
+
+        return [[k, info[k]] for k in ITEM_ORDER]
+
 
 def instance():
     global inst
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendProtocol.py
--- a/tools/python/xen/xend/XendProtocol.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendProtocol.py     Fri Dec  2 18:52:25 2005
@@ -100,7 +100,7 @@
         """
         return self.xendRequest(url, "POST", args)
 
-    def handleStatus(self, version, status, message):
+    def handleStatus(self, _, status, message):
         """Handle the status returned from the request.
         """
         status = int(status)
@@ -114,8 +114,8 @@
         """Handle the data returned in response to the request.
         """
         if data is None: return None
-        type = self.getHeader('Content-Type')
-        if type != sxp.mime_type:
+        typ = self.getHeader('Content-Type')
+        if typ != sxp.mime_type:
             return data
         try:
             pin = sxp.Parser()
@@ -205,5 +205,5 @@
             path = xroot.get_xend_unix_path()
         self.path = path
 
-    def makeConnection(self, url):
+    def makeConnection(self, _):
         return UnixConnection(self.path)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/XendRoot.py Fri Dec  2 18:52:25 2005
@@ -92,24 +92,6 @@
         self.config = None
         self.configure()
 
-
-    def add_component(self, name, val):
-        """Add a xend component.
-
-        @param name: component name
-        @param val:  component object
-        """
-        self.components[name] = val
-
-    def get_component(self, name):
-        """Get a xend component from its name.
-        This is used as a work-round for problems caused by mutually
-        recursive imports.
-
-        @param name: component name
-        @return: component object (or None)
-        """
-        return self.components.get(name)
 
     def _logError(self, fmt, *args):
         """Logging function to log to stderr. We use this for XendRoot log
@@ -189,7 +171,7 @@
         v = self.get_config_value(name, val)
         try:
             return int(v)
-        except Exception, ex:
+        except Exception:
             raise XendError("invalid xend config %s: expected int: %s" % 
(name, v))
 
     def get_xend_http_server(self):
@@ -277,21 +259,3 @@
     except:
         inst = XendRoot()
     return inst
-
-def add_component(name, val):
-    """Register a component with XendRoot.
-    This is used to work-round import cycles.
-
-    @param name: component name
-    @param val:  component value (often a module)
-    """
-    return instance().add_component(name, val)
-
-def get_component(name):
-    """Get a component.
-    This is used to work-round import cycles.
-
-    @param name: component name
-    @return component or None
-    """
-    return instance().get_component(name)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/image.py    Fri Dec  2 18:52:25 2005
@@ -27,7 +27,7 @@
 from xen.xend.server.netif import randomMAC
 
 
-xc = xen.lowlevel.xc.new()
+xc = xen.lowlevel.xc.xc()
 
 
 MAX_GUEST_CMDLINE = 1024
@@ -293,7 +293,7 @@
                ret.append("-bridge")
                ret.append("%s" % bridge)
             if name == 'vtpm':
-               instance = sxp.child_value(info, 'instance')
+               instance = sxp.child_value(info, 'pref_instance')
                ret.append("-instance")
                ret.append("%s" % instance)
         return ret
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/DevController.py     Fri Dec  2 18:52:25 2005
@@ -25,15 +25,18 @@
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xswatch import xswatch
 
-DEVICE_CREATE_TIMEOUT = 5
+DEVICE_CREATE_TIMEOUT = 10
 HOTPLUG_STATUS_NODE = "hotplug-status"
+HOTPLUG_ERROR_NODE  = "hotplug-error"
 HOTPLUG_STATUS_ERROR = "error"
+HOTPLUG_STATUS_BUSY  = "busy"
 
 Connected = 1
 Died      = 2
 Error     = 3
 Missing   = 4
 Timeout   = 5
+Busy      = 6
 
 xenbusState = {
     'Unknown'      : 0,
@@ -79,9 +82,37 @@
         if devid is None:
             return 0
 
-        self.writeDetails(config, devid, back, front)
-
-        return devid
+        (backpath, frontpath) = self.addStoreEntries(config, devid, back,
+                                                     front)
+
+        while True:
+            t = xstransact()
+            try:
+                if devid in self.deviceIDs(t):
+                    if 'dev' in back:
+                        dev_str = '%s (%d, %s)' % (back['dev'], devid,
+                                                   self.deviceClass)
+                    else:
+                        dev_str = '%s (%s)' % (devid, self.deviceClass)
+                    
+                    raise VmError("Device %s is already connected." % dev_str)
+
+                log.debug('DevController: writing %s to %s.', str(front),
+                          frontpath)
+                log.debug('DevController: writing %s to %s.', str(back),
+                          backpath)
+
+                t.remove(frontpath)
+                t.remove(backpath)
+
+                t.write2(frontpath, front)
+                t.write2(backpath,  back)
+
+                if t.commit():
+                    return devid
+            except:
+                t.abort()
+                raise
 
 
     def waitForDevices(self):
@@ -98,23 +129,38 @@
         if status == Timeout:
             self.destroyDevice(devid)
             raise VmError("Device %s (%s) could not be connected. "
-                          "Hotplug scripts not working" %
+                          "Hotplug scripts not working." %
                           (devid, self.deviceClass))
 
         elif status == Error:
             self.destroyDevice(devid)
             raise VmError("Device %s (%s) could not be connected. "
-                          "Backend device not found" %
+                          "Backend device not found." %
                           (devid, self.deviceClass))
 
         elif status == Missing:
+            # Don't try to destroy the device; it's already gone away.
             raise VmError("Device %s (%s) could not be connected. "
-                          "Device not found" % (devid, self.deviceClass))
+                          "Device not found." % (devid, self.deviceClass))
 
         elif status == Died:
             self.destroyDevice(devid)
             raise VmError("Device %s (%s) could not be connected. "
-                          "Device has died" % (devid, self.deviceClass))
+                          "Device has died." % (devid, self.deviceClass))
+
+        elif status == Busy:
+            err = None
+            frontpath = self.frontendPath(devid)
+            backpath = xstransact.Read(frontpath, "backend")
+            if backpath:
+                err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
+            if not err:
+                err = "Busy."
+                
+            self.destroyDevice(devid)
+            raise VmError("Device %s (%s) could not be connected.\n%s" %
+                          (devid, self.deviceClass, err))
+
 
 
     def reconfigureDevice(self, devid, config):
@@ -245,21 +291,29 @@
             raise VmError("Device %s not connected" % devid)
 
 
-    def deviceIDs(self):
+    def deviceIDs(self, transaction = None):
         """@return The IDs of each of the devices currently configured for
         this instance's deviceClass.
         """
-        return map(int, xstransact.List(self.frontendRoot()))
+        fe = self.frontendRoot()
+        if transaction:
+            return map(lambda x: int(x.split('/')[-1]), transaction.list(fe))
+        else:
+            return map(int, xstransact.List(fe))
 
 
 ## private:
 
-    def writeDetails(self, config, devid, backDetails, frontDetails):
-        """Write the details in the store to trigger creation of a device.
-        The backend domain ID is taken from the given config, paths for
-        frontend and backend are computed, and these are written to the store
-        appropriately, including references from frontend to backend and vice
-        versa.
+    def addStoreEntries(self, config, devid, backDetails, frontDetails):
+        """Add to backDetails and frontDetails the entries to be written in
+        the store to trigger creation of a device.  The backend domain ID is
+        taken from the given config, paths for frontend and backend are
+        computed, and these are added to the backDetails and frontDetails
+        dictionaries for writing to the store, including references from
+        frontend to backend and vice versa.
+
+        @return A pair of (backpath, frontpath).  backDetails and frontDetails
+        will have been updated appropriately, also.
 
         @param config The configuration of the device, as given to
         {@link #createDevice}.
@@ -298,24 +352,7 @@
             'state' : str(xenbusState['Initialising'])
             })
 
-        log.debug('DevController: writing %s to %s.', str(frontDetails),
-                  frontpath)
-        log.debug('DevController: writing %s to %s.', str(backDetails),
-                  backpath)
-
-        while True:
-            t = xstransact()
-            try:
-                t.remove2(backpath, HOTPLUG_STATUS_NODE)
-
-                t.write2(frontpath, frontDetails)
-                t.write2(backpath,  backDetails)
-
-                if t.commit():
-                    return
-            except:
-                t.abort()
-                raise
+        return (backpath, frontpath)
 
 
     def waitForBackend(self, devid):
@@ -328,7 +365,7 @@
             ev = Event()
             result = { 'status': Timeout }
             
-            xswatch(statusPath, hotplugStatusCallback, statusPath, ev, result)
+            xswatch(statusPath, hotplugStatusCallback, ev, result)
 
             ev.wait(DEVICE_CREATE_TIMEOUT)
             return result['status']
@@ -366,6 +403,8 @@
         if status is not None:
             if status == HOTPLUG_STATUS_ERROR:
                 result['status'] = Error
+            elif status == HOTPLUG_STATUS_BUSY:
+                result['status'] = Busy
             else:
                 result['status'] = Connected
         else:
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/SrvDaemon.py Fri Dec  2 18:52:25 2005
@@ -267,7 +267,7 @@
         try:
             log.info("Xend Daemon started")
 
-            xc = xen.lowlevel.xc.new()
+            xc = xen.lowlevel.xc.xc()
             xinfo = xc.xeninfo()
             log.info("Xend changeset: %s.", xinfo['xen_changeset'])
             del xc
@@ -300,3 +300,25 @@
     except:
         inst = Daemon()
     return inst
+
+
+def main(argv = None):
+    global XEND_DAEMONIZE
+    
+    XEND_DAEMONIZE = 0
+    if argv is None:
+        argv = sys.argv
+
+    try:
+        daemon = instance()
+    
+        r,w = os.pipe()
+        daemon.run(os.fdopen(w, 'w'))
+        return 0
+    except Exception, exn:
+        log.fatal(exn)
+        return 1
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/SrvDomain.py Fri Dec  2 18:52:25 2005
@@ -54,6 +54,10 @@
     def acceptCommand(self, req):
         req.setResponseCode(http.ACCEPTED)
         req.setHeader("Location", "%s/.." % req.prePathURL())
+
+    def op_rename(self, _, req):
+        self.acceptCommand(req)
+        return self.dom.setName(req.args['name'][0])
 
     def op_shutdown(self, _, req):
         self.acceptCommand(req)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/blkif.py     Fri Dec  2 18:52:25 2005
@@ -48,13 +48,11 @@
         devid = blkif.blkdev_name_to_number(dev)
 
         (typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1)
-        back = { 'dev' : dev,
-                 'type' : typ,
-                 'params' : params
+        back = { 'dev'    : dev,
+                 'type'   : typ,
+                 'params' : params,
+                 'mode'   : sxp.child_value(config, 'mode', 'r')
                  }
-
-        if 'r' == sxp.child_value(config, 'mode', 'r'):
-            back['read-only'] = ""  # existence indicates read-only
 
         front = { 'virtual-device' : "%i" % devid }
 
@@ -66,18 +64,16 @@
 
         result = DevController.configuration(self, devid)
 
-        (dev, typ, params, ro) = self.readBackend(devid,
-                                                  'dev', 'type', 'params',
-                                                  'read-only')
+        (dev, typ, params, mode) = self.readBackend(devid,
+                                                    'dev', 'type', 'params',
+                                                    'mode')
 
         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'])
+        if mode:
+            result.append(['mode', mode])
 
         return result
 
@@ -93,8 +89,11 @@
         try:
             DevController.destroyDevice(self, int(devid))
         except ValueError:
+            devid_end = type(devid) is str and devid.split('/')[-1] or None
+
             for i in self.deviceIDs():
-                if self.readBackend(i, 'dev') == devid:
+                d = self.readBackend(i, 'dev')
+                if d == devid or (devid_end and d == devid_end):
                     DevController.destroyDevice(self, i)
                     return
             raise VmError("Device %s not connected" % devid)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/iopif.py
--- a/tools/python/xen/xend/server/iopif.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/iopif.py     Fri Dec  2 18:52:25 2005
@@ -28,7 +28,7 @@
 from xen.xend.server.DevController import DevController
 
 
-xc = xen.lowlevel.xc.new()
+xc = xen.lowlevel.xc.xc()
 
 
 def parse_ioport(val):
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/netif.py     Fri Dec  2 18:52:25 2005
@@ -71,8 +71,8 @@
         script = os.path.join(xroot.network_script_dir,
                               sxp.child_value(config, 'script',
                                               xroot.get_vif_script()))
-        type = sxp.child_value(config, 'type')
-        if type == 'ioemu':
+        typ = sxp.child_value(config, 'type')
+        if typ == 'ioemu':
             return (None,{},{})
         bridge = sxp.child_value(config, 'bridge')
         mac    = sxp.child_value(config, 'mac')
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/pciif.py     Fri Dec  2 18:52:25 2005
@@ -27,7 +27,7 @@
 from xen.xend.server.DevController import DevController
 
 
-xc = xen.lowlevel.xc.new()
+xc = xen.lowlevel.xc.xc()
 
 
 def parse_pci(val):
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/relocate.py
--- a/tools/python/xen/xend/server/relocate.py  Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/relocate.py  Fri Dec  2 18:52:25 2005
@@ -16,30 +16,24 @@
 # Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
-import socket
 import sys
 import StringIO
 
 from xen.web import protocol, tcp, unix
 
-from xen.xend import scheduler
 from xen.xend import sxp
+from xen.xend import XendDomain
+from xen.xend import XendRoot
 from xen.xend.XendError import XendError
-from xen.xend import XendRoot
 from xen.xend.XendLogging import log
 
-
-xroot = XendRoot.instance()
-
-
-DEBUG = 0
 
 class RelocationProtocol(protocol.Protocol):
     """Asynchronous handler for a connected relocation socket.
     """
 
     def __init__(self):
-        #protocol.Protocol.__init__(self)
+        protocol.Protocol.__init__(self)
         self.parser = sxp.Parser()
 
     def dataReceived(self, data):
@@ -59,11 +53,6 @@
     def loseConnection(self):
         if self.transport:
             self.transport.loseConnection()
-        if self.connected:
-            scheduler.now(self.connectionLost)
-
-    def connectionLost(self, reason=None):
-        pass
 
     def send_reply(self, sxpr):
         io = StringIO.StringIO()
@@ -91,7 +80,7 @@
     def opname(self, name):
          return 'op_' + name.replace('.', '_')
 
-    def operror(self, name, req):
+    def operror(self, name, _):
         raise XendError('Invalid operation: ' +name)
 
     def dispatch(self, req):
@@ -100,7 +89,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('_', '.')
@@ -110,50 +99,28 @@
         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_receive(self, name, req):
+    def op_receive(self, name, _):
         if self.transport:
             self.send_reply(["ready", name])
             self.transport.sock.setblocking(1)
-            xd = xroot.get_component("xen.xend.XendDomain")
-            xd.domain_restore_fd(self.transport.sock.fileno())
+            XendDomain.instance().domain_restore_fd(
+                self.transport.sock.fileno())
             self.transport.sock.setblocking(0)
         else:
             log.error(name + ": no transport")
             raise XendError(name + ": no transport")
 
-class RelocationFactory(protocol.ServerFactory):
-    """Asynchronous handler for the relocation server socket.
-    """
-
-    def __init__(self):
-        #protocol.ServerFactory.__init__(self)
-        pass
-
-    def buildProtocol(self, addr):
-        return RelocationProtocol()
 
 def listenRelocation():
-    factory = RelocationFactory()
+    xroot = XendRoot.instance()
     if xroot.get_xend_unix_server():
         path = '/var/lib/xend/relocation-socket'
-        unix.listenUNIX(path, factory)
+        unix.listenUNIX(path, RelocationProtocol)
     if xroot.get_xend_relocation_server():
         port = xroot.get_xend_relocation_port()
         interface = xroot.get_xend_relocation_address()
-        l = tcp.listenTCP(port, factory, interface=interface)
+        l = tcp.listenTCP(port, RelocationProtocol, interface=interface)
         l.setCloExec()
-
-def setupRelocation(dst, port):
-    try:
-        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        sock.connect((dst, port))
-    except socket.error, err:
-        raise XendError("can't connect: %s" % err[1])
-
-    sock.send("receive\n")
-    print sock.recv(80)
-
-    return sock
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/tpmif.py     Fri Dec  2 18:52:25 2005
@@ -38,10 +38,10 @@
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
 
-        devid = int(sxp.child_value(config, 'instance', '0'))
+        devid = int(sxp.child_value(config, 'pref_instance', '0'))
         log.info("The domain has a TPM with instance %d." % devid)
 
-        back  = { 'instance' : "%i" % devid }
+        back  = { 'pref_instance' : "%i" % devid }
         front = { 'handle' : "%i" % devid }
 
         return (devid, back, front)
@@ -50,8 +50,7 @@
 
         result = DevController.configuration(self, devid)
 
-        (instance) = self.readBackend(devif,
-                                      'instance')
+        (instance,) = self.readBackend(devid, 'instance')
 
         if instance:
             result.append(['instance', instance])
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/tests/test_sxp.py
--- a/tools/python/xen/xend/tests/test_sxp.py   Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/tests/test_sxp.py   Fri Dec  2 18:52:25 2005
@@ -6,8 +6,8 @@
 class test_sxp(unittest.TestCase):
 
     def testAllFromString(self):
-        def t(input, expected):
-            self.assertEqual(xen.xend.sxp.all_from_string(input), expected)
+        def t(inp, expected):
+            self.assertEqual(xen.xend.sxp.all_from_string(inp), expected)
 
         t('String',           ['String'])
         t('(String Thing)',   [['String', 'Thing']])
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/tests/test_uuid.py
--- a/tools/python/xen/xend/tests/test_uuid.py  Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/tests/test_uuid.py  Fri Dec  2 18:52:25 2005
@@ -21,9 +21,9 @@
             self.assertEqual(uuid.toString(inp), expected)
             self.assertEqual(uuid.fromString(expected), inp)
 
-        t([0 for i in range(0, 16)], "00000000-0000-0000-0000-000000000000")
+        t([0 for _ in range(0, 16)], "00000000-00000000-00000000-00000000")
         t([185, 158, 125, 206, 250, 178, 125, 57, 2, 6, 162, 74, 178, 236,
-           196, 5], "b99e7dce-fab2-7d39-0206-a24ab2ecc405")
+           196, 5], "b99e7dce-fab27d39-0206a24a-b2ecc405")
 
 
 def test_suite():
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/uuid.py
--- a/tools/python/xen/xend/uuid.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/uuid.py     Fri Dec  2 18:52:25 2005
@@ -25,14 +25,14 @@
 import random
 
 
-def getUuidUuidgen(random = True):
+def getUuidUuidgen(randomly = True):
     """Generate a UUID using the command uuidgen.
 
-    If random is true (default) generates a random uuid.
-    If random is false generates a time-based uuid.
+    If randomly is true (default) generates a random uuid.
+    If randomly is false generates a time-based uuid.
     """
     cmd = "uuidgen"
-    if random:
+    if randomly:
         cmd += " -r"
     else:
         cmd += " -t"
@@ -42,7 +42,7 @@
 def getUuidRandom():
     """Generate a random UUID."""
     
-    return [ random.randint(0, 255) for i in range(0, 16) ]
+    return [ random.randint(0, 255) for _ in range(0, 16) ]
 
 
 #uuidFactory = getUuidUuidgen
@@ -54,8 +54,7 @@
 
 
 def toString(u):
-    f = "%02x"
-    return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(u) )
+    return "-".join(["%02x" * 4] * 4) % tuple(u)
 
 def fromString(s):
     s = s.replace('-', '')
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py      Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py      Fri Dec  2 18:52:25 2005
@@ -198,9 +198,10 @@
             if len(tup) == 2:
                 (key, val) = tup
                 try:
-                    fmt = { str : "%s",
-                            int : "%i",
-                            float : "%f",
+                    fmt = { str        : "%s",
+                            int        : "%i",
+                            float      : "%f",
+                            long       : "%li",
                             type(None) : None }[type(val)]
                 except KeyError:
                     raise TypeError
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/xenstore/xsutil.py
--- a/tools/python/xen/xend/xenstore/xsutil.py  Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/xenstore/xsutil.py  Fri Dec  2 18:52:25 2005
@@ -5,7 +5,7 @@
 # this archive for more details.
 
 import threading
-from xen.lowlevel import xs
+import xen.lowlevel.xs
 
 xs_lock = threading.Lock()
 xs_handle = None
@@ -15,7 +15,7 @@
     if not xs_handle:
         xs_lock.acquire()
         if not xs_handle:
-            xs_handle = xs.open()
+            xs_handle = xen.lowlevel.xs.xs()
         xs_lock.release()
     return xs_handle
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/xenstore/xswatch.py
--- a/tools/python/xen/xend/xenstore/xswatch.py Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/xenstore/xswatch.py Fri Dec  2 18:52:25 2005
@@ -13,6 +13,18 @@
 
 class xswatch:
 
+    ##
+    # Create a watch on the given path in the store.  The watch will fire
+    # immediately, then subsequently each time the watched path is changed,
+    # until the watch is deregistered, either by the return value from the
+    # watch callback being False, or by an explicit call to unwatch.
+    #
+    # @param fn The function to be called when the watch fires.  This function
+    # should take the path that has changed as its first argument, followed by
+    # the extra arguments given to this constructor, if any.  It should return
+    # True if the watch is to remain registered, or False if it is to be
+    # deregistered.
+    #
     def __init__(self, path, fn, *args, **kwargs):
         self.path = path
         self.fn = fn
@@ -51,7 +63,7 @@
         try:
             we = xs.read_watch()
             watch = we[1]
-            res = watch.fn(*watch.args, **watch.kwargs)
+            res = watch.fn(we[0], *watch.args, **watch.kwargs)
             if not res:
                 watch.unwatch()
         except:
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xm/create.py     Fri Dec  2 18:52:25 2005
@@ -220,11 +220,9 @@
           fn=set_bool, default=0,
           use="Make the domain a network interface backend.")
 
-gopts.var('tpmif', val='frontend=DOM',
-          fn=append_value, default=[],
-          use="""Make the domain a TPM interface backend. If frontend is given,
-          the frontend in that domain is connected to this backend (not
-          completely implemented, yet)""")
+gopts.var('tpmif', val='no|yes',
+          fn=append_value, default=0,
+          use="Make the domain a TPM interface backend.")
 
 gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
           fn=append_value, default=[],
@@ -273,9 +271,13 @@
 
 gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
           fn=append_value, default=[],
-          use="""Add a tpm interface. On the backend side us the the given
-          instance as virtual TPM instance. Use the backend in the given
-          domain.""")
+          use="""Add a TPM interface. On the backend side use the given
+          instance as virtual TPM instance. The given number is merely the
+          preferred instance number. The hotplug script will determine
+          which instance number will actually be assigned to the domain.
+          The associtation between virtual machine and the TPM instance
+          number can be found in /etc/xen/vtpm.db. Use the backend in the
+          given domain.""")
 
 gopts.var('nics', val="NUM",
           fn=set_int, default=1,
@@ -465,33 +467,19 @@
             if instance == "VTPMD":
                 instance = "0"
             else:
-                try:
-                    if int(instance) == 0:
-                        err('VM config error: vTPM instance must not be 0.')
-                except ValueError:
-                    err('Vm config error: could not parse instance number.')
+                if instance != None:
+                    try:
+                        if int(instance) == 0:
+                            err('VM config error: vTPM instance must not be 
0.')
+                    except ValueError:
+                        err('Vm config error: could not parse instance 
number.')
             backend = d.get('backend')
             config_vtpm = ['vtpm']
             if instance:
-                config_vtpm.append(['instance', instance])
+                config_vtpm.append(['pref_instance', instance])
             if backend:
                 config_vtpm.append(['backend', backend])
             config_devs.append(['device', config_vtpm])
-
-def configure_tpmif(config_devs, vals):
-    """Create the config for virtual TPM interfaces.
-    """
-    tpmif = vals.tpmif
-    tpmif_n = 1
-    for idx in range(0, tpmif_n):
-        if idx < len(tpmif):
-            d = tpmif[idx]
-            frontend = d.get('frontend')
-            config_tpmif = ['tpmif']
-            if frontend:
-                config_tpmif.append(['frontend', frontend])
-            config_devs.append(['device', config_tpmif])
-
 
 def configure_vifs(config_devs, vals):
     """Create the config for virtual network interfaces.
@@ -685,22 +673,6 @@
         vtpms.append(d)
     vals.vtpm = vtpms
 
-def preprocess_tpmif(vals):
-    if not vals.tpmif: return
-    tpmifs = []
-    for tpmif in vals.tpmif:
-        d = {}
-        a = tpmif.split(',')
-        for b in a:
-            (k, v) = b.strip().split('=', 1)
-            k = k.strip()
-            v = v.strip()
-            if k not in ['frontend']:
-                err('Invalid tpmif specifier: ' + vtpm)
-            d[k] = v
-        tpmifs.append(d)
-    vals.tpmif = tpmifs
-
 def preprocess_ip(vals):
     if vals.ip or vals.dhcp != 'off':
         dummy_nfs_server = '1.2.3.4'
@@ -791,7 +763,6 @@
     preprocess_nfs(vals)
     preprocess_vnc(vals)
     preprocess_vtpm(vals)
-    preprocess_tpmif(vals)
          
 def make_domain(opts, config):
     """Create, build and start a domain.
@@ -827,92 +798,41 @@
     opts.info("Started domain %s" % (dom))
     return int(sxp.child_value(dominfo, 'domid'))
 
-def get_dom0_alloc():
-    """Return current allocation memory of dom0 (in MB). Return 0 on error"""
-    PROC_XEN_BALLOON = "/proc/xen/balloon"
-
-    f = open(PROC_XEN_BALLOON, "r")
-    line = f.readline()
-    for x in line.split():
-        for n in x:
-            if not n.isdigit():
-                break
-        else:
-            f.close()
-            return int(x)/1024
-    f.close()
-    return 0
-
-def balloon_out(dom0_min_mem, opts):
-    """Balloon out memory from dom0 if necessary"""
-    SLACK = 4
-    timeout = 20 # 2s
-    ret = 1
-
-    xc = xen.lowlevel.xc.new()
-    free_mem = xc.physinfo()['free_pages'] / 256
-    domU_need_mem = opts.vals.memory + SLACK 
-
-    # we already have enough free memory, return success
-    if free_mem >= domU_need_mem:
-        del xc
-        return 0
-
-    dom0_cur_alloc = get_dom0_alloc()
-    dom0_new_alloc = dom0_cur_alloc - (domU_need_mem - free_mem)
-    if dom0_new_alloc < dom0_min_mem:
-        dom0_new_alloc = dom0_min_mem
-
-    server.xend_domain_mem_target_set(0, dom0_new_alloc)
-
-    while timeout > 0:
-        time.sleep(0.1) # sleep 100ms
-
-        free_mem = xc.physinfo()['free_pages'] / 256
-        if free_mem >= domU_need_mem:
-            ret = 0
-            break
-        timeout -= 1
-
-    del xc
-    return ret
-
-
 def parseCommandLine(argv):
-    opts = gopts
-    args = opts.parse(argv)
-    if opts.vals.help:
-        opts.usage()
-    if opts.vals.help or opts.vals.help_config:
-        opts.load_defconfig(help=1)
-    if opts.vals.help or opts.vals.help_config:
+    gopts.reset()
+    args = gopts.parse(argv)
+    if gopts.vals.help:
+        gopts.usage()
+    if gopts.vals.help or gopts.vals.help_config:
+        gopts.load_defconfig(help=1)
+    if gopts.vals.help or gopts.vals.help_config:
         return (None, None)
 
-    if not opts.vals.display:
-        opts.vals.display = os.getenv("DISPLAY")
+    if not gopts.vals.display:
+        gopts.vals.display = os.getenv("DISPLAY")
 
     # Process remaining args as config variables.
     for arg in args:
         if '=' in arg:
             (var, val) = arg.strip().split('=', 1)
             gopts.setvar(var.strip(), val.strip())
-    if opts.vals.config:
-        config = opts.vals.config
+    if gopts.vals.config:
+        config = gopts.vals.config
     else:
-        opts.load_defconfig()
-        preprocess(opts.vals)
-        if not opts.getopt('name') and opts.getopt('defconfig'):
-            opts.setopt('name', os.path.basename(opts.getopt('defconfig')))
-        config = make_config(opts.vals)
-
-    if type(config) == str:
-        config = sxp.parse(file(config))[0]
-
-    return (opts, config)
+        gopts.load_defconfig()
+        preprocess(gopts.vals)
+        if not gopts.getopt('name') and gopts.getopt('defconfig'):
+            gopts.setopt('name', os.path.basename(gopts.getopt('defconfig')))
+        config = make_config(gopts.vals)
+
+    return (gopts, config)
 
 
 def main(argv):
-    (opts, config) = parseCommandLine(argv)
+    try:
+        (opts, config) = parseCommandLine(argv)
+    except StandardError, ex:
+        err(str(ex))
 
     if not opts:
         return
@@ -920,16 +840,6 @@
     if opts.vals.dryrun:
         PrettyPrint.prettyprint(config)
     else:
-        from xen.xend import XendRoot
-
-        xroot = XendRoot.instance()
-
-        dom0_min_mem = xroot.get_dom0_min_mem()
-        if dom0_min_mem != 0:
-            if balloon_out(dom0_min_mem, opts):
-                print >>sys.stderr, "error: cannot allocate enough memory for 
domain"
-                sys.exit(1)
-
         dom = make_domain(opts, config)
         if opts.vals.console_autoconnect:
             console.execConsole(dom)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xm/help.py
--- a/tools/python/xen/xm/help.py       Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xm/help.py       Fri Dec  2 18:52:25 2005
@@ -87,7 +87,10 @@
         """Execute the check and set the variable to the new value.
         """
         if not self.check: return
-        env[self.name] = self.check(self.name, env.get(self.name))
+        try: 
+            env[self.name] = self.check(self.name, env.get(self.name))
+        except StandardError, ex:
+            raise sys.exc_type, self.name + " - " + str(ex)
 
     def doHelp(self, out):
         """Print help for the variable.
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xm/main.py       Fri Dec  2 18:52:25 2005
@@ -24,9 +24,8 @@
 import os
 import os.path
 import sys
-import commands
 import re
-from getopt import getopt
+import getopt
 import socket
 import warnings
 warnings.filterwarnings('ignore', category=FutureWarning)
@@ -39,6 +38,14 @@
 from xen.xm.opts import *
 
 import console
+
+
+# getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
+# getopt.getopt if gnu_getopt is not available.  This will mean that options
+# may only be specified before positional arguments.
+if not hasattr(getopt, 'gnu_getopt'):
+    getopt.gnu_getopt = getopt.getopt
+
 
 # Strings for shorthelp
 console_help = "console <DomId>                  Attach to domain DomId's 
console."
@@ -71,7 +78,8 @@
 vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs>   Set which cpus a VCPU can 
use" 
 dmesg_help =   "dmesg [--clear]                  Read or clear Xen's message 
buffer"
 info_help =    "info                             Get information about the xen 
host"
-log_help = "log      Print the xend log"
+rename_help =  "rename <DomId> <New Name>        Rename a domain"
+log_help =     "log                              Print the xend log"
 sched_bvt_help = """sched-bvt <Parameters>           Set Borrowed Virtual Time 
scheduler
                                     parameters"""
 sched_bvt_ctxallow_help = """sched-bvt-ctxallow <Allow>       Set the BVT 
scheduler context switch
@@ -96,25 +104,88 @@
 vnet_delete_help = "vnet-delete <vnetid>             delete a vnet"
 
 
+short_command_list = [
+    "console",
+    "create",
+    "destroy",
+    "help",
+    "list",
+    "mem-max",
+    "mem-set",
+    "migrate",
+    "pause",
+    "reboot",
+    "restore",
+    "save",
+    "shutdown",
+    "top",
+    "unpause",
+    ]
+
+domain_commands = [
+    "console",
+    "create",
+    "destroy",
+    "domid",
+    "domname",
+    "list",
+    "mem-max",
+    "mem-set",
+    "migrate",
+    "pause",
+    "reboot",
+    "rename",
+    "restore",
+    "save",
+    "shutdown",
+    "sysrq",
+    "top",
+    "unpause",
+    "set-vcpus",
+    "vcpu-pin",
+    ]
+
+host_commands = [
+    "dmesg",
+    "info",
+    "log",
+    "top",
+    ]
+
+scheduler_commands = [
+    "sched-bvt",
+    "sched-bvt-ctxallow",
+    "sched-sedf",
+    ]
+
+device_commands = [
+    "block-attach",
+    "block-detach",
+    "block-list",
+    "network-attach",
+    "network-detach",
+    "network-list",
+    ]
+
+vnet_commands = [
+    "vnet-list",
+    "vnet-create",
+    "vnet-delete",
+    ]
+
+all_commands = (domain_commands + host_commands + scheduler_commands +
+                device_commands + vnet_commands)
+
+
+def commandToHelp(cmd):
+    return eval(cmd.replace("-", "_") + "_help")
+
+
 shorthelp = """Usage: xm <subcommand> [args]
     Control, list, and manipulate Xen guest instances
 
-xm common subcommands:"""  + help_spacer \
-+ console_help + help_spacer \
-+ create_help + help_spacer \
-+ destroy_help + help_spacer \
-+ help_help    + help_spacer \
-+ list_help    + help_spacer \
-+ mem_max_help + help_spacer \
-+ mem_set_help + help_spacer \
-+ migrate_help + help_spacer \
-+ pause_help   + help_spacer \
-+ reboot_help  + help_spacer \
-+ restore_help + help_spacer \
-+ save_help    + help_spacer \
-+ shutdown_help + help_spacer \
-+ top_help     + help_spacer \
-+ unpause_help + """
+xm common subcommands:
+   """  + help_spacer.join(map(commandToHelp, short_command_list))  + """
 
 <DomName> can be substituted for <DomId> in xm subcommands.
 
@@ -127,50 +198,20 @@
 
 xm full list of subcommands:
 
-  Domain Commands: """ + help_spacer \
-+ console_help + help_spacer \
-+ create_help + help_spacer \
-+ destroy_help + help_spacer \
-+ domid_help   + help_spacer \
-+ domname_help   + help_spacer \
-+ list_help    + help_spacer \
-+ mem_max_help + help_spacer \
-+ mem_set_help + help_spacer \
-+ migrate_help + help_spacer \
-+ pause_help   + help_spacer \
-+ reboot_help  + help_spacer \
-+ restore_help + help_spacer \
-+ save_help    + help_spacer \
-+ shutdown_help + help_spacer \
-+ sysrq_help + help_spacer \
-+ top_help     + help_spacer \
-+ unpause_help + help_spacer \
-+ set_vcpus_help + help_spacer \
-+ vcpu_pin_help + """
-
-   Xen Host Commands: """ + help_spacer \
-+ dmesg_help + help_spacer \
-+ info_help + help_spacer \
-+ log_help  + help_spacer \
-+ top_help  + """
-
-  Scheduler Commands: """ + help_spacer \
-+ sched_bvt_help + help_spacer \
-+ sched_bvt_ctxallow_help + help_spacer \
-+ sched_sedf_help + """
-
-  Virtual Device Commands:"""  + help_spacer \
-+ block_attach_help + help_spacer \
-+ block_detach_help + help_spacer \
-+ block_list_help + help_spacer \
-+ network_attach_help + help_spacer \
-+ network_detach_help + help_spacer \
-+ network_list_help + """
-
-  Vnet commands: """ + help_spacer \
-+ vnet_list_help + help_spacer \
-+ vnet_create_help + help_spacer \
-+ vnet_delete_help + """
+  Domain Commands:
+   """ + help_spacer.join(map(commandToHelp,  domain_commands)) + """
+
+  Xen Host Commands:
+   """ + help_spacer.join(map(commandToHelp,  host_commands)) + """
+
+  Scheduler Commands:
+   """ + help_spacer.join(map(commandToHelp,  scheduler_commands)) + """
+
+  Virtual Device Commands:
+   """  + help_spacer.join(map(commandToHelp, device_commands)) + """
+
+  Vnet commands:
+   """ + help_spacer.join(map(commandToHelp,  vnet_commands)) + """
 
 <DomName> can be substituted for <DomId> in xm subcommands.
 
@@ -180,48 +221,14 @@
 
 # array for xm help <command>
 help = {
-    "--long": longhelp,
-    "console": console_help,
-    "create": create_help,
-    "destroy": destroy_help,
-    "domid ": domid_help,
-    "domname": domname_help,
-    "list": list_help,
-    "mem-max": mem_max_help,
-    "mem-set": mem_set_help,
-    "migrate": migrate_help,
-    "pause": pause_help,
-    "reboot": reboot_help,
-    "restore": restore_help,
-    "save":  save_help,
-    "shutdown": shutdown_help,
-    "sysrq": sysrq_help,
-    "unpause": unpause_help,
-    "set-vcpus": set_vcpus_help,
-    "vcpu-list": vcpu_list_help,
-    "vcpu-pin": vcpu_pin_help,
-#  Xen Host Commands:
-    "dmesg": dmesg_help,
-    "info":  info_help,
-    "log":   log_help,
-    "top":  top_help,
-#  Scheduler Commands:
-    "sched-bvt": sched_bvt_help,
-    "sched-bvt-ctxallow": sched_bvt_ctxallow_help,
-    "sched-sedf":  sched_sedf_help,
-
-#  Virtual Device Commands:
-    "block-attach": block_attach_help,
-    "block-detach": block_detach_help,
-    "block-list": block_list_help,
-    "network-attach": network_attach_help,
-    "network-detach": network_detach_help,
-    "network-list":  network_list_help,
-# Vnet commands:
-    "vnet-list": vnet_list_help,
-    "vnet-create": vnet_create_help,
-    "vnet-delete": vnet_delete_help
-   }
+    "--long": longhelp
+    }
+
+for command in all_commands:
+    # create is handled specially
+    if (command != 'create'):
+        help[command] = commandToHelp(command)
+
 
 ####################################################################
 #
@@ -229,10 +236,20 @@
 #
 ####################################################################
 
-def arg_check(args,num,name):
-    if len(args) < num:
-        err("'xm %s' requires %s argument(s)!\n" % (name, num))
-        usage(name)
+def arg_check(args, name, lo, hi = -1):
+    n = len(args)
+    
+    if hi == -1:
+        if n != lo:
+            err("'xm %s' requires %d argument%s.\n" % (name, lo,
+                                                       lo > 1 and 's' or ''))
+            usage(name)
+    else:
+        if n < lo or n > hi:
+            err("'xm %s' requires between %d and %d arguments.\n" %
+                (name, lo, hi))
+            usage(name)
+
 
 def unit(c):
     if not c.isalpha():
@@ -262,14 +279,17 @@
 def err(msg):
     print >>sys.stderr, "Error:", msg
 
-def handle_xend_error(cmd, dom, ex):
+def handle_xend_error(cmd, args, ex):
+    non_option = filter(lambda x: x[0] != '-', args)
+    dom = len(non_option) > 0 and non_option[0] or None
+
     error = str(ex)
     if error == "Not found" and dom != None:
         err("Domain '%s' not found when running 'xm %s'" % (dom, cmd))
-        sys.exit(1)
     else:
         err(error)
-        sys.exit(1)
+
+    sys.exit(1)
     
 
 #########################################################################
@@ -279,7 +299,7 @@
 #########################################################################
 
 def xm_save(args):
-    arg_check(args,2,"save")
+    arg_check(args, "save", 2)
 
     dom = args[0] # TODO: should check if this exists
     savefile = os.path.abspath(args[1])
@@ -292,7 +312,7 @@
     server.xend_domain_save(dom, savefile)
     
 def xm_restore(args):
-    arg_check(args,1,"restore")
+    arg_check(args, "restore", 1)
 
     savefile = os.path.abspath(args[0])
 
@@ -320,8 +340,8 @@
     use_long = 0
     show_vcpus = 0
     try:
-        (options, params) = getopt(args, 'lv', ['long','vcpus'])
-    except GetoptError, opterr:
+        (options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus'])
+    except getopt.GetoptError, opterr:
         err(opterr)
         sys.exit(1)
     
@@ -482,29 +502,33 @@
 
 
 def xm_reboot(args):
-    arg_check(args,1,"reboot")
+    arg_check(args, "reboot", 1, 4)
     from xen.xm import shutdown
-    # ugly hack because the opt parser apparently wants
-    # the subcommand name just to throw it away!
-    shutdown.main(["bogus", "-R"] + args)
+    shutdown.main(["shutdown", "-R"] + args)
 
 def xm_pause(args):
-    arg_check(args, 1, "pause")
+    arg_check(args, "pause", 1)
     dom = args[0]
 
     from xen.xend.XendClient import server
     server.xend_domain_pause(dom)
 
 def xm_unpause(args):
-    arg_check(args, 1, "unpause")
+    arg_check(args, "unpause", 1)
     dom = args[0]
 
     from xen.xend.XendClient import server
     server.xend_domain_unpause(dom)
+
+def xm_rename(args):
+    arg_check(args, "rename", 2)
+
+    from xen.xend.XendClient import server
+    server.xend_domain_rename(args[0], args[1])
 
 def xm_subcommand(command, args):
     cmd = __import__(command, globals(), locals(), 'xen.xm')
-    cmd.main(["bogus"] + args)
+    cmd.main([command] + args)
 
 
 #############################################################
@@ -522,7 +546,7 @@
     return cpus
 
 def xm_vcpu_pin(args):
-    arg_check(args, 3, "vcpu-pin")
+    arg_check(args, "vcpu-pin", 3)
 
     dom  = args[0]
     vcpu = int(args[1])
@@ -532,7 +556,7 @@
     server.xend_domain_pincpu(dom, vcpu, cpumap)
 
 def xm_mem_max(args):
-    arg_check(args, 2, "mem-max")
+    arg_check(args, "mem-max", 2)
 
     dom = args[0]
     mem = int_unit(args[1], 'm')
@@ -541,7 +565,7 @@
     server.xend_domain_maxmem_set(dom, mem)
     
 def xm_mem_set(args):
-    arg_check(args, 2, "mem-set")
+    arg_check(args, "mem-set", 2)
 
     dom = args[0]
     mem_target = int_unit(args[1], 'm')
@@ -550,13 +574,13 @@
     server.xend_domain_mem_target_set(dom, mem_target)
     
 def xm_set_vcpus(args):
-    arg_check(args, 2, "set-vcpus")
+    arg_check(args, "set-vcpus", 2)
     
     from xen.xend.XendClient import server
     server.xend_domain_set_vcpus(args[0], int(args[1]))
 
 def xm_domid(args):
-    arg_check(args, 1, "domid")
+    arg_check(args, "domid", 1)
 
     name = args[0]
 
@@ -565,7 +589,7 @@
     print sxp.child_value(dom, 'domid')
     
 def xm_domname(args):
-    arg_check(args, 1, "domname")
+    arg_check(args, "domname", 1)
 
     name = args[0]
 
@@ -574,21 +598,21 @@
     print sxp.child_value(dom, 'name')
 
 def xm_sched_bvt(args):
-    arg_check(args, 6, "sched-bvt")
+    arg_check(args, "sched-bvt", 6)
     dom = args[0]
     v = map(long, args[1:6])
     from xen.xend.XendClient import server
     server.xend_domain_cpu_bvt_set(dom, *v)
 
 def xm_sched_bvt_ctxallow(args):
-    arg_check(args, 1, "sched-bvt-ctxallow")
+    arg_check(args, "sched-bvt-ctxallow", 1)
 
     slice = int(args[0])
     from xen.xend.XendClient import server
     server.xend_node_cpu_bvt_slice_set(slice)
 
 def xm_sched_sedf(args):
-    arg_check(args, 6, "sched-sedf")
+    arg_check(args, "sched-sedf", 6)
     
     dom = args[0]
     v = map(int, args[1:6])
@@ -605,9 +629,8 @@
         else: 
             print "%-23s:" % x[0], x[1]
 
-# TODO: remove as soon as console server shows up
 def xm_console(args):
-    arg_check(args,1,"console")
+    arg_check(args, "console", 1)
 
     dom = args[0]
     from xen.xend.XendClient import server
@@ -632,7 +655,7 @@
               use="Clear the contents of the Xen message buffer.")
     # Work around for gopts
     myargs = args
-    myargs.insert(0, "bogus")
+    myargs.insert(0, 'dmesg')
     gopts.parse(myargs)
     if not (1 <= len(myargs) <= 2):
         err('Invalid arguments: ' + str(myargs))
@@ -644,11 +667,13 @@
         server.xend_node_clear_dmesg()
 
 def xm_log(args):
+    arg_check(args, 'xm-log', 0)
+    
     from xen.xend.XendClient import server
     print server.xend_node_log()
 
 def xm_network_list(args):
-    arg_check(args,1,"network-list")
+    arg_check(args, "network-list", 1)
     dom = args[0]
     from xen.xend.XendClient import server
     for x in server.xend_domain_devices(dom, 'vif'):
@@ -656,7 +681,7 @@
         print
 
 def xm_block_list(args):
-    arg_check(args,1,"block-list")
+    arg_check(args, "block-list", 1)
     dom = args[0]
     from xen.xend.XendClient import server
     for x in server.xend_domain_devices(dom, 'vbd'):
@@ -664,20 +689,14 @@
         print
 
 def xm_block_attach(args):
-    n = len(args)
-    if n == 0:
-        usage("block-attach")
-        
-    if n < 4 or n > 5:
-        err("%s: Invalid argument(s)" % args[0])
-        usage("block-attach")
+    arg_check(args, 'block-attach', 4, 5)
 
     dom = args[0]
     vbd = ['vbd',
            ['uname', args[1]],
            ['dev',   args[2]],
            ['mode',  args[3]]]
-    if n == 5:
+    if len(args) == 5:
         vbd.append(['backend', args[4]])
 
     from xen.xend.XendClient import server
@@ -685,10 +704,8 @@
 
 
 def xm_network_attach(args):
-    n = len(args)
-    if n == 0:
-        usage("network-attach")
-        
+    arg_check(args, 'network-attach', 1, 10000)
+
     dom = args[0]
     vif = ['vif']
 
@@ -700,7 +717,7 @@
 
 
 def detach(args, command, deviceClass):
-    arg_check(args, 2, command)
+    arg_check(args, command, 2)
 
     dom = args[0]
     dev = args[1]
@@ -720,8 +737,8 @@
 def xm_vnet_list(args):
     from xen.xend.XendClient import server
     try:
-        (options, params) = getopt(args, 'l', ['long'])
-    except GetoptError, opterr:
+        (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
+    except getopt.GetoptError, opterr:
         err(opterr)
         sys.exit(1)
     
@@ -747,7 +764,7 @@
             print vnet, ex
 
 def xm_vnet_create(args):
-    arg_check(args, 1, "vnet-create")
+    arg_check(args, "vnet-create", 1)
     conf = args[0]
     if not os.access(conf, os.R_OK):
         print "File not found: %s" % conf
@@ -757,7 +774,7 @@
     server.xend_vnet_create(conf)
 
 def xm_vnet_delete(args):
-    arg_check(args, 1, "vnet-delete")
+    arg_check(args, "vnet-delete", 1)
     vnet = args[0]
     from xen.xend.XendClient import server
     server.xend_vnet_delete(vnet)
@@ -770,6 +787,7 @@
     # domain commands
     "domid": xm_domid,
     "domname": xm_domname,
+    "rename": xm_rename,
     "restore": xm_restore,
     "save": xm_save,
     "reboot": xm_reboot,
@@ -846,6 +864,10 @@
     err('Option %s is the new replacement, see "xm help %s" for more info' % 
(new, new))
 
 def usage(cmd=None):
+    if cmd == 'create':
+        mycmd = xm_lookup_cmd(cmd)
+        mycmd( ['--help'] )
+        sys.exit(1)
     if help.has_key(cmd):
         print "   " + help[cmd]
     else:
@@ -889,7 +911,7 @@
             sys.exit(1)
         except xen.xend.XendError.XendError, ex:
             if len(args) > 0:
-                handle_xend_error(argv[1], args[0], ex)
+                handle_xend_error(argv[1], args, ex)
             else:
                 print "Unexpected error:", sys.exc_info()[0]
                 print
@@ -897,7 +919,7 @@
                 raise
         except xen.xend.XendProtocol.XendError, ex:
             if len(args) > 0:
-                handle_xend_error(argv[1], args[0], ex)
+                handle_xend_error(argv[1], args, ex)
             else:
                 print "Unexpected error:", sys.exc_info()[0]
                 print
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xm/opts.py
--- a/tools/python/xen/xm/opts.py       Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xm/opts.py       Fri Dec  2 18:52:25 2005
@@ -13,11 +13,12 @@
 # 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.
 #============================================================================
 
 """Object-oriented command-line option support.
 """
-from getopt import getopt, GetoptError
+import getopt
 import os
 import os.path
 import sys
@@ -60,6 +61,14 @@
         self.value = None
         self.set(default)
 
+
+    def reset(self):
+        self.specified_opt = None
+        self.specified_val = None
+        self.value = None
+        self.set(self.default)
+
+
     def __repr__(self):
         return self.name + '=' + str(self.specified_val)
 
@@ -223,6 +232,14 @@
         # Option to use for bare words.
         self.default_opt = None
 
+
+    def reset(self):
+        self.vals = OptVals()
+        self.vars = {}
+        for opt in self.options:
+            opt.reset()
+
+
     def __repr__(self):
         return '\n'.join(map(str, self.options))
 
@@ -317,9 +334,10 @@
         while args:
             # let getopt parse whatever it feels like -- if anything
             try:
-                (xvals, args) = getopt(args[0:],
-                                       self.short_opts(), self.long_opts())
-            except GetoptError, err:
+                (xvals, args) = getopt.getopt(args[0:],
+                                              self.short_opts(),
+                                              self.long_opts())
+            except getopt.GetoptError, err:
                 self.err(str(err))
                 
             for (k, v) in xvals:
@@ -416,22 +434,22 @@
         are used to set options with the same names.
         Variables are not used to set options that are already specified.
         """
-        # Create global and lobal dicts for the file.
+        # Create global and local dicts for the file.
         # Initialize locals to the vars.
         # Use exec to do the standard imports and
         # define variables we are passing to the script.
-        globals = {}
-        locals = {}
-        locals.update(self.vars)
+        globs = {}
+        locs = {}
+        locs.update(self.vars)
         cmd = '\n'.join(self.imports + 
                         [ "from xen.xm.help import Vars",
                           "xm_file = '%s'" % defconfig,
                           "xm_help = %d" % help,
                           "xm_vars = Vars(xm_file, xm_help, locals())"
                           ])
-        exec cmd in globals, locals
+        exec cmd in globs, locs
         try:
-            execfile(defconfig, globals, locals)
+            execfile(defconfig, globs, locs)
         except:
             if not help: raise
         if help:
@@ -444,7 +462,7 @@
                    types.IntType,
                    types.FloatType
                    ]
-        for (k, v) in locals.items():
+        for (k, v) in locs.items():
             if self.specified(k): continue
             if not(type(v) in vtypes): continue
             self.setopt(k, v)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xm/tests/test_create.py
--- a/tools/python/xen/xm/tests/test_create.py  Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xm/tests/test_create.py  Fri Dec  2 18:52:25 2005
@@ -34,31 +34,79 @@
 
     def testCommandLine(self):
         (fd, fname) = tempfile.mkstemp()
+        os.close(fd)
+        self.t('-f %s kernel=/mykernel display=fakedisplay '
+               'macaddr=ab:cd:ef:ed nics=0' % fname,
+               { 'name'      : os.path.basename(fname),
+                 'xm_file'   : fname,
+                 'defconfig' : fname,
+                 'kernel'    : '/mykernel',
+                 'display'   : 'fakedisplay',
+                 'macaddr'   : 'ab:cd:ef:ed',
+                 'memory'    : 128,
+                 'vcpus'     : 1,
+                 'boot'      : 'c',
+                 'dhcp'      : 'off',
+                 'interface' : 'eth0',
+                 'path'      : '.:/etc/xen',
+                 'builder'   : 'linux',
+                 })
+
+
+    def testConfigFile(self):
+        (fd, fname) = tempfile.mkstemp()
         try:
-            self.t('-f %s kernel=/mykernel display=fakedisplay '
-                   'macaddr=ab:cd:ef:ed nics=0' % fname,
-                   { 'name'      : os.path.basename(fname),
-                     'xm_file'   : fname,
-                     'defconfig' : fname,
-                     'kernel'    : '/mykernel',
-                     'display'   : 'fakedisplay',
-                     'macaddr'   : 'ab:cd:ef:ed',
-                     'memory'    : 128,
-                     'vcpus'     : 1,
-                     'boot'      : 'c',
-                     'dhcp'      : 'off',
-                     'interface' : 'eth0',
-                     'path'      : '.:/etc/xen',
-                     'builder'   : 'linux',
-                     })
+            os.write(fd,
+                     '''
+kernel = "/boot/vmlinuz-xenU-smp"
+memory = 768
+name = "dom1"
+vcpus = 4
+nics = 1
+disk = ['phy:/dev/virt-blkdev-backend/dom1,sda1,w',
+'phy:/dev/virt-blkdev-backend/usr,sda2,r']
+root = "/dev/sda1 ro"
+extra = " profile=1 GATEWAY=10.0.1.254 NETMASK=255.255.0.0 IPADDR=10.0.134.1 
HOSTNAME=dom1"
+on_poweroff = 'destroy'
+on_reboot   = 'destroy'
+on_crash    = 'destroy'
+                     ''')
         finally:
             os.close(fd)
+
+        self.t('-f %s display=fakedisplay' % fname,
+               { 'kernel'      : '/boot/vmlinuz-xenU-smp',
+                 'memory'      : 768,
+                 'name'        : 'dom1',
+                 'vcpus'       : 4,
+                 'nics'        : 1,
+                 'root'        : '/dev/sda1 ro',
+                 'extra'       : ' profile=1 GATEWAY=10.0.1.254 
NETMASK=255.255.0.0 IPADDR=10.0.134.1 HOSTNAME=dom1',
+                 'on_poweroff' : 'destroy',
+                 'on_reboot'   : 'destroy',
+                 'on_crash'    : 'destroy',
+                 'disk'        : [['phy:/dev/virt-blkdev-backend/dom1',
+                                   'sda1', 'w', None],
+                                  ['phy:/dev/virt-blkdev-backend/usr',
+                                   'sda2', 'r', None]],
+
+                 'xm_file'     : fname,
+                 'defconfig'   : fname,
+                 'display'     : 'fakedisplay',
+
+                 'boot'        : 'c',
+                 'dhcp'        : 'off',
+                 'interface'   : 'eth0',
+                 'path'        : '.:/etc/xen',
+                 'builder'     : 'linux',
+               })
 
 
     def testConfigFileAndCommandLine(self):
         (fd, fname) = tempfile.mkstemp()
-        os.write(fd,
-                 '''
+        try:
+            os.write(fd,
+                     '''
 name       = "testname"
 memory     = 256
 ssidref    = 1
@@ -66,30 +114,30 @@
 maxmem     = 1024
 cpu        = 2
 cpu_weight = 0.75
-                 ''')
-        try:
-            self.t('-f %s display=fakedisplay macaddr=ab:cd:ef:ed nics=0' %
-              fname,
-                   { 'name'       : 'testname',
-                     'xm_file'    : fname,
-                     'defconfig'  : fname,
-                     'kernel'     : '/mykernel',
-                     'display'    : 'fakedisplay',
-                     'macaddr'    : 'ab:cd:ef:ed',
-                     'memory'     : 256,
-                     'maxmem'     : 1024,
-                     'cpu'        : 2,
-                     'ssidref'    : 1,
-                     'cpu_weight' : 0.75,
-                     'vcpus'      : 1,
-                     'boot'       : 'c',
-                     'dhcp'       : 'off',
-                     'interface'  : 'eth0',
-                     'path'       : '.:/etc/xen',
-                     'builder'    : 'linux',
-                     })
+                     ''')
         finally:
             os.close(fd)
+
+        self.t('-f %s display=fakedisplay macaddr=ab:cd:ef:ed nics=0' %
+          fname,
+               { 'name'       : 'testname',
+                 'xm_file'    : fname,
+                 'defconfig'  : fname,
+                 'kernel'     : '/mykernel',
+                 'display'    : 'fakedisplay',
+                 'macaddr'    : 'ab:cd:ef:ed',
+                 'memory'     : 256,
+                 'maxmem'     : 1024,
+                 'cpu'        : 2,
+                 'ssidref'    : 1,
+                 'cpu_weight' : 0.75,
+                 'vcpus'      : 1,
+                 'boot'       : 'c',
+                 'dhcp'       : 'off',
+                 'interface'  : 'eth0',
+                 'path'       : '.:/etc/xen',
+                 'builder'    : 'linux',
+                 })
             
 
 def test_suite():
diff -r eae5812f33f1 -r 28bd01c9b596 tools/security/Makefile
--- a/tools/security/Makefile   Fri Dec  2 18:12:11 2005
+++ b/tools/security/Makefile   Fri Dec  2 18:52:25 2005
@@ -12,21 +12,21 @@
 XML2VERSION = $(shell xml2-config --version )
 VALIDATE_SCHEMA=$(shell if [[ $(XML2VERSION) < 2.6.20 ]]; then echo ""; else 
echo "-DVALIDATE_SCHEMA"; fi; )
 
-ifeq ($(ACM_USE_SECURITY_POLICY),ACM_NULL_POLICY)
+ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_NULL_POLICY)
 POLICY=null
 endif
-ifeq ($(ACM_USE_SECURITY_POLICY),ACM_CHINESE_WALL_POLICY)
+ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_CHINESE_WALL_POLICY)
 POLICY=chwall
 endif
-ifeq ($(ACM_USE_SECURITY_POLICY),ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+ifeq ($(ACM_DEFAULT_SECURITY_POLICY),ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
 POLICY=ste
 endif
-ifeq 
($(ACM_USE_SECURITY_POLICY),ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+ifeq 
($(ACM_DEFAULT_SECURITY_POLICY),ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)
 POLICY=chwall_ste
 endif
 POLICYFILE=./policies/$(POLICY)/$(POLICY).bin
 
-ifneq ($(ACM_USE_SECURITY_POLICY), ACM_NULL_POLICY)
+ifeq ($(ACM_SECURITY),y)
 all: build
 
 install:all
@@ -55,7 +55,7 @@
        $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_XML2BIN) $(VALIDATE_SCHEMA) -o $@ 
$<
 
 clean:
-       rm -rf secpol_tool secpol_xml2bin xen
+       rm -rf secpol_tool secpol_xml2bin xen get_decision
 
 policy_clean:
        rm -rf policies/*/*.bin policies/*/*.map
@@ -69,14 +69,3 @@
 boot_install: $(POLICYFILE)
        @cp $(POLICYFILE) /boot
        @./updategrub.sh $(POLICY) $(PWD)/$(XEN_ROOT)
-
-LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
-mk-symlinks:
-       [ -e xen/linux ] || mkdir -p xen/linux
-       [ -e xen/io ]    || mkdir -p xen/io
-       ( cd xen >/dev/null ; \
-         ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
-       ( cd xen/io >/dev/null ; \
-         ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
-       ( cd xen/linux >/dev/null ; \
-         ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
diff -r eae5812f33f1 -r 28bd01c9b596 tools/security/install.txt
--- a/tools/security/install.txt        Fri Dec  2 18:12:11 2005
+++ b/tools/security/install.txt        Fri Dec  2 18:52:25 2005
@@ -24,11 +24,13 @@
        # cd "xen_root"
        # edit/xemacs/vi Config.mk
 
-       change the line:
-       ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLICY
+       change the lines:
+       ACM_SECURITY ?= n
+       ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_POLICY
 
        to:
-       ACM_USE_SECURITY_POLICY ?= 
ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
+       ACM_SECURITY ?= y
+       ACM_DEFAULT_SECURITY_POLICY ?= 
ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
 
        # make all
        # ./install.sh
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/crypto/Makefile
--- a/tools/vtpm_manager/crypto/Makefile        Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/crypto/Makefile        Fri Dec  2 18:52:25 2005
@@ -1,19 +1,19 @@
-XEN_ROOT = ../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
-
-BIN            = libtcpaCrypto.a
-
-all: build
-
-build: $(BIN)
-
-install: build
-
-clean:
-       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
-
-mrproper: clean
-       rm -f *~
-
-$(BIN): $(OBJS)
-       $(AR) rcs $(BIN) $(OBJS)
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIN            = libtcpaCrypto.a
+
+all: build
+
+build: $(BIN)
+
+install: build
+
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+mrproper: clean
+       rm -f *~
+
+$(BIN): $(OBJS)
+       $(AR) rcs $(BIN) $(OBJS)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/manager/Makefile
--- a/tools/vtpm_manager/manager/Makefile       Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/manager/Makefile       Fri Dec  2 18:52:25 2005
@@ -1,27 +1,27 @@
-XEN_ROOT = ../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
-
-BIN            = vtpm_managerd
-
-all: build
-
-build: $(BIN)
-
-install: build
-       if [ ! -d "$(DESTDIR)/var/vtpm/fifos" ]; \
-               then mkdir -p $(DESTDIR)/var/vtpm/fifos; \
-       fi
-       $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
-
-clean:
-       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
-
-mrproper: clean
-       rm -f $(BIN) *~
-
-$(BIN): $(OBJS)
-       $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
-
-# libraries
-LIBS += ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.a
-LIBS += -lcrypto -lpthread -lrt -lm
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIN            = vtpm_managerd
+
+all: build
+
+build: $(BIN)
+
+install: build
+       if [ ! -d "$(DESTDIR)/var/vtpm/fifos" ]; \
+               then mkdir -p $(DESTDIR)/var/vtpm/fifos; \
+       fi
+       $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
+
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+mrproper: clean
+       rm -f $(BIN) *~
+
+$(BIN): $(OBJS)
+       $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+
+# libraries
+LIBS += ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.a
+LIBS += -lcrypto -lpthread -lrt -lm
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/manager/tpmpassthrough.c
--- a/tools/vtpm_manager/manager/tpmpassthrough.c       Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/manager/tpmpassthrough.c       Fri Dec  2 18:52:25 2005
@@ -1,110 +1,110 @@
-// ===================================================================
-// 
-// Copyright (c) 2005, Intel Corp.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions 
-// are met:
-//
-//   * Redistributions of source code must retain the above copyright 
-//     notice, this list of conditions and the following disclaimer.
-//   * 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.
-//   * Neither the name of Intel Corporation nor the names of its 
-//     contributors may be used to endorse or promote products derived
-//     from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-// ===================================================================
-// 
-// tpmpassthrough.c
-// 
-//  Functions regarding passing DMI requests to HWTPM
-//
-// ==================================================================
-
-#include "tcg.h"
-#include "vtpm_manager.h"
-#include "vtpmpriv.h"
-#include "vtsp.h"
-#include "log.h"
-
-TPM_RESULT VTPM_Handle_TPM_Command( VTPM_DMI_RESOURCE *dmi,
-                                   buffer_t *inbuf,  
-                                   buffer_t *outbuf) {
-  
-  TPM_RESULT status = TPM_SUCCESS;
-  TPM_COMMAND_CODE *ord;               
-  
-  ord = (TPM_COMMAND_CODE *) (inbuf->bytes + sizeof(TPM_TAG) + sizeof(UINT32));
-  
-  switch (*ord) {
-    
-    // Forbidden for DMI use
-  case TPM_ORD_TakeOwnership:
-  case TPM_ORD_ChangeAuthOwner:
-  case TPM_ORD_DirWriteAuth:
-  case TPM_ORD_DirRead:
-  case TPM_ORD_AuthorizeMigrationKey:
-  case TPM_ORD_CreateMaintenanceArchive:
-  case TPM_ORD_LoadMaintenanceArchive:
-  case TPM_ORD_KillMaintenanceFeature:
-  case TPM_ORD_LoadManuMaintPub:
-  case TPM_ORD_ReadManuMaintPub:
-  case TPM_ORD_SelfTestFull:
-  case TPM_ORD_SelfTestStartup:
-  case TPM_ORD_CertifySelfTest:
-  case TPM_ORD_ContinueSelfTest:
-  case TPM_ORD_GetTestResult:
-  case TPM_ORD_Reset:
-  case TPM_ORD_OwnerClear:
-  case TPM_ORD_DisableOwnerClear:
-  case TPM_ORD_ForceClear:
-  case TPM_ORD_DisableForceClear:
-  case TPM_ORD_GetCapabilityOwner:
-  case TPM_ORD_OwnerSetDisable:
-  case TPM_ORD_PhysicalEnable:
-  case TPM_ORD_PhysicalDisable:
-  case TPM_ORD_SetOwnerInstall:
-  case TPM_ORD_PhysicalSetDeactivated:
-  case TPM_ORD_SetTempDeactivated:
-  case TPM_ORD_CreateEndorsementKeyPair:
-  case TPM_ORD_GetAuditEvent:
-  case TPM_ORD_GetAuditEventSigned:
-  case TPM_ORD_GetOrdinalAuditStatus:
-  case TPM_ORD_SetOrdinalAuditStatus:
-  case TPM_ORD_SetRedirection:
-  case TPM_ORD_FieldUpgrade:
-  case TSC_ORD_PhysicalPresence:
-    status = TPM_DISABLED_CMD;
-    goto abort_egress;
-    break;
-    
-  } // End ORD Switch
-  
-  // Call TCS with command
-  
-  TPMTRY(TPM_IOERROR, VTSP_RawTransmit( dmi->TCSContext,inbuf, outbuf) );
-  
-  goto egress;
-  
- abort_egress:
-  vtpmloginfo(VTPM_LOG_VTPM, "TPM Command Failed in tpmpassthrough.\n");
- egress:
-  
-  return status;
-}
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * 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.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// tpmpassthrough.c
+// 
+//  Functions regarding passing DMI requests to HWTPM
+//
+// ==================================================================
+
+#include "tcg.h"
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "vtsp.h"
+#include "log.h"
+
+TPM_RESULT VTPM_Handle_TPM_Command( VTPM_DMI_RESOURCE *dmi,
+                                   buffer_t *inbuf,  
+                                   buffer_t *outbuf) {
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE *ord;               
+  
+  ord = (TPM_COMMAND_CODE *) (inbuf->bytes + sizeof(TPM_TAG) + sizeof(UINT32));
+  
+  switch (*ord) {
+    
+    // Forbidden for DMI use
+  case TPM_ORD_TakeOwnership:
+  case TPM_ORD_ChangeAuthOwner:
+  case TPM_ORD_DirWriteAuth:
+  case TPM_ORD_DirRead:
+  case TPM_ORD_AuthorizeMigrationKey:
+  case TPM_ORD_CreateMaintenanceArchive:
+  case TPM_ORD_LoadMaintenanceArchive:
+  case TPM_ORD_KillMaintenanceFeature:
+  case TPM_ORD_LoadManuMaintPub:
+  case TPM_ORD_ReadManuMaintPub:
+  case TPM_ORD_SelfTestFull:
+  case TPM_ORD_SelfTestStartup:
+  case TPM_ORD_CertifySelfTest:
+  case TPM_ORD_ContinueSelfTest:
+  case TPM_ORD_GetTestResult:
+  case TPM_ORD_Reset:
+  case TPM_ORD_OwnerClear:
+  case TPM_ORD_DisableOwnerClear:
+  case TPM_ORD_ForceClear:
+  case TPM_ORD_DisableForceClear:
+  case TPM_ORD_GetCapabilityOwner:
+  case TPM_ORD_OwnerSetDisable:
+  case TPM_ORD_PhysicalEnable:
+  case TPM_ORD_PhysicalDisable:
+  case TPM_ORD_SetOwnerInstall:
+  case TPM_ORD_PhysicalSetDeactivated:
+  case TPM_ORD_SetTempDeactivated:
+  case TPM_ORD_CreateEndorsementKeyPair:
+  case TPM_ORD_GetAuditEvent:
+  case TPM_ORD_GetAuditEventSigned:
+  case TPM_ORD_GetOrdinalAuditStatus:
+  case TPM_ORD_SetOrdinalAuditStatus:
+  case TPM_ORD_SetRedirection:
+  case TPM_ORD_FieldUpgrade:
+  case TSC_ORD_PhysicalPresence:
+    status = TPM_DISABLED_CMD;
+    goto abort_egress;
+    break;
+    
+  } // End ORD Switch
+  
+  // Call TCS with command
+  
+  TPMTRY(TPM_IOERROR, VTSP_RawTransmit( dmi->TCSContext,inbuf, outbuf) );
+  
+  goto egress;
+  
+ abort_egress:
+  vtpmloginfo(VTPM_LOG_VTPM, "TPM Command Failed in tpmpassthrough.\n");
+ egress:
+  
+  return status;
+}
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Fri Dec  2 18:52:25 2005
@@ -1,137 +1,137 @@
-// ===================================================================
-// 
-// Copyright (c) 2005, Intel Corp.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions 
-// are met:
-//
-//   * Redistributions of source code must retain the above copyright 
-//     notice, this list of conditions and the following disclaimer.
-//   * 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.
-//   * Neither the name of Intel Corporation nor the names of its 
-//     contributors may be used to endorse or promote products derived
-//     from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-// ===================================================================
-// 
-// vtpm_manager.h
-// 
-//  Public Interface header for VTPM Manager
-//
-// ==================================================================
-
-#ifndef __VTPM_MANAGER_H__
-#define __VTPM_MANAGER_H__
-
-#include "tcg.h"
-
-#define VTPM_TAG_REQ 0x01c1
-#define VTPM_TAG_RSP 0x01c4
-#define COMMAND_BUFFER_SIZE 4096
-
-// Header sizes. Note Header MAY include the DMI
-#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
-#define VTPM_COMMAND_HEADER_SIZE_CLT (                  sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
-
-// ********************** Public Functions *************************
-TPM_RESULT VTPM_Init_Service(); // Start VTPM Service
-void VTPM_Stop_Service();  // Stop VTPM Service
-#ifdef VTPM_MULTI_VM
-int VTPM_Service_Handler();
-#else
-void *VTPM_Service_Handler(void *threadTypePtr);
-#endif
-
-//************************ Command Codes ****************************
-#define VTPM_ORD_OPEN              1   // ULM Creates New DMI
-#define VTPM_ORD_CLOSE             2   // ULM Closes a DMI
-#define VTPM_ORD_DELETE            3   // ULM Permemently Deletes DMI
-#define VTPM_ORD_SAVENVM          4   // DMI requests Secrets Unseal
-#define VTPM_ORD_LOADNVM          5   // DMI requests Secrets Saved
-#define VTPM_ORD_TPMCOMMAND       6   // DMI issues HW TPM Command
-
-//************************ Return Codes ****************************
-#define VTPM_SUCCESS               0
-#define VTPM_FAIL                  1
-#define VTPM_UNSUPPORTED           2
-#define VTPM_FORBIDDEN             3
-#define VTPM_RESTORE_CONTEXT_FAILED    4
-#define VTPM_INVALID_REQUEST       5
-
-/******************* Command Parameter API *************************
-
-VTPM Command Format
-  dmi: 4 bytes                  // Source of message. 
-                                // WARNING: This is prepended by the channel. 
-                                // Thus it is received by VTPM Manager, 
-                                // but not sent by DMI
-  tpm tag: 2 bytes
-  command size: 4 bytes         // Size of command including header but not DMI
-  ord: 4 bytes                  // Command ordinal above
-  parameters: size - 10 bytes   // Command Parameter
-
-VTPM Response Format
-  tpm tag: 2 bytes
-  response_size: 4 bytes
-  status: 4 bytes         
-  parameters: size - 10 bytes
-
-
-VTPM_Open:
-  Input Parameters:
-    Domain_type: 1 byte
-    domain_id: 4 bytes
-    instance_id: 4 bytes
-  Output Parameters:
-    None
-    
-VTPM_Close
-  Input Parameters:
-    instance_id: 4 bytes
-  Output Parameters:
-    None
-
-VTPM_Delete
-  Input Parameters:
-    instance_id: 4 bytes
-  Output Parameters:
-    None
-
-VTPM_SaveNVM
-  Input Parameters:
-    data: n bytes (Header indicates size of data)
-  Output Parameters:
-    None
-
-VTPM_LoadNVM
-  Input Parameters:
-    None
-  Output Parameters:
-    data: n bytes (Header indicates size of data)
-
-VTPM_TPMCommand
-  Input Parameters:
-    TPM Command Byte Stream: n bytes 
-  Output Parameters:
-    TPM Reponse Byte Stream: n bytes 
-
-*********************************************************************/
-
-#endif //_VTPM_MANAGER_H_
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * 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.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpm_manager.h
+// 
+//  Public Interface header for VTPM Manager
+//
+// ==================================================================
+
+#ifndef __VTPM_MANAGER_H__
+#define __VTPM_MANAGER_H__
+
+#include "tcg.h"
+
+#define VTPM_TAG_REQ 0x01c1
+#define VTPM_TAG_RSP 0x01c4
+#define COMMAND_BUFFER_SIZE 4096
+
+// Header sizes. Note Header MAY include the DMI
+#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
+#define VTPM_COMMAND_HEADER_SIZE_CLT (                  sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
+
+// ********************** Public Functions *************************
+TPM_RESULT VTPM_Init_Service(); // Start VTPM Service
+void VTPM_Stop_Service();  // Stop VTPM Service
+#ifdef VTPM_MULTI_VM
+int VTPM_Service_Handler();
+#else
+void *VTPM_Service_Handler(void *threadTypePtr);
+#endif
+
+//************************ Command Codes ****************************
+#define VTPM_ORD_OPEN              1   // ULM Creates New DMI
+#define VTPM_ORD_CLOSE             2   // ULM Closes a DMI
+#define VTPM_ORD_DELETE            3   // ULM Permemently Deletes DMI
+#define VTPM_ORD_SAVENVM          4   // DMI requests Secrets Unseal
+#define VTPM_ORD_LOADNVM          5   // DMI requests Secrets Saved
+#define VTPM_ORD_TPMCOMMAND       6   // DMI issues HW TPM Command
+
+//************************ Return Codes ****************************
+#define VTPM_SUCCESS               0
+#define VTPM_FAIL                  1
+#define VTPM_UNSUPPORTED           2
+#define VTPM_FORBIDDEN             3
+#define VTPM_RESTORE_CONTEXT_FAILED    4
+#define VTPM_INVALID_REQUEST       5
+
+/******************* Command Parameter API *************************
+
+VTPM Command Format
+  dmi: 4 bytes                  // Source of message. 
+                                // WARNING: This is prepended by the channel. 
+                                // Thus it is received by VTPM Manager, 
+                                // but not sent by DMI
+  tpm tag: 2 bytes
+  command size: 4 bytes         // Size of command including header but not DMI
+  ord: 4 bytes                  // Command ordinal above
+  parameters: size - 10 bytes   // Command Parameter
+
+VTPM Response Format
+  tpm tag: 2 bytes
+  response_size: 4 bytes
+  status: 4 bytes         
+  parameters: size - 10 bytes
+
+
+VTPM_Open:
+  Input Parameters:
+    Domain_type: 1 byte
+    domain_id: 4 bytes
+    instance_id: 4 bytes
+  Output Parameters:
+    None
+    
+VTPM_Close
+  Input Parameters:
+    instance_id: 4 bytes
+  Output Parameters:
+    None
+
+VTPM_Delete
+  Input Parameters:
+    instance_id: 4 bytes
+  Output Parameters:
+    None
+
+VTPM_SaveNVM
+  Input Parameters:
+    data: n bytes (Header indicates size of data)
+  Output Parameters:
+    None
+
+VTPM_LoadNVM
+  Input Parameters:
+    None
+  Output Parameters:
+    data: n bytes (Header indicates size of data)
+
+VTPM_TPMCommand
+  Input Parameters:
+    TPM Command Byte Stream: n bytes 
+  Output Parameters:
+    TPM Reponse Byte Stream: n bytes 
+
+*********************************************************************/
+
+#endif //_VTPM_MANAGER_H_
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c        Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/manager/vtpmd.c        Fri Dec  2 18:52:25 2005
@@ -1,134 +1,134 @@
-// ===================================================================
-// 
-// Copyright (c) 2005, Intel Corp.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions 
-// are met:
-//
-//   * Redistributions of source code must retain the above copyright 
-//     notice, this list of conditions and the following disclaimer.
-//   * 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.
-//   * Neither the name of Intel Corporation nor the names of its 
-//     contributors may be used to endorse or promote products derived
-//     from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-// ===================================================================
-// 
-// vtpmd.c
-// 
-//  Application
-//
-// ===================================================================
-
-#include <stdio.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "vtpm_manager.h"
-#include "vtpmpriv.h"
-#include "tcg.h"
-#include "log.h"
-
-#ifndef VTPM_MULTI_VM
- #include <pthread.h>
-#endif
-
-void signal_handler(int reason) {
-#ifndef VTPM_MULTI_VM
-
-  if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) {
-    if (reason >= 0) { // Reason is a signal
-      vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal 
%d.\n", reason);
-    } else  {// Reason is a TPM_RESULT * -1
-      vtpmloginfo(VTPM_LOG_VTPM,"VTPM Manager shuting down for: %s\n", 
tpm_get_error_name(-1 * reason) );
-    }
-    
-    return;
-  } else {
-    vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n");
-    pthread_exit(NULL);
-  }
-#else
-  VTPM_Stop_Service();
-  exit(-1);
-#endif
-}
-
-struct sigaction ctl_c_handler;
-
-int main(int argc, char **argv) {
-
-  vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n");
-  
-  if (VTPM_Init_Service() != TPM_SUCCESS) {
-    vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during 
startup.\n");
-    return -1;
-  }
-  
-  ctl_c_handler.sa_handler = signal_handler;
-  sigemptyset(&ctl_c_handler.sa_mask);
-  ctl_c_handler.sa_flags = 0;    
-  
-  if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1) 
-    vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break 
will not stop service gently.\n");
-  
-  // For easier debuggin with gdb
-  if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) 
-    vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break 
will not stop service gently.\n");    
-  
-#ifdef VTPM_MULTI_VM
-  TPM_RESULT status = VTPM_Service_Handler();
-    
-  if (status != TPM_SUCCESS) 
-    vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager exited with status %s. It never 
should exit.\n", tpm_get_error_name(status));
-  
-  return -1;
-#else
-  sigset_t sig_mask;
-      
-  sigemptyset(&sig_mask);
-  sigaddset(&sig_mask, SIGPIPE);
-  sigprocmask(SIG_BLOCK, &sig_mask, NULL);
-  //pthread_mutex_init(&vtpm_globals->dmi_mutex, NULL);
-  pthread_t be_thread, dmi_thread;
-  int betype_be, dmitype_dmi;
-  
-  vtpm_globals->master_pid = pthread_self();
-  
-  betype_be = BE_LISTENER_THREAD;
-  if (pthread_create(&be_thread, NULL, VTPM_Service_Handler, &betype_be) != 0) 
{
-    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n");
-    exit(-1);
-  }
-  
-  dmitype_dmi = DMI_LISTENER_THREAD;
-  if (pthread_create(&dmi_thread, NULL, VTPM_Service_Handler, &dmitype_dmi) != 
0) {
-    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n");
-    exit(-1);
-  }
-  
-  //Join the other threads until exit time.
-  pthread_join(be_thread, NULL);
-  pthread_join(dmi_thread, NULL);
-  
-  VTPM_Stop_Service();
-  return 0;
-#endif
-}
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * 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.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpmd.c
+// 
+//  Application
+//
+// ===================================================================
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "tcg.h"
+#include "log.h"
+
+#ifndef VTPM_MULTI_VM
+ #include <pthread.h>
+#endif
+
+void signal_handler(int reason) {
+#ifndef VTPM_MULTI_VM
+
+  if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) {
+    if (reason >= 0) { // Reason is a signal
+      vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal 
%d.\n", reason);
+    } else  {// Reason is a TPM_RESULT * -1
+      vtpmloginfo(VTPM_LOG_VTPM,"VTPM Manager shuting down for: %s\n", 
tpm_get_error_name(-1 * reason) );
+    }
+    
+    return;
+  } else {
+    vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n");
+    pthread_exit(NULL);
+  }
+#else
+  VTPM_Stop_Service();
+  exit(-1);
+#endif
+}
+
+struct sigaction ctl_c_handler;
+
+int main(int argc, char **argv) {
+
+  vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n");
+  
+  if (VTPM_Init_Service() != TPM_SUCCESS) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during 
startup.\n");
+    return -1;
+  }
+  
+  ctl_c_handler.sa_handler = signal_handler;
+  sigemptyset(&ctl_c_handler.sa_mask);
+  ctl_c_handler.sa_flags = 0;    
+  
+  if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1) 
+    vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break 
will not stop service gently.\n");
+  
+  // For easier debuggin with gdb
+  if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) 
+    vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break 
will not stop service gently.\n");    
+  
+#ifdef VTPM_MULTI_VM
+  TPM_RESULT status = VTPM_Service_Handler();
+    
+  if (status != TPM_SUCCESS) 
+    vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager exited with status %s. It never 
should exit.\n", tpm_get_error_name(status));
+  
+  return -1;
+#else
+  sigset_t sig_mask;
+      
+  sigemptyset(&sig_mask);
+  sigaddset(&sig_mask, SIGPIPE);
+  sigprocmask(SIG_BLOCK, &sig_mask, NULL);
+  //pthread_mutex_init(&vtpm_globals->dmi_mutex, NULL);
+  pthread_t be_thread, dmi_thread;
+  int betype_be, dmitype_dmi;
+  
+  vtpm_globals->master_pid = pthread_self();
+  
+  betype_be = BE_LISTENER_THREAD;
+  if (pthread_create(&be_thread, NULL, VTPM_Service_Handler, &betype_be) != 0) 
{
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n");
+    exit(-1);
+  }
+  
+  dmitype_dmi = DMI_LISTENER_THREAD;
+  if (pthread_create(&dmi_thread, NULL, VTPM_Service_Handler, &dmitype_dmi) != 
0) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n");
+    exit(-1);
+  }
+  
+  //Join the other threads until exit time.
+  pthread_join(be_thread, NULL);
+  pthread_join(dmi_thread, NULL);
+  
+  VTPM_Stop_Service();
+  return 0;
+#endif
+}
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h     Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/manager/vtpmpriv.h     Fri Dec  2 18:52:25 2005
@@ -1,151 +1,151 @@
-// ===================================================================
-// 
-// Copyright (c) 2005, Intel Corp.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions 
-// are met:
-//
-//   * Redistributions of source code must retain the above copyright 
-//     notice, this list of conditions and the following disclaimer.
-//   * 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.
-//   * Neither the name of Intel Corporation nor the names of its 
-//     contributors may be used to endorse or promote products derived
-//     from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-// ===================================================================
-// 
-// vtpmpriv.h
-// 
-//  Structures and functions private to the manager
-//
-// ==================================================================
-
-#ifndef __VTPMPRIV_H__
-#define __VTPMPRIV_H__
-
-#include "tcg.h"
-#include "tcs.h"
-#include "buffer.h"
-#include "crypto.h"
-
-#define STATE_FILE    "/var/vtpm/VTPM"
-#define DMI_NVM_FILE  "/var/vtpm/vtpm_dm_%d.data"
-#define VTPM_BE_DEV   "/dev/vtpm0"
-#define VTPM_CTL_DM   0
-
-#ifndef VTPM_MUTLI_VM
- #include <sys/types.h>
- #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
- #define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
-
- #define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-to-%d.fifo"
- #define VTPM_RX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
-
- #define BE_LISTENER_THREAD 1
- #define DMI_LISTENER_THREAD 2
-
- // Seconds until DMI timeout. Timeouts result in DMI being out
- // of sync, which may require a reboot of DMI and guest to recover
- // from. Don't set this to low. Also note that DMI may issue a TPM
- // call so we should expect time to process at DMI + TPM processing.
- #define DMI_TIMEOUT 90 
-#endif
-
-
-// ------------------------ Private Structures -----------------------
-typedef struct VTPM_DMI_RESOURCE_T {
-  // I/O info for Manager to talk to DMI's over FIFOs
-#ifndef VTPM_MUTLI_VM
-  int                   guest_tx_fh;          // open GUEST_TX_FIFO
-  int                   vtpm_tx_fh;           // open VTPM_TX_FIFO
-  char                  *guest_tx_fname;      // open GUEST_TX_FIFO
-  char                  *vtpm_tx_fname;       // open VTPM_TX_FIFO
-  
-  pid_t                 dmi_pid;
-#endif
-  // Non-persistent Information
-  bool                  connected;
-  UINT32                dmi_domain_id;
-  TCS_CONTEXT_HANDLE    TCSContext;     // TCS Handle
-  char                  *NVMLocation;   // NULL term string indicating location
-                                        // of NVM.
-  // Persistent Information about DMI
-  UINT32                dmi_id;
-  TPM_DIGEST            NVM_measurement;  // Equal to the SHA1 of the blob
-  TPM_DIGEST            DMI_measurement;  // Correct measurement of the owning 
DMI
-} VTPM_DMI_RESOURCE;
-
-typedef struct tdVTPM_GLOBALS {
-  // Non-persistent data
-  int                 be_fh;                  // File handle to ipc used to 
communicate with backend
-#ifndef VTPM_MULTI_VM
-  int                 vtpm_rx_fh;
-  int                 guest_rx_fh;
-  
-  pid_t               master_pid;
-#endif
-  struct hashtable    *dmi_map;               // Table of all DMI's known 
indexed by persistent instance #
-#ifndef VTPM_MULTI_VM
-  pthread_mutex_t     dmi_map_mutex;          // 
-#endif
-  TCS_CONTEXT_HANDLE  manager_tcs_handle;     // TCS Handle used by manager
-  TPM_HANDLE          storageKeyHandle;       // Key used by persistent store
-  CRYPTO_INFO         storageKey;             // For software encryption
-  TCS_AUTH            keyAuth;                // OIAP session for storageKey 
-  BOOL                DMI_table_dirty;        // Indicates that a command
-                                              // has updated the DMI table
-
-    
-  // Persistent Data
-  TPM_AUTHDATA        owner_usage_auth;       // OwnerAuth of real TPM
-  TPM_AUTHDATA        srk_usage_auth;         // SRK Auth of real TPM    
-  buffer_t            storageKeyWrap;         // Wrapped copy of storageKey
-
-  TPM_AUTHDATA        storage_key_usage_auth; 
-    
-}VTPM_GLOBALS;
-
-//Global dmi map
-extern VTPM_GLOBALS *vtpm_globals;
-
-// ********************** Command Handler Prototypes ***********************
-TPM_RESULT VTPM_Handle_Load_NVM(       VTPM_DMI_RESOURCE *myDMI, 
-                                        const buffer_t *inbuf, 
-                                        buffer_t *outbuf);
-
-TPM_RESULT VTPM_Handle_Save_NVM(       VTPM_DMI_RESOURCE *myDMI, 
-                                        const buffer_t *inbuf, 
-                                        buffer_t *outbuf);
-
-TPM_RESULT VTPM_Handle_TPM_Command(    VTPM_DMI_RESOURCE *dmi, 
-                                        buffer_t *inbuf, 
-                                        buffer_t *outbuf);
-
-TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf);
-                                
-TPM_RESULT VTPM_Handle_Close_DMI(const buffer_t *param_buf);
-                                   
-TPM_RESULT VTPM_Handle_Delete_DMI(const buffer_t *param_buf);
-
-TPM_RESULT VTPM_SaveService(void);
-TPM_RESULT VTPM_LoadService(void);
-
-TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res);
-#endif // __VTPMPRIV_H__
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * 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.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpmpriv.h
+// 
+//  Structures and functions private to the manager
+//
+// ==================================================================
+
+#ifndef __VTPMPRIV_H__
+#define __VTPMPRIV_H__
+
+#include "tcg.h"
+#include "tcs.h"
+#include "buffer.h"
+#include "crypto.h"
+
+#define STATE_FILE    "/var/vtpm/VTPM"
+#define DMI_NVM_FILE  "/var/vtpm/vtpm_dm_%d.data"
+#define VTPM_BE_DEV   "/dev/vtpm0"
+#define VTPM_CTL_DM   0
+
+#ifndef VTPM_MUTLI_VM
+ #include <sys/types.h>
+ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
+ #define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
+
+ #define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-to-%d.fifo"
+ #define VTPM_RX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
+
+ #define BE_LISTENER_THREAD 1
+ #define DMI_LISTENER_THREAD 2
+
+ // Seconds until DMI timeout. Timeouts result in DMI being out
+ // of sync, which may require a reboot of DMI and guest to recover
+ // from. Don't set this to low. Also note that DMI may issue a TPM
+ // call so we should expect time to process at DMI + TPM processing.
+ #define DMI_TIMEOUT 90 
+#endif
+
+
+// ------------------------ Private Structures -----------------------
+typedef struct VTPM_DMI_RESOURCE_T {
+  // I/O info for Manager to talk to DMI's over FIFOs
+#ifndef VTPM_MUTLI_VM
+  int                   guest_tx_fh;          // open GUEST_TX_FIFO
+  int                   vtpm_tx_fh;           // open VTPM_TX_FIFO
+  char                  *guest_tx_fname;      // open GUEST_TX_FIFO
+  char                  *vtpm_tx_fname;       // open VTPM_TX_FIFO
+  
+  pid_t                 dmi_pid;
+#endif
+  // Non-persistent Information
+  bool                  connected;
+  UINT32                dmi_domain_id;
+  TCS_CONTEXT_HANDLE    TCSContext;     // TCS Handle
+  char                  *NVMLocation;   // NULL term string indicating location
+                                        // of NVM.
+  // Persistent Information about DMI
+  UINT32                dmi_id;
+  TPM_DIGEST            NVM_measurement;  // Equal to the SHA1 of the blob
+  TPM_DIGEST            DMI_measurement;  // Correct measurement of the owning 
DMI
+} VTPM_DMI_RESOURCE;
+
+typedef struct tdVTPM_GLOBALS {
+  // Non-persistent data
+  int                 be_fh;                  // File handle to ipc used to 
communicate with backend
+#ifndef VTPM_MULTI_VM
+  int                 vtpm_rx_fh;
+  int                 guest_rx_fh;
+  
+  pid_t               master_pid;
+#endif
+  struct hashtable    *dmi_map;               // Table of all DMI's known 
indexed by persistent instance #
+#ifndef VTPM_MULTI_VM
+  pthread_mutex_t     dmi_map_mutex;          // 
+#endif
+  TCS_CONTEXT_HANDLE  manager_tcs_handle;     // TCS Handle used by manager
+  TPM_HANDLE          storageKeyHandle;       // Key used by persistent store
+  CRYPTO_INFO         storageKey;             // For software encryption
+  TCS_AUTH            keyAuth;                // OIAP session for storageKey 
+  BOOL                DMI_table_dirty;        // Indicates that a command
+                                              // has updated the DMI table
+
+    
+  // Persistent Data
+  TPM_AUTHDATA        owner_usage_auth;       // OwnerAuth of real TPM
+  TPM_AUTHDATA        srk_usage_auth;         // SRK Auth of real TPM    
+  buffer_t            storageKeyWrap;         // Wrapped copy of storageKey
+
+  TPM_AUTHDATA        storage_key_usage_auth; 
+    
+}VTPM_GLOBALS;
+
+//Global dmi map
+extern VTPM_GLOBALS *vtpm_globals;
+
+// ********************** Command Handler Prototypes ***********************
+TPM_RESULT VTPM_Handle_Load_NVM(       VTPM_DMI_RESOURCE *myDMI, 
+                                        const buffer_t *inbuf, 
+                                        buffer_t *outbuf);
+
+TPM_RESULT VTPM_Handle_Save_NVM(       VTPM_DMI_RESOURCE *myDMI, 
+                                        const buffer_t *inbuf, 
+                                        buffer_t *outbuf);
+
+TPM_RESULT VTPM_Handle_TPM_Command(    VTPM_DMI_RESOURCE *dmi, 
+                                        buffer_t *inbuf, 
+                                        buffer_t *outbuf);
+
+TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf);
+                                
+TPM_RESULT VTPM_Handle_Close_DMI(const buffer_t *param_buf);
+                                   
+TPM_RESULT VTPM_Handle_Delete_DMI(const buffer_t *param_buf);
+
+TPM_RESULT VTPM_SaveService(void);
+TPM_RESULT VTPM_LoadService(void);
+
+TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res);
+#endif // __VTPMPRIV_H__
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/manager/vtsp.c Fri Dec  2 18:52:25 2005
@@ -1,810 +1,810 @@
-// ===================================================================
-// 
-// Copyright (c) 2005, Intel Corp.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions 
-// are met:
-//
-//   * Redistributions of source code must retain the above copyright 
-//     notice, this list of conditions and the following disclaimer.
-//   * 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.
-//   * Neither the name of Intel Corporation nor the names of its 
-//     contributors may be used to endorse or promote products derived
-//     from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-// ===================================================================
-// 
-// vtsp.c
-// 
-//  Higher level interface to TCS for use in service.
-//
-// ==================================================================
-
-#include <string.h>
-#include "tcg.h"
-#include "tcs.h"
-#include "bsg.h"
-#include "log.h"
-#include "crypto.h"
-#include "vtsp.h"
-#include "buffer.h"
-
-#define  RSA_KEY_SIZE 0x0800
-
-/***********************************************************************************
- * GenerateAuth: Generate authorization info to be sent back to application
- *
- * Parameters: outParamDigestText  The concatenation of output parameters to 
be SHA1ed
- *    outParamDigestTextSize Size of inParamDigestText
- *    HMACkey     Key to be used for HMACing
- *          For OIAP use key.authUsage or PersistStore.ownerAuth
- *          For OSAP use shared secret
- *    pAuth     Authorization information from the application
- *
- * Return:  TPM_SUCCESS   Authorization data created
- *    TPM_AUTHFAIL   Invalid (NULL) HMACkey presented for OSAP
- 
*************************************************************************************/
-TPM_RESULT GenerateAuth( /*[IN]*/ const BYTE *inParamDigestText,
-                        /*[IN]*/ UINT32 inParamDigestTextSize,
-                        /*[IN]*/ const TPM_SECRET *HMACkey,  
-                        /*[IN,OUT]*/ TCS_AUTH *auth) {
-    
-  if (inParamDigestText == NULL || auth == NULL) 
-    return (TPM_AUTHFAIL);
-  else {
-    
-    //Generate new OddNonce
-    Crypto_GetRandom(auth->NonceOdd.nonce, sizeof(TPM_NONCE));
-    
-    // Create SHA1 inParamDigest
-    TPM_DIGEST inParamDigest;
-    Crypto_SHA1Full(inParamDigestText, inParamDigestTextSize, (BYTE *) 
&inParamDigest);
-    
-    // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
-    BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
-    
-    BSG_PackList(   hmacText, 4, 
-                   BSG_TPM_DIGEST, &inParamDigest,
-                   BSG_TPM_NONCE, &(auth->NonceEven),
-                   BSG_TPM_NONCE, &(auth->NonceOdd), 
-                   BSG_TYPE_BOOL, &(auth->fContinueAuthSession) );
-    
-    Crypto_HMAC((BYTE *) hmacText, sizeof(hmacText), (BYTE *) HMACkey, 
sizeof(TPM_DIGEST), (BYTE *) &(auth->HMAC));
-    
-    return(TPM_SUCCESS);
-    
-  }
-}
-
-/***********************************************************************************
- * VerifyAuth: Verify the authdata for a command requiring authorization
- *
- * Parameters: inParamDigestText  The concatenation of parameters to be SHA1ed
- *    inParamDigestTextSize Size of inParamDigestText
- *    authDataUsage   AuthDataUsage for the Entity being used
- *          Key->authDataUsage or TPM_AUTH_OWNER
- *    HMACkey     Key to be used for HMACing
- *          For OIAP use key.authUsage or PersistStore.ownerAuth
- *          For OSAP use NULL (It will be aquired from the Auth Session)
- *          If unknown (default), assume OIAP
- *    sessionAuth    A TCS_AUTH info for the session
- *    pAuth     Authorization information from the application
- *              hContext        If specified, on failed Auth, VerifyAuth will
- *                                      generate a new OIAP session in place 
of themselves
- *                                      destroyed session.
- *
- * Return:  TPM_SUCCESS   Authorization Verified
- *    TPM_AUTHFAIL   Authorization Failed
- *    TPM_FAIL    Failure during SHA1 routines
- 
*************************************************************************************/
-TPM_RESULT VerifyAuth( /*[IN]*/ const BYTE *outParamDigestText,
-                      /*[IN]*/ UINT32 outParamDigestTextSize,
-                      /*[IN]*/ const TPM_SECRET *HMACkey,  
-                      /*[IN,OUT]*/ TCS_AUTH *auth,
-                      /*[IN]*/  TCS_CONTEXT_HANDLE hContext) {
-  if (outParamDigestText == NULL || auth == NULL) 
-    return (TPM_AUTHFAIL);
-  
-  
-  // Create SHA1 inParamDigest
-  TPM_DIGEST outParamDigest;
-  Crypto_SHA1Full(outParamDigestText, outParamDigestTextSize, (BYTE *) 
&outParamDigest);
-  
-  // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
-  TPM_DIGEST hm;
-  BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
-  
-  BSG_PackList(   hmacText, 4, 
-                 BSG_TPM_DIGEST, &outParamDigest,
-                 BSG_TPM_NONCE, &(auth->NonceEven),
-                 BSG_TPM_NONCE, &(auth->NonceOdd), 
-                 BSG_TYPE_BOOL, &(auth->fContinueAuthSession) );
-  
-  Crypto_HMAC((BYTE *) hmacText, sizeof(hmacText),
-             (BYTE *) HMACkey, sizeof(TPM_DIGEST), (BYTE *) &hm);
-    
-  // Compare correct HMAC with provided one.
-  if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0)  // 0 indicates 
equality
-    return (TPM_SUCCESS);
-  else {
-    VTSP_OIAP( hContext, auth);
-    return (TPM_AUTHFAIL);
-  }
-}
-
-TPM_RESULT VTSP_OIAP(const TCS_CONTEXT_HANDLE hContext,
-                    TCS_AUTH *auth) {
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "OIAP.\n");
-  TPM_RESULT status = TPM_SUCCESS;                           
-  TPMTRYRETURN( TCSP_OIAP(hContext,
-                         &auth->AuthHandle,
-                         &auth->NonceEven) );
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  return status;
-}
-
-TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_HANDLE hContext,
-                    const TPM_ENTITY_TYPE entityType,
-                    const UINT32 entityValue,
-                    const TPM_AUTHDATA *usageAuth,
-                    TPM_SECRET *sharedSecret, 
-                    TCS_AUTH *auth) {
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "OSAP.\n");
-  TPM_RESULT status = TPM_SUCCESS;
-  TPM_NONCE nonceEvenOSAP, nonceOddOSAP;
-  
-  Crypto_GetRandom((BYTE *) &nonceOddOSAP, sizeof(TPM_NONCE) ); 
-  
-  TPMTRYRETURN( TCSP_OSAP(    hContext,
-                             entityType,
-                             entityValue, 
-                             nonceOddOSAP,
-                             &auth->AuthHandle, 
-                             &auth->NonceEven, 
-                             &nonceEvenOSAP) );
-  
-  // Calculating Session Secret
-  BYTE sharedSecretText[TPM_DIGEST_SIZE * 2];
-  
-  BSG_PackList(  sharedSecretText, 2,
-                BSG_TPM_NONCE, &nonceEvenOSAP,
-                BSG_TPM_NONCE, &nonceOddOSAP);
-  
-  Crypto_HMAC(sharedSecretText, sizeof(sharedSecretText), (BYTE *) usageAuth, 
TPM_DIGEST_SIZE, (BYTE *) sharedSecret);       
-    
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  return status;
-}
-
-
-
-TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
-                             CRYPTO_INFO *crypto_info) {
-  
-  TPM_RESULT status;
-  TPM_NONCE antiReplay;
-  TPM_DIGEST   checksum;
-  BYTE *pubEKtext;
-  UINT32 pubEKtextsize;
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Reading Public EK.\n");
-  
-  // GenerateAuth new nonceOdd    
-  Crypto_GetRandom(&antiReplay, sizeof(TPM_NONCE) );
-  
-  
-  TPMTRYRETURN( TCSP_ReadPubek(  hContext,
-                                antiReplay,
-                                &pubEKtextsize,
-                                &pubEKtext,
-                                &checksum) );
-  
-  
-  // Extract the remaining output parameters
-  TPM_PUBKEY pubEK;
-  
-  BSG_Unpack(BSG_TPM_PUBKEY, pubEKtext, (BYTE *) &pubEK);
-  
-  // Build CryptoInfo for the bindingKey
-  TPM_RSA_KEY_PARMS rsaKeyParms;
-  
-  BSG_Unpack(BSG_TPM_RSA_KEY_PARMS, 
-            pubEK.algorithmParms.parms, 
-            &rsaKeyParms);
-  
-  Crypto_RSABuildCryptoInfoPublic(rsaKeyParms.exponentSize, 
-                                 rsaKeyParms.exponent, 
-                                 pubEK.pubKey.keyLength, 
-                                 pubEK.pubKey.key, 
-                                 crypto_info);
-    
-  // Destroy rsaKeyParms
-  BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
-
-  // Set encryption scheme
-  crypto_info->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
-  //crypto_info->encScheme = pubEK.algorithmParms.encScheme;
-  crypto_info->algorithmID = pubEK.algorithmParms.algorithmID;
-  
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  return status;
-}
-
-TPM_RESULT VTSP_TakeOwnership(   const TCS_CONTEXT_HANDLE hContext,
-                                 const TPM_AUTHDATA *ownerAuth, 
-                                 const TPM_AUTHDATA *srkAuth,
-                                 CRYPTO_INFO *ek_cryptoInfo,
-                                 TCS_AUTH *auth) {
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Taking Ownership of TPM.\n");
-  
-  TPM_RESULT status = TPM_SUCCESS;
-  TPM_COMMAND_CODE command = TPM_ORD_TakeOwnership;
-  TPM_PROTOCOL_ID proto_id = TPM_PID_OWNER;
-  BYTE *new_srk;
-  
-  BYTE *paramText;        // Digest to make Auth.
-  UINT32 paramTextSize;
-  
-  // vars for srkpubkey parameter
-  TPM_KEY srkPub;
-  TPM_KEY_PARMS srkKeyInfo = {TPM_ALG_RSA, TPM_ES_RSAESOAEP_SHA1_MGF1, 
TPM_SS_NONE, 12, 0};
-  BYTE srkRSAkeyInfo[12] = { 0x00, 0x00, (RSA_KEY_SIZE >> 8), 0x00,   0x00, 
0x00, 0x00, 0x02,   0x00, 0x00, 0x00, 0x00};
-  srkKeyInfo.parms = (BYTE *) &srkRSAkeyInfo;
-  
-  struct pack_buf_t srkText;
-  
-  // GenerateAuth new nonceOdd    
-  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
-  
-  //These values are accurate for an enc(AuthData).
-  struct pack_buf_t encOwnerAuth, encSrkAuth;
-  
-  encOwnerAuth.data = (BYTE *)malloc(sizeof(BYTE) * 256);
-  encSrkAuth.data = (BYTE *)malloc(sizeof(BYTE) * 256);
-  
-  if (encOwnerAuth.data == NULL || encSrkAuth.data == NULL) {
-    vtpmloginfo(VTPM_LOG_VTSP, "Could not malloc encrypted auths.\n");
-    status = TPM_RESOURCES;
-    goto abort_egress;
-  }
-  
-  Crypto_RSAEnc(ek_cryptoInfo, sizeof(TPM_SECRET), (BYTE *) ownerAuth, 
&encOwnerAuth.size, encOwnerAuth.data);
-  Crypto_RSAEnc(ek_cryptoInfo, sizeof(TPM_SECRET), (BYTE *) srkAuth, 
&encSrkAuth.size, encSrkAuth.data);
-  
-  
-  // Build srk public key struct
-  srkPub.ver = TPM_STRUCT_VER_1_1;
-  srkPub.keyUsage = TPM_KEY_STORAGE;
-  srkPub.keyFlags = 0x00;
-  srkPub.authDataUsage = TPM_AUTH_ALWAYS;
-  memcpy(&srkPub.algorithmParms, &srkKeyInfo, sizeof(TPM_KEY_PARMS));
-  srkPub.PCRInfoSize = 0;
-  srkPub.PCRInfo = 0;
-  srkPub.pubKey.keyLength= 0;
-  srkPub.encDataSize = 0;
-  
-  srkText.data = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
-  srkText.size = BSG_Pack(BSG_TPM_KEY, (BYTE *) &srkPub, srkText.data);
-  
-  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
-  
-  paramTextSize = BSG_PackList(paramText, 5,
-                              BSG_TPM_COMMAND_CODE,&command,
-                              BSG_TPM_PROTOCOL_ID, &proto_id,
-                              BSG_TPM_SIZE32_DATA, &encOwnerAuth,
-                              BSG_TPM_SIZE32_DATA, &encSrkAuth,
-                              BSG_TPM_KEY, &srkPub);
-  
-  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, ownerAuth, auth) );
-  
-  new_srk = srkText.data;
-  TPMTRYRETURN( TCSP_TakeOwnership ( hContext,
-                                    proto_id,
-                                    encOwnerAuth.size, 
-                                    encOwnerAuth.data,
-                                    encSrkAuth.size,
-                                    encSrkAuth.data,
-                                    &srkText.size,
-                                    &new_srk, 
-                                    auth ) );
-  
-  
-  paramTextSize = BSG_PackList(paramText, 2, 
-                              BSG_TPM_RESULT, &status,
-                              BSG_TPM_COMMAND_CODE, &command);
-  memcpy(paramText + paramTextSize, new_srk, srkText.size);
-  paramTextSize += srkText.size;
-  
-  
-  TPMTRYRETURN( VerifyAuth(  paramText, paramTextSize,
-                            ownerAuth, auth, 
-                            hContext) );
-  
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  free(srkText.data);
-  free(encSrkAuth.data);
-  free(encOwnerAuth.data);
-  free(paramText);
-  
-  TCS_FreeMemory(hContext, new_srk);
-  
-  return status;
-}
-
-TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE    hContext,
-                                  const TPM_AUTHDATA          *ownerAuth, 
-                                  TCS_AUTH                    *auth) {
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Disabling Pubek Read.\n");
-  
-  TPM_RESULT status = TPM_SUCCESS;
-  TPM_COMMAND_CODE command = TPM_ORD_DisablePubekRead;
-  
-  BYTE *paramText;        // Digest to make Auth.
-  UINT32 paramTextSize;
-    
-  // Generate HMAC   
-  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
-  
-  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
-  
-  paramTextSize = BSG_PackList(paramText, 1,
-                              BSG_TPM_COMMAND_CODE, &command);
-  
-  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
-                             ownerAuth, auth) );
-  
-  // Call TCS
-  TPMTRYRETURN( TCSP_DisablePubekRead ( hContext, // in
-                                        auth) );
-  
-  // Verify Auth
-  paramTextSize = BSG_PackList(paramText, 2,
-                              BSG_TPM_RESULT, &status,
-                              BSG_TPM_COMMAND_CODE, &command);
-  
-  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
-                           ownerAuth, auth, 
-                           hContext) );
-  goto egress;
-  
- abort_egress:
- egress:
-  free(paramText);
-  return status;
-}
-
-TPM_RESULT VTSP_CreateWrapKey(  const TCS_CONTEXT_HANDLE hContext,
-                                const TPM_KEY_USAGE      usage,
-                                const TPM_AUTHDATA       *newKeyAuth,
-                                const TCS_KEY_HANDLE     parentHandle, 
-                                const TPM_AUTHDATA       *osapSharedSecret,
-                                buffer_t                 *pubKeyBuf,
-                                TCS_AUTH                 *auth) {
-  
-  int i;
-  TPM_RESULT status = TPM_SUCCESS;
-  TPM_COMMAND_CODE command = TPM_ORD_CreateWrapKey;
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Creating new key of type %d.\n", usage);
-  
-  // vars for Calculate encUsageAuth
-  BYTE *paramText;      
-  UINT32 paramTextSize;
-  
-  // vars for Calculate encUsageAuth
-  BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
-  TPM_DIGEST XORKey1;
-  UINT32 XORbufferSize;
-  TPM_SECRET encUsageAuth, encMigrationAuth;
-  
-  // vars for Flatten newKey prototype
-  BYTE *flatKey = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
-  UINT32 flatKeySize = TCPA_MAX_BUFFER_LENGTH;                                 
   
-  struct pack_buf_t newKeyText;
-  
-  // Fill in newKey
-  TPM_KEY newKey;
-  
-  BYTE RSAkeyInfo[12] = { 0x00, 0x00, (RSA_KEY_SIZE >> 8), 0x00,   0x00, 0x00, 
0x00, 0x02,   0x00, 0x00, 0x00, 0x00};
-  newKey.algorithmParms.algorithmID = TPM_ALG_RSA;
-  newKey.algorithmParms.parms = (BYTE *) &RSAkeyInfo;
-  newKey.algorithmParms.parmSize = 12;
-  
-  switch (usage) {
-  case TPM_KEY_SIGNING:
-    vtpmloginfo(VTPM_LOG_VTSP, "Creating Signing Key...\n");
-    newKey.keyUsage = TPM_KEY_SIGNING;
-    newKey.algorithmParms.encScheme = TPM_ES_NONE;
-    newKey.algorithmParms.sigScheme = TPM_SS_RSASSAPKCS1v15_SHA1;
-    break;
-  case TPM_KEY_STORAGE:
-    vtpmloginfo(VTPM_LOG_VTSP, "Creating Storage Key...\n");
-    newKey.keyUsage = TPM_KEY_STORAGE;
-    newKey.algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
-    newKey.algorithmParms.sigScheme = TPM_SS_NONE;
-    break;
-  case TPM_KEY_BIND:
-    vtpmloginfo(VTPM_LOG_VTSP, "Creating Binding Key...\n");
-    newKey.keyUsage = TPM_KEY_BIND;
-    newKey.algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
-    newKey.algorithmParms.sigScheme = TPM_SS_NONE;
-    break;
-  default:
-    vtpmloginfo(VTPM_LOG_VTSP, "Cannot create key. Invalid Key Type.\n");
-    status = TPM_BAD_PARAMETER;
-    goto abort_egress;
-  }
-  
-  
-  newKey.ver = TPM_STRUCT_VER_1_1;
-  
-  newKey.keyFlags = 0;
-  newKey.authDataUsage = TPM_AUTH_ALWAYS;
-  newKey.pubKey.keyLength= 0;
-  newKey.encDataSize = 0;
-  newKey.encData = NULL;
-  
-  // FIXME: Support PCR bindings
-  newKey.PCRInfoSize = 0;
-  newKey.PCRInfo = NULL;
-  
-  // Calculate encUsageAuth                                    
-  XORbufferSize = BSG_PackList(  XORbuffer, 2, 
-                                BSG_TPM_SECRET, osapSharedSecret,
-                                BSG_TPM_NONCE, &auth->NonceEven);
-  Crypto_SHA1Full(XORbuffer, XORbufferSize, (BYTE *) &XORKey1);
-  
-  // FIXME: No support for migratable keys.
-  for (i=0; i < TPM_DIGEST_SIZE; i++) 
-    ((BYTE *) &encUsageAuth)[i] = ((BYTE *) &XORKey1)[i] ^ ((BYTE *) 
newKeyAuth)[i];
-  
-  // Flatten newKey prototype
-  flatKeySize = BSG_Pack(BSG_TPM_KEY, (BYTE *) &newKey, flatKey);
-  newKeyText.data = flatKey;
-  newKeyText.size = flatKeySize;
-  
-  // GenerateAuth new nonceOdd    
-  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
-  
-  // Generate HMAC
-  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
-  
-  paramTextSize = BSG_PackList(paramText, 3,
-                              BSG_TPM_COMMAND_CODE, &command,
-                              BSG_TPM_AUTHDATA, &encUsageAuth,
-                              BSG_TPM_AUTHDATA, &encMigrationAuth);
-  memcpy(paramText + paramTextSize, newKeyText.data, newKeyText.size);
-  paramTextSize += newKeyText.size;
-  
-  
-  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
-                             osapSharedSecret, auth) );
-  
-  // Call TCS
-  TPMTRYRETURN( TCSP_CreateWrapKey(  hContext, 
-                                    parentHandle,
-                                    encUsageAuth,
-                                    encMigrationAuth,
-                                    &newKeyText.size,
-                                    &newKeyText.data,
-                                    auth) );
-  
-  // Verify Auth
-  paramTextSize = BSG_PackList(paramText, 2,
-                              BSG_TPM_RESULT, &status,
-                              BSG_TPM_COMMAND_CODE, &command);
-  memcpy(paramText + paramTextSize, newKeyText.data, newKeyText.size);
-  paramTextSize += newKeyText.size;
-  
-  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
-                           osapSharedSecret, auth, 0) );
-  
-  // Unpack/return key structure
-  TPMTRYRETURN(buffer_init(pubKeyBuf, 0, 0) );
-  TPMTRYRETURN(buffer_append_raw(pubKeyBuf, newKeyText.size, newKeyText.data) 
);
-  
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  free(flatKey);
-  free(paramText);
-  TCS_FreeMemory(hContext, newKeyText.data);
-  
-  return status;
-}
-
-TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
-                        const TCS_KEY_HANDLE        hUnwrappingKey,
-                        const buffer_t              *rgbWrappedKeyBlob,
-                        const TPM_AUTHDATA          *parentAuth,
-                        TPM_HANDLE                  *newKeyHandle,
-                        TCS_AUTH                    *auth,
-                        CRYPTO_INFO                 *cryptoinfo /*= NULL*/) {
-  
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
-  
-  TPM_RESULT status = TPM_SUCCESS;
-  TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
-  
-  BYTE *paramText;        // Digest to make Auth.
-  UINT32 paramTextSize;
-  
-  if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
-      (newKeyHandle==NULL) || (auth==NULL)) {
-    status = TPM_BAD_PARAMETER;
-    goto abort_egress;
-  }
-  
-  // Generate Extra TCS Parameters
-  TPM_HANDLE phKeyHMAC;
-  
-  // Generate HMAC
-  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
-  
-  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
-  
-  paramTextSize = BSG_PackList(paramText, 1,
-                              BSG_TPM_COMMAND_CODE, &command);
-  
-  memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, 
buffer_len(rgbWrappedKeyBlob));
-  paramTextSize += buffer_len(rgbWrappedKeyBlob);
-  
-  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
-                             parentAuth, auth) );
-  
-  // Call TCS
-  TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
-                                    hUnwrappingKey,
-                                    buffer_len(rgbWrappedKeyBlob),
-                                    rgbWrappedKeyBlob->bytes,
-                                    auth,
-                                    newKeyHandle,
-                                    &phKeyHMAC) );
-  
-  // Verify Auth
-  paramTextSize = BSG_PackList(paramText, 3,
-                              BSG_TPM_RESULT, &status,
-                              BSG_TPM_COMMAND_CODE, &command,
-                              BSG_TPM_HANDLE, newKeyHandle);
-  
-  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
-                           parentAuth, auth, 
-                           hContext) );
-  
-  // Unpack/return key structure
-  if (cryptoinfo != NULL) {
-    TPM_KEY newKey;
-    
-    BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
-    TPM_RSA_KEY_PARMS rsaKeyParms;
-    
-    BSG_Unpack(BSG_TPM_RSA_KEY_PARMS, 
-              newKey.algorithmParms.parms, 
-              &rsaKeyParms);
-    
-    Crypto_RSABuildCryptoInfoPublic(rsaKeyParms.exponentSize, 
-                                   rsaKeyParms.exponent, 
-                                   newKey.pubKey.keyLength, 
-                                   newKey.pubKey.key, 
-                                   cryptoinfo);
-    
-    // Destroy rsaKeyParms
-    BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
-    
-    // Set encryption scheme
-    cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
-  }
-  
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  free(paramText);
-  return status;
-}
-
-TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
-                        const TPM_KEY_HANDLE        key_handle,
-                        const buffer_t              *bound_data,
-                        const TPM_AUTHDATA          *usage_auth,
-                        buffer_t                    *clear_data,
-                        TCS_AUTH                    *auth) {
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Unbinding %d bytes of data.\n", 
buffer_len(bound_data));
-  
-  TPM_RESULT status = TPM_SUCCESS;
-  TPM_COMMAND_CODE command = TPM_ORD_UnBind;
-  
-  BYTE *paramText;        // Digest to make Auth.
-  UINT32 paramTextSize;
-  
-  // Generate Extra TCS Parameters
-  struct pack_buf_t clear_data32;
-  BYTE *clear_data_text;
-  UINT32 clear_data_size;
-  
-  // Generate HMAC   
-  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
-  
-  struct pack_buf_t bound_data32 = {bound_data->size, bound_data->bytes};
-  
-  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
-  
-  paramTextSize = BSG_PackList(paramText, 2,
-                              BSG_TPM_COMMAND_CODE, &command,
-                              BSG_TPM_SIZE32_DATA, &bound_data32);
-  
-  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
-                             usage_auth, auth) );
-  
-  // Call TCS
-  TPMTRYRETURN( TCSP_UnBind( hContext,
-                            key_handle,
-                            buffer_len(bound_data),
-                            bound_data->bytes,
-                            auth,
-                            &clear_data_size,
-                            &clear_data_text) );
-  
-  
-  // Verify Auth
-  clear_data32.size = clear_data_size;
-  clear_data32.data = clear_data_text;
-  paramTextSize = BSG_PackList(paramText, 3,
-                              BSG_TPM_RESULT, &status,
-                              BSG_TPM_COMMAND_CODE, &command,
-                              BSG_TPM_SIZE32_DATA, &clear_data32);
-  
-  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
-                           usage_auth, auth, 
-                           hContext) );
-  
-  // Unpack/return key structure
-  TPMTRYRETURN(buffer_init(clear_data, 0, 0));
-  TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size, 
clear_data_text) );
-  
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  free(paramText);
-  TCS_FreeMemory(hContext, clear_data_text);
-  
-  return status;
-}
-
-TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cryptoInfo, 
-                       const buffer_t *inData, 
-                       buffer_t *outData)               
-{
-  vtpmloginfo(VTPM_LOG_VTSP, "Binding %d bytes of data.\n", 
buffer_len(inData));
-  TPM_BOUND_DATA boundData;
-  UINT32 i;
-  
-  // Fill boundData's accessory information
-  boundData.ver = TPM_STRUCT_VER_1_1;
-  boundData.payload = TPM_PT_BIND;
-  boundData.payloadData = inData->bytes;
-  
-  // Pack boundData before encryption
-  BYTE* flatBoundData = (BYTE *)malloc(sizeof(BYTE) * 
-                                      (sizeof(TPM_VERSION) +
-                                       sizeof(TPM_PAYLOAD_TYPE) +
-                                       buffer_len(inData)));
-  if (flatBoundData == NULL) {
-    return TPM_NOSPACE;
-  }
-  UINT32 flatBoundDataSize = 0;
-  flatBoundDataSize = BSG_PackList(  flatBoundData, 2, 
-                                    BSG_TPM_VERSION, &boundData.ver, 
-                                    BSG_TYPE_BYTE, &boundData.payload);
-  
-  memcpy(flatBoundData+flatBoundDataSize, inData->bytes, buffer_len(inData));
-  flatBoundDataSize += buffer_len(inData);
-  
-  BYTE out_tmp[RSA_KEY_SIZE/8]; // RSAEnc does not do blocking, So this is 
what will come out.
-  UINT32 out_tmp_size;
-  
-  // Encrypt flatBoundData
-  Crypto_RSAEnc( cryptoInfo, 
-                flatBoundDataSize, 
-                flatBoundData, 
-                &out_tmp_size, 
-                out_tmp);
-  
-  if (out_tmp_size > RSA_KEY_SIZE/8) {
-    // The result of RSAEnc should be a fixed size based on key size.
-    vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n");
-  }
-  
-  buffer_init(outData, 0, NULL);
-  buffer_append_raw(outData, out_tmp_size, out_tmp);
-  
-  vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size);
-  for(i = 0 ; i < out_tmp_size ; i++) {
-    vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out_tmp[i]);
-  }
-  vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
-  
-  // Free flatBoundData
-  free(flatBoundData);
-  
-  return TPM_SUCCESS;
-}
-
-// Function Reaches into unsupported TCS command, beware.
-TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
-                            const buffer_t *inbuf,
-                            buffer_t *outbuf ) {
-  
-  vtpmloginfo(VTPM_LOG_VTSP, "Passthrough in use.\n");
-  TPM_RESULT status = TPM_SUCCESS;
-  
-  // Generate Extra TCS Parameters
-  BYTE *resultText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
-  UINT32 resultTextSize =  TCPA_MAX_BUFFER_LENGTH;
-  
-  // Call TCS                          
-  TPMTRYRETURN( TCSP_RawTransmitData(buffer_len(inbuf), inbuf->bytes, 
-                                    &resultTextSize, resultText) );
-  
-  // Unpack/return key structure
-  TPMTRYRETURN(buffer_init (outbuf, resultTextSize, resultText) );             
                   
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  TCS_FreeMemory(hContext, resultText);
-  free(resultText);
-  return status;
-}
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * 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.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtsp.c
+// 
+//  Higher level interface to TCS for use in service.
+//
+// ==================================================================
+
+#include <string.h>
+#include "tcg.h"
+#include "tcs.h"
+#include "bsg.h"
+#include "log.h"
+#include "crypto.h"
+#include "vtsp.h"
+#include "buffer.h"
+
+#define  RSA_KEY_SIZE 0x0800
+
+/***********************************************************************************
+ * GenerateAuth: Generate authorization info to be sent back to application
+ *
+ * Parameters: outParamDigestText  The concatenation of output parameters to 
be SHA1ed
+ *    outParamDigestTextSize Size of inParamDigestText
+ *    HMACkey     Key to be used for HMACing
+ *          For OIAP use key.authUsage or PersistStore.ownerAuth
+ *          For OSAP use shared secret
+ *    pAuth     Authorization information from the application
+ *
+ * Return:  TPM_SUCCESS   Authorization data created
+ *    TPM_AUTHFAIL   Invalid (NULL) HMACkey presented for OSAP
+ 
*************************************************************************************/
+TPM_RESULT GenerateAuth( /*[IN]*/ const BYTE *inParamDigestText,
+                        /*[IN]*/ UINT32 inParamDigestTextSize,
+                        /*[IN]*/ const TPM_SECRET *HMACkey,  
+                        /*[IN,OUT]*/ TCS_AUTH *auth) {
+    
+  if (inParamDigestText == NULL || auth == NULL) 
+    return (TPM_AUTHFAIL);
+  else {
+    
+    //Generate new OddNonce
+    Crypto_GetRandom(auth->NonceOdd.nonce, sizeof(TPM_NONCE));
+    
+    // Create SHA1 inParamDigest
+    TPM_DIGEST inParamDigest;
+    Crypto_SHA1Full(inParamDigestText, inParamDigestTextSize, (BYTE *) 
&inParamDigest);
+    
+    // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
+    BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
+    
+    BSG_PackList(   hmacText, 4, 
+                   BSG_TPM_DIGEST, &inParamDigest,
+                   BSG_TPM_NONCE, &(auth->NonceEven),
+                   BSG_TPM_NONCE, &(auth->NonceOdd), 
+                   BSG_TYPE_BOOL, &(auth->fContinueAuthSession) );
+    
+    Crypto_HMAC((BYTE *) hmacText, sizeof(hmacText), (BYTE *) HMACkey, 
sizeof(TPM_DIGEST), (BYTE *) &(auth->HMAC));
+    
+    return(TPM_SUCCESS);
+    
+  }
+}
+
+/***********************************************************************************
+ * VerifyAuth: Verify the authdata for a command requiring authorization
+ *
+ * Parameters: inParamDigestText  The concatenation of parameters to be SHA1ed
+ *    inParamDigestTextSize Size of inParamDigestText
+ *    authDataUsage   AuthDataUsage for the Entity being used
+ *          Key->authDataUsage or TPM_AUTH_OWNER
+ *    HMACkey     Key to be used for HMACing
+ *          For OIAP use key.authUsage or PersistStore.ownerAuth
+ *          For OSAP use NULL (It will be aquired from the Auth Session)
+ *          If unknown (default), assume OIAP
+ *    sessionAuth    A TCS_AUTH info for the session
+ *    pAuth     Authorization information from the application
+ *              hContext        If specified, on failed Auth, VerifyAuth will
+ *                                      generate a new OIAP session in place 
of themselves
+ *                                      destroyed session.
+ *
+ * Return:  TPM_SUCCESS   Authorization Verified
+ *    TPM_AUTHFAIL   Authorization Failed
+ *    TPM_FAIL    Failure during SHA1 routines
+ 
*************************************************************************************/
+TPM_RESULT VerifyAuth( /*[IN]*/ const BYTE *outParamDigestText,
+                      /*[IN]*/ UINT32 outParamDigestTextSize,
+                      /*[IN]*/ const TPM_SECRET *HMACkey,  
+                      /*[IN,OUT]*/ TCS_AUTH *auth,
+                      /*[IN]*/  TCS_CONTEXT_HANDLE hContext) {
+  if (outParamDigestText == NULL || auth == NULL) 
+    return (TPM_AUTHFAIL);
+  
+  
+  // Create SHA1 inParamDigest
+  TPM_DIGEST outParamDigest;
+  Crypto_SHA1Full(outParamDigestText, outParamDigestTextSize, (BYTE *) 
&outParamDigest);
+  
+  // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
+  TPM_DIGEST hm;
+  BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
+  
+  BSG_PackList(   hmacText, 4, 
+                 BSG_TPM_DIGEST, &outParamDigest,
+                 BSG_TPM_NONCE, &(auth->NonceEven),
+                 BSG_TPM_NONCE, &(auth->NonceOdd), 
+                 BSG_TYPE_BOOL, &(auth->fContinueAuthSession) );
+  
+  Crypto_HMAC((BYTE *) hmacText, sizeof(hmacText),
+             (BYTE *) HMACkey, sizeof(TPM_DIGEST), (BYTE *) &hm);
+    
+  // Compare correct HMAC with provided one.
+  if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0)  // 0 indicates 
equality
+    return (TPM_SUCCESS);
+  else {
+    VTSP_OIAP( hContext, auth);
+    return (TPM_AUTHFAIL);
+  }
+}
+
+TPM_RESULT VTSP_OIAP(const TCS_CONTEXT_HANDLE hContext,
+                    TCS_AUTH *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "OIAP.\n");
+  TPM_RESULT status = TPM_SUCCESS;                           
+  TPMTRYRETURN( TCSP_OIAP(hContext,
+                         &auth->AuthHandle,
+                         &auth->NonceEven) );
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_HANDLE hContext,
+                    const TPM_ENTITY_TYPE entityType,
+                    const UINT32 entityValue,
+                    const TPM_AUTHDATA *usageAuth,
+                    TPM_SECRET *sharedSecret, 
+                    TCS_AUTH *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "OSAP.\n");
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_NONCE nonceEvenOSAP, nonceOddOSAP;
+  
+  Crypto_GetRandom((BYTE *) &nonceOddOSAP, sizeof(TPM_NONCE) ); 
+  
+  TPMTRYRETURN( TCSP_OSAP(    hContext,
+                             entityType,
+                             entityValue, 
+                             nonceOddOSAP,
+                             &auth->AuthHandle, 
+                             &auth->NonceEven, 
+                             &nonceEvenOSAP) );
+  
+  // Calculating Session Secret
+  BYTE sharedSecretText[TPM_DIGEST_SIZE * 2];
+  
+  BSG_PackList(  sharedSecretText, 2,
+                BSG_TPM_NONCE, &nonceEvenOSAP,
+                BSG_TPM_NONCE, &nonceOddOSAP);
+  
+  Crypto_HMAC(sharedSecretText, sizeof(sharedSecretText), (BYTE *) usageAuth, 
TPM_DIGEST_SIZE, (BYTE *) sharedSecret);       
+    
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+
+
+TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
+                             CRYPTO_INFO *crypto_info) {
+  
+  TPM_RESULT status;
+  TPM_NONCE antiReplay;
+  TPM_DIGEST   checksum;
+  BYTE *pubEKtext;
+  UINT32 pubEKtextsize;
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Reading Public EK.\n");
+  
+  // GenerateAuth new nonceOdd    
+  Crypto_GetRandom(&antiReplay, sizeof(TPM_NONCE) );
+  
+  
+  TPMTRYRETURN( TCSP_ReadPubek(  hContext,
+                                antiReplay,
+                                &pubEKtextsize,
+                                &pubEKtext,
+                                &checksum) );
+  
+  
+  // Extract the remaining output parameters
+  TPM_PUBKEY pubEK;
+  
+  BSG_Unpack(BSG_TPM_PUBKEY, pubEKtext, (BYTE *) &pubEK);
+  
+  // Build CryptoInfo for the bindingKey
+  TPM_RSA_KEY_PARMS rsaKeyParms;
+  
+  BSG_Unpack(BSG_TPM_RSA_KEY_PARMS, 
+            pubEK.algorithmParms.parms, 
+            &rsaKeyParms);
+  
+  Crypto_RSABuildCryptoInfoPublic(rsaKeyParms.exponentSize, 
+                                 rsaKeyParms.exponent, 
+                                 pubEK.pubKey.keyLength, 
+                                 pubEK.pubKey.key, 
+                                 crypto_info);
+    
+  // Destroy rsaKeyParms
+  BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
+
+  // Set encryption scheme
+  crypto_info->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
+  //crypto_info->encScheme = pubEK.algorithmParms.encScheme;
+  crypto_info->algorithmID = pubEK.algorithmParms.algorithmID;
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+TPM_RESULT VTSP_TakeOwnership(   const TCS_CONTEXT_HANDLE hContext,
+                                 const TPM_AUTHDATA *ownerAuth, 
+                                 const TPM_AUTHDATA *srkAuth,
+                                 CRYPTO_INFO *ek_cryptoInfo,
+                                 TCS_AUTH *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Taking Ownership of TPM.\n");
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_TakeOwnership;
+  TPM_PROTOCOL_ID proto_id = TPM_PID_OWNER;
+  BYTE *new_srk;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+  
+  // vars for srkpubkey parameter
+  TPM_KEY srkPub;
+  TPM_KEY_PARMS srkKeyInfo = {TPM_ALG_RSA, TPM_ES_RSAESOAEP_SHA1_MGF1, 
TPM_SS_NONE, 12, 0};
+  BYTE srkRSAkeyInfo[12] = { 0x00, 0x00, (RSA_KEY_SIZE >> 8), 0x00,   0x00, 
0x00, 0x00, 0x02,   0x00, 0x00, 0x00, 0x00};
+  srkKeyInfo.parms = (BYTE *) &srkRSAkeyInfo;
+  
+  struct pack_buf_t srkText;
+  
+  // GenerateAuth new nonceOdd    
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  //These values are accurate for an enc(AuthData).
+  struct pack_buf_t encOwnerAuth, encSrkAuth;
+  
+  encOwnerAuth.data = (BYTE *)malloc(sizeof(BYTE) * 256);
+  encSrkAuth.data = (BYTE *)malloc(sizeof(BYTE) * 256);
+  
+  if (encOwnerAuth.data == NULL || encSrkAuth.data == NULL) {
+    vtpmloginfo(VTPM_LOG_VTSP, "Could not malloc encrypted auths.\n");
+    status = TPM_RESOURCES;
+    goto abort_egress;
+  }
+  
+  Crypto_RSAEnc(ek_cryptoInfo, sizeof(TPM_SECRET), (BYTE *) ownerAuth, 
&encOwnerAuth.size, encOwnerAuth.data);
+  Crypto_RSAEnc(ek_cryptoInfo, sizeof(TPM_SECRET), (BYTE *) srkAuth, 
&encSrkAuth.size, encSrkAuth.data);
+  
+  
+  // Build srk public key struct
+  srkPub.ver = TPM_STRUCT_VER_1_1;
+  srkPub.keyUsage = TPM_KEY_STORAGE;
+  srkPub.keyFlags = 0x00;
+  srkPub.authDataUsage = TPM_AUTH_ALWAYS;
+  memcpy(&srkPub.algorithmParms, &srkKeyInfo, sizeof(TPM_KEY_PARMS));
+  srkPub.PCRInfoSize = 0;
+  srkPub.PCRInfo = 0;
+  srkPub.pubKey.keyLength= 0;
+  srkPub.encDataSize = 0;
+  
+  srkText.data = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  srkText.size = BSG_Pack(BSG_TPM_KEY, (BYTE *) &srkPub, srkText.data);
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 5,
+                              BSG_TPM_COMMAND_CODE,&command,
+                              BSG_TPM_PROTOCOL_ID, &proto_id,
+                              BSG_TPM_SIZE32_DATA, &encOwnerAuth,
+                              BSG_TPM_SIZE32_DATA, &encSrkAuth,
+                              BSG_TPM_KEY, &srkPub);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, ownerAuth, auth) );
+  
+  new_srk = srkText.data;
+  TPMTRYRETURN( TCSP_TakeOwnership ( hContext,
+                                    proto_id,
+                                    encOwnerAuth.size, 
+                                    encOwnerAuth.data,
+                                    encSrkAuth.size,
+                                    encSrkAuth.data,
+                                    &srkText.size,
+                                    &new_srk, 
+                                    auth ) );
+  
+  
+  paramTextSize = BSG_PackList(paramText, 2, 
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command);
+  memcpy(paramText + paramTextSize, new_srk, srkText.size);
+  paramTextSize += srkText.size;
+  
+  
+  TPMTRYRETURN( VerifyAuth(  paramText, paramTextSize,
+                            ownerAuth, auth, 
+                            hContext) );
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(srkText.data);
+  free(encSrkAuth.data);
+  free(encOwnerAuth.data);
+  free(paramText);
+  
+  TCS_FreeMemory(hContext, new_srk);
+  
+  return status;
+}
+
+TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE    hContext,
+                                  const TPM_AUTHDATA          *ownerAuth, 
+                                  TCS_AUTH                    *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Disabling Pubek Read.\n");
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_DisablePubekRead;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+    
+  // Generate HMAC   
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 1,
+                              BSG_TPM_COMMAND_CODE, &command);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             ownerAuth, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_DisablePubekRead ( hContext, // in
+                                        auth) );
+  
+  // Verify Auth
+  paramTextSize = BSG_PackList(paramText, 2,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command);
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           ownerAuth, auth, 
+                           hContext) );
+  goto egress;
+  
+ abort_egress:
+ egress:
+  free(paramText);
+  return status;
+}
+
+TPM_RESULT VTSP_CreateWrapKey(  const TCS_CONTEXT_HANDLE hContext,
+                                const TPM_KEY_USAGE      usage,
+                                const TPM_AUTHDATA       *newKeyAuth,
+                                const TCS_KEY_HANDLE     parentHandle, 
+                                const TPM_AUTHDATA       *osapSharedSecret,
+                                buffer_t                 *pubKeyBuf,
+                                TCS_AUTH                 *auth) {
+  
+  int i;
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_CreateWrapKey;
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Creating new key of type %d.\n", usage);
+  
+  // vars for Calculate encUsageAuth
+  BYTE *paramText;      
+  UINT32 paramTextSize;
+  
+  // vars for Calculate encUsageAuth
+  BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
+  TPM_DIGEST XORKey1;
+  UINT32 XORbufferSize;
+  TPM_SECRET encUsageAuth, encMigrationAuth;
+  
+  // vars for Flatten newKey prototype
+  BYTE *flatKey = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+  UINT32 flatKeySize = TCPA_MAX_BUFFER_LENGTH;                                 
   
+  struct pack_buf_t newKeyText;
+  
+  // Fill in newKey
+  TPM_KEY newKey;
+  
+  BYTE RSAkeyInfo[12] = { 0x00, 0x00, (RSA_KEY_SIZE >> 8), 0x00,   0x00, 0x00, 
0x00, 0x02,   0x00, 0x00, 0x00, 0x00};
+  newKey.algorithmParms.algorithmID = TPM_ALG_RSA;
+  newKey.algorithmParms.parms = (BYTE *) &RSAkeyInfo;
+  newKey.algorithmParms.parmSize = 12;
+  
+  switch (usage) {
+  case TPM_KEY_SIGNING:
+    vtpmloginfo(VTPM_LOG_VTSP, "Creating Signing Key...\n");
+    newKey.keyUsage = TPM_KEY_SIGNING;
+    newKey.algorithmParms.encScheme = TPM_ES_NONE;
+    newKey.algorithmParms.sigScheme = TPM_SS_RSASSAPKCS1v15_SHA1;
+    break;
+  case TPM_KEY_STORAGE:
+    vtpmloginfo(VTPM_LOG_VTSP, "Creating Storage Key...\n");
+    newKey.keyUsage = TPM_KEY_STORAGE;
+    newKey.algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
+    newKey.algorithmParms.sigScheme = TPM_SS_NONE;
+    break;
+  case TPM_KEY_BIND:
+    vtpmloginfo(VTPM_LOG_VTSP, "Creating Binding Key...\n");
+    newKey.keyUsage = TPM_KEY_BIND;
+    newKey.algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
+    newKey.algorithmParms.sigScheme = TPM_SS_NONE;
+    break;
+  default:
+    vtpmloginfo(VTPM_LOG_VTSP, "Cannot create key. Invalid Key Type.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+  
+  newKey.ver = TPM_STRUCT_VER_1_1;
+  
+  newKey.keyFlags = 0;
+  newKey.authDataUsage = TPM_AUTH_ALWAYS;
+  newKey.pubKey.keyLength= 0;
+  newKey.encDataSize = 0;
+  newKey.encData = NULL;
+  
+  // FIXME: Support PCR bindings
+  newKey.PCRInfoSize = 0;
+  newKey.PCRInfo = NULL;
+  
+  // Calculate encUsageAuth                                    
+  XORbufferSize = BSG_PackList(  XORbuffer, 2, 
+                                BSG_TPM_SECRET, osapSharedSecret,
+                                BSG_TPM_NONCE, &auth->NonceEven);
+  Crypto_SHA1Full(XORbuffer, XORbufferSize, (BYTE *) &XORKey1);
+  
+  // FIXME: No support for migratable keys.
+  for (i=0; i < TPM_DIGEST_SIZE; i++) 
+    ((BYTE *) &encUsageAuth)[i] = ((BYTE *) &XORKey1)[i] ^ ((BYTE *) 
newKeyAuth)[i];
+  
+  // Flatten newKey prototype
+  flatKeySize = BSG_Pack(BSG_TPM_KEY, (BYTE *) &newKey, flatKey);
+  newKeyText.data = flatKey;
+  newKeyText.size = flatKeySize;
+  
+  // GenerateAuth new nonceOdd    
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  // Generate HMAC
+  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 3,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_AUTHDATA, &encUsageAuth,
+                              BSG_TPM_AUTHDATA, &encMigrationAuth);
+  memcpy(paramText + paramTextSize, newKeyText.data, newKeyText.size);
+  paramTextSize += newKeyText.size;
+  
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             osapSharedSecret, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_CreateWrapKey(  hContext, 
+                                    parentHandle,
+                                    encUsageAuth,
+                                    encMigrationAuth,
+                                    &newKeyText.size,
+                                    &newKeyText.data,
+                                    auth) );
+  
+  // Verify Auth
+  paramTextSize = BSG_PackList(paramText, 2,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command);
+  memcpy(paramText + paramTextSize, newKeyText.data, newKeyText.size);
+  paramTextSize += newKeyText.size;
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           osapSharedSecret, auth, 0) );
+  
+  // Unpack/return key structure
+  TPMTRYRETURN(buffer_init(pubKeyBuf, 0, 0) );
+  TPMTRYRETURN(buffer_append_raw(pubKeyBuf, newKeyText.size, newKeyText.data) 
);
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(flatKey);
+  free(paramText);
+  TCS_FreeMemory(hContext, newKeyText.data);
+  
+  return status;
+}
+
+TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
+                        const TCS_KEY_HANDLE        hUnwrappingKey,
+                        const buffer_t              *rgbWrappedKeyBlob,
+                        const TPM_AUTHDATA          *parentAuth,
+                        TPM_HANDLE                  *newKeyHandle,
+                        TCS_AUTH                    *auth,
+                        CRYPTO_INFO                 *cryptoinfo /*= NULL*/) {
+  
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+  
+  if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
+      (newKeyHandle==NULL) || (auth==NULL)) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+  // Generate Extra TCS Parameters
+  TPM_HANDLE phKeyHMAC;
+  
+  // Generate HMAC
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 1,
+                              BSG_TPM_COMMAND_CODE, &command);
+  
+  memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, 
buffer_len(rgbWrappedKeyBlob));
+  paramTextSize += buffer_len(rgbWrappedKeyBlob);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             parentAuth, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
+                                    hUnwrappingKey,
+                                    buffer_len(rgbWrappedKeyBlob),
+                                    rgbWrappedKeyBlob->bytes,
+                                    auth,
+                                    newKeyHandle,
+                                    &phKeyHMAC) );
+  
+  // Verify Auth
+  paramTextSize = BSG_PackList(paramText, 3,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_HANDLE, newKeyHandle);
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           parentAuth, auth, 
+                           hContext) );
+  
+  // Unpack/return key structure
+  if (cryptoinfo != NULL) {
+    TPM_KEY newKey;
+    
+    BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
+    TPM_RSA_KEY_PARMS rsaKeyParms;
+    
+    BSG_Unpack(BSG_TPM_RSA_KEY_PARMS, 
+              newKey.algorithmParms.parms, 
+              &rsaKeyParms);
+    
+    Crypto_RSABuildCryptoInfoPublic(rsaKeyParms.exponentSize, 
+                                   rsaKeyParms.exponent, 
+                                   newKey.pubKey.keyLength, 
+                                   newKey.pubKey.key, 
+                                   cryptoinfo);
+    
+    // Destroy rsaKeyParms
+    BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
+    
+    // Set encryption scheme
+    cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
+  }
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(paramText);
+  return status;
+}
+
+TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
+                        const TPM_KEY_HANDLE        key_handle,
+                        const buffer_t              *bound_data,
+                        const TPM_AUTHDATA          *usage_auth,
+                        buffer_t                    *clear_data,
+                        TCS_AUTH                    *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Unbinding %d bytes of data.\n", 
buffer_len(bound_data));
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_UnBind;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+  
+  // Generate Extra TCS Parameters
+  struct pack_buf_t clear_data32;
+  BYTE *clear_data_text;
+  UINT32 clear_data_size;
+  
+  // Generate HMAC   
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  struct pack_buf_t bound_data32 = {bound_data->size, bound_data->bytes};
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 2,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_SIZE32_DATA, &bound_data32);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             usage_auth, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_UnBind( hContext,
+                            key_handle,
+                            buffer_len(bound_data),
+                            bound_data->bytes,
+                            auth,
+                            &clear_data_size,
+                            &clear_data_text) );
+  
+  
+  // Verify Auth
+  clear_data32.size = clear_data_size;
+  clear_data32.data = clear_data_text;
+  paramTextSize = BSG_PackList(paramText, 3,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_SIZE32_DATA, &clear_data32);
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           usage_auth, auth, 
+                           hContext) );
+  
+  // Unpack/return key structure
+  TPMTRYRETURN(buffer_init(clear_data, 0, 0));
+  TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size, 
clear_data_text) );
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(paramText);
+  TCS_FreeMemory(hContext, clear_data_text);
+  
+  return status;
+}
+
+TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cryptoInfo, 
+                       const buffer_t *inData, 
+                       buffer_t *outData)               
+{
+  vtpmloginfo(VTPM_LOG_VTSP, "Binding %d bytes of data.\n", 
buffer_len(inData));
+  TPM_BOUND_DATA boundData;
+  UINT32 i;
+  
+  // Fill boundData's accessory information
+  boundData.ver = TPM_STRUCT_VER_1_1;
+  boundData.payload = TPM_PT_BIND;
+  boundData.payloadData = inData->bytes;
+  
+  // Pack boundData before encryption
+  BYTE* flatBoundData = (BYTE *)malloc(sizeof(BYTE) * 
+                                      (sizeof(TPM_VERSION) +
+                                       sizeof(TPM_PAYLOAD_TYPE) +
+                                       buffer_len(inData)));
+  if (flatBoundData == NULL) {
+    return TPM_NOSPACE;
+  }
+  UINT32 flatBoundDataSize = 0;
+  flatBoundDataSize = BSG_PackList(  flatBoundData, 2, 
+                                    BSG_TPM_VERSION, &boundData.ver, 
+                                    BSG_TYPE_BYTE, &boundData.payload);
+  
+  memcpy(flatBoundData+flatBoundDataSize, inData->bytes, buffer_len(inData));
+  flatBoundDataSize += buffer_len(inData);
+  
+  BYTE out_tmp[RSA_KEY_SIZE/8]; // RSAEnc does not do blocking, So this is 
what will come out.
+  UINT32 out_tmp_size;
+  
+  // Encrypt flatBoundData
+  Crypto_RSAEnc( cryptoInfo, 
+                flatBoundDataSize, 
+                flatBoundData, 
+                &out_tmp_size, 
+                out_tmp);
+  
+  if (out_tmp_size > RSA_KEY_SIZE/8) {
+    // The result of RSAEnc should be a fixed size based on key size.
+    vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n");
+  }
+  
+  buffer_init(outData, 0, NULL);
+  buffer_append_raw(outData, out_tmp_size, out_tmp);
+  
+  vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size);
+  for(i = 0 ; i < out_tmp_size ; i++) {
+    vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out_tmp[i]);
+  }
+  vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
+  
+  // Free flatBoundData
+  free(flatBoundData);
+  
+  return TPM_SUCCESS;
+}
+
+// Function Reaches into unsupported TCS command, beware.
+TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
+                            const buffer_t *inbuf,
+                            buffer_t *outbuf ) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Passthrough in use.\n");
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  // Generate Extra TCS Parameters
+  BYTE *resultText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  UINT32 resultTextSize =  TCPA_MAX_BUFFER_LENGTH;
+  
+  // Call TCS                          
+  TPMTRYRETURN( TCSP_RawTransmitData(buffer_len(inbuf), inbuf->bytes, 
+                                    &resultTextSize, resultText) );
+  
+  // Unpack/return key structure
+  TPMTRYRETURN(buffer_init (outbuf, resultTextSize, resultText) );             
                   
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  TCS_FreeMemory(hContext, resultText);
+  free(resultText);
+  return status;
+}
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/manager/vtsp.h Fri Dec  2 18:52:25 2005
@@ -1,102 +1,102 @@
-// ===================================================================
-// 
-// Copyright (c) 2005, Intel Corp.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions 
-// are met:
-//
-//   * Redistributions of source code must retain the above copyright 
-//     notice, this list of conditions and the following disclaimer.
-//   * 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.
-//   * Neither the name of Intel Corporation nor the names of its 
-//     contributors may be used to endorse or promote products derived
-//     from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-// ===================================================================
-// 
-// vtsp.h
-// 
-//  Higher level interface to TCS.
-//
-// ==================================================================
-
-#ifndef __VTSP_H__
-#define __VTSP_H__
-
-#include "tcg.h"
-#include "tcs.h"
-
-#define KEY_BUFFER_SIZE 2048
-
-TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
-                            const buffer_t *inbuf,
-                            buffer_t *outbuf );
-
-TPM_RESULT VTSP_OIAP(  const TCS_CONTEXT_HANDLE hContext,
-                       TCS_AUTH *auth);
-                       
-TPM_RESULT VTSP_OSAP(  const TCS_CONTEXT_HANDLE hContext,
-                       const TPM_ENTITY_TYPE entityType,
-                       const UINT32 entityValue,
-                       const TPM_AUTHDATA *usageAuth,
-                       TPM_SECRET *sharedsecret, 
-                       TCS_AUTH *auth);
-
-TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
-                             CRYPTO_INFO *cypto_info);
-
-TPM_RESULT VTSP_TakeOwnership(   const TCS_CONTEXT_HANDLE hContext,
-                                 const TPM_AUTHDATA *ownerAuth, 
-                                 const TPM_AUTHDATA *srkAuth,
-                                 CRYPTO_INFO *ek_cryptoInfo,
-                                 TCS_AUTH *auth);
-                               
-TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE    hContext,
-                                  const TPM_AUTHDATA *ownerAuth, 
-                                  TCS_AUTH                    *auth);
-                               
-TPM_RESULT VTSP_CreateWrapKey(  const TCS_CONTEXT_HANDLE hContext,
-                                const TPM_KEY_USAGE      usage,
-                                const TPM_AUTHDATA       *newKeyAuth,
-                                const TCS_KEY_HANDLE     parentHandle, 
-                                const TPM_AUTHDATA       *osapSharedSecret,
-                                buffer_t                 *pubKeyBuf,
-                                TCS_AUTH                 *auth);
-
-TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
-                        const TCS_KEY_HANDLE        hUnwrappingKey,
-                        const buffer_t              *rgbWrappedKeyBlob,
-                        const TPM_AUTHDATA          *parentAuth,
-                        TPM_HANDLE                  *newKeyHandle,
-                        TCS_AUTH                    *pAuth,
-                        CRYPTO_INFO                 *cryptoinfo);
-
-TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
-                        const TPM_KEY_HANDLE        key_handle,
-                        const buffer_t              *bound_data,
-                        const TPM_AUTHDATA          *usage_auth,
-                        buffer_t                    *clear_data,
-                        TCS_AUTH                    *auth);
-                        
-TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cryptoInfo,
-            const buffer_t *inData, 
-            buffer_t *outData);
-                        
-#endif //_VTSP_H_
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * 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.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtsp.h
+// 
+//  Higher level interface to TCS.
+//
+// ==================================================================
+
+#ifndef __VTSP_H__
+#define __VTSP_H__
+
+#include "tcg.h"
+#include "tcs.h"
+
+#define KEY_BUFFER_SIZE 2048
+
+TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
+                            const buffer_t *inbuf,
+                            buffer_t *outbuf );
+
+TPM_RESULT VTSP_OIAP(  const TCS_CONTEXT_HANDLE hContext,
+                       TCS_AUTH *auth);
+                       
+TPM_RESULT VTSP_OSAP(  const TCS_CONTEXT_HANDLE hContext,
+                       const TPM_ENTITY_TYPE entityType,
+                       const UINT32 entityValue,
+                       const TPM_AUTHDATA *usageAuth,
+                       TPM_SECRET *sharedsecret, 
+                       TCS_AUTH *auth);
+
+TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
+                             CRYPTO_INFO *cypto_info);
+
+TPM_RESULT VTSP_TakeOwnership(   const TCS_CONTEXT_HANDLE hContext,
+                                 const TPM_AUTHDATA *ownerAuth, 
+                                 const TPM_AUTHDATA *srkAuth,
+                                 CRYPTO_INFO *ek_cryptoInfo,
+                                 TCS_AUTH *auth);
+                               
+TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE    hContext,
+                                  const TPM_AUTHDATA *ownerAuth, 
+                                  TCS_AUTH                    *auth);
+                               
+TPM_RESULT VTSP_CreateWrapKey(  const TCS_CONTEXT_HANDLE hContext,
+                                const TPM_KEY_USAGE      usage,
+                                const TPM_AUTHDATA       *newKeyAuth,
+                                const TCS_KEY_HANDLE     parentHandle, 
+                                const TPM_AUTHDATA       *osapSharedSecret,
+                                buffer_t                 *pubKeyBuf,
+                                TCS_AUTH                 *auth);
+
+TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
+                        const TCS_KEY_HANDLE        hUnwrappingKey,
+                        const buffer_t              *rgbWrappedKeyBlob,
+                        const TPM_AUTHDATA          *parentAuth,
+                        TPM_HANDLE                  *newKeyHandle,
+                        TCS_AUTH                    *pAuth,
+                        CRYPTO_INFO                 *cryptoinfo);
+
+TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
+                        const TPM_KEY_HANDLE        key_handle,
+                        const buffer_t              *bound_data,
+                        const TPM_AUTHDATA          *usage_auth,
+                        buffer_t                    *clear_data,
+                        TCS_AUTH                    *auth);
+                        
+TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cryptoInfo,
+            const buffer_t *inData, 
+            buffer_t *outData);
+                        
+#endif //_VTSP_H_
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/util/Makefile
--- a/tools/vtpm_manager/util/Makefile  Fri Dec  2 18:12:11 2005
+++ b/tools/vtpm_manager/util/Makefile  Fri Dec  2 18:52:25 2005
@@ -1,19 +1,19 @@
-XEN_ROOT = ../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
-
-BIN            = libTCGUtils.a
-
-all: build
-
-build: $(BIN)
-
-install: build
-
-clean:
-       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
-
-mrproper: clean
-       rm -f *~
-
-$(BIN): $(OBJS)
-       $(AR) rcs $(BIN) $(OBJS)
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIN            = libTCGUtils.a
+
+all: build
+
+build: $(BIN)
+
+install: build
+
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+mrproper: clean
+       rm -f *~
+
+$(BIN): $(OBJS)
+       $(AR) rcs $(BIN) $(OBJS)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xenmon/xenmon.py
--- a/tools/xenmon/xenmon.py    Fri Dec  2 18:12:11 2005
+++ b/tools/xenmon/xenmon.py    Fri Dec  2 18:52:25 2005
@@ -58,6 +58,8 @@
 EXCOUNT = "Exec Count"
 
 # globals
+dom_in_use = []
+
 # our curses screen
 stdscr = None
 
@@ -88,18 +90,18 @@
 # encapsulate information about a domain
 class DomainInfo:
     def __init__(self):
-        self.allocated_samples = []
-        self.gotten_samples = []
-        self.blocked_samples = []
-        self.waited_samples = []
-        self.execcount_samples = []
-        self.iocount_samples = []
+        self.allocated_sum = 0
+        self.gotten_sum = 0
+        self.blocked_sum = 0
+        self.waited_sum = 0
+        self.exec_count = 0;
+        self.iocount_sum = 0
         self.ffp_samples = []
 
     def gotten_stats(self, passed):
-        total = float(sum(self.gotten_samples))
+        total = float(self.gotten_sum)
         per = 100*total/passed
-        exs = sum(self.execcount_samples)
+        exs = self.exec_count
         if exs > 0:
             avg = total/exs
         else:
@@ -107,9 +109,9 @@
         return [total/(float(passed)/10**9), per, avg]
 
     def waited_stats(self, passed):
-        total = float(sum(self.waited_samples))
+        total = float(self.waited_sum)
         per = 100*total/passed
-        exs = sum(self.execcount_samples)
+        exs = self.exec_count
         if exs > 0:
             avg = total/exs
         else:
@@ -117,9 +119,9 @@
         return [total/(float(passed)/10**9), per, avg]
 
     def blocked_stats(self, passed):
-        total = float(sum(self.blocked_samples))
+        total = float(self.blocked_sum)
         per = 100*total/passed
-        ios = sum(self.iocount_samples)
+        ios = self.iocount_sum
         if ios > 0:
             avg = total/float(ios)
         else:
@@ -127,20 +129,20 @@
         return [total/(float(passed)/10**9), per, avg]
 
     def allocated_stats(self, passed):
-        total = sum(self.allocated_samples)
-        exs = sum(self.execcount_samples)
+        total = self.allocated_sum
+        exs = self.exec_count
         if exs > 0:
             return float(total)/exs
         else:
             return 0
 
     def ec_stats(self, passed):
-        total = float(sum(self.execcount_samples))/(float(passed)/10**9)
-        return total
+        total = float(self.exec_count/(float(passed)/10**9))
+       return total
 
     def io_stats(self, passed):
-        total = float(sum(self.iocount_samples))
-        exs = sum(self.execcount_samples)
+        total = float(self.iocount_sum)
+        exs = self.exec_count
         if exs > 0:
             avg = total/exs
         else:
@@ -165,12 +167,13 @@
     
     while passed < duration:
         for i in range(0, NDOMAINS):
-            dominfos[i].gotten_samples.append(samples[curid][0*NDOMAINS + i])
-            dominfos[i].allocated_samples.append(samples[curid][1*NDOMAINS + 
i])
-            dominfos[i].waited_samples.append(samples[curid][2*NDOMAINS + i])
-            dominfos[i].blocked_samples.append(samples[curid][3*NDOMAINS + i])
-            dominfos[i].execcount_samples.append(samples[curid][4*NDOMAINS + 
i])
-            dominfos[i].iocount_samples.append(samples[curid][5*NDOMAINS + i])
+            if dom_in_use[i]:
+                dominfos[i].gotten_sum += samples[curid][0*NDOMAINS + i]
+                dominfos[i].allocated_sum += samples[curid][1*NDOMAINS + i]
+                dominfos[i].waited_sum += samples[curid][2*NDOMAINS + i]
+                dominfos[i].blocked_sum += samples[curid][3*NDOMAINS + i]
+                dominfos[i].exec_count += samples[curid][4*NDOMAINS + i]
+                dominfos[i].iocount_sum += samples[curid][5*NDOMAINS + i]
     
         passed += samples[curid][6*NDOMAINS]
         lost_samples.append(samples[curid][6*NDOMAINS + 2])
@@ -187,7 +190,13 @@
 
     lostinfo = [min(lost_samples), sum(lost_samples), max(lost_samples)]
     ffpinfo = [min(ffp_samples), sum(ffp_samples), max(ffp_samples)]
-    ldoms = map(lambda x: dominfos[x].stats(passed), range(0, NDOMAINS))
+
+    ldoms = []
+    for x in range(0, NDOMAINS):
+        if dom_in_use[x]:
+            ldoms.append(dominfos[x].stats(passed))
+        else:
+            ldoms.append(0)
 
     return [ldoms, lostinfo, ffpinfo]
 
@@ -222,6 +231,7 @@
     cpu = 0          # cpu of interest to display data for
     ncpu = 1         # number of cpu's on this platform
     slen = 0         # size of shared data structure, incuding padding
+    global dom_in_use
     
     # mmap the (the first chunk of the) file
     shmf = open(SHM_FILE, "r+")
@@ -229,6 +239,7 @@
 
     samples = []
     doms = []
+    dom_in_use = []
 
     # initialize curses
     stdscr = _c.initscr()
@@ -238,9 +249,7 @@
     stdscr.keypad(1)
     stdscr.timeout(1000)
     [maxy, maxx] = stdscr.getmaxyx()
-
-    
-
+    
     # display in a loop
     while True:
 
@@ -264,6 +273,11 @@
                 len = struct.calcsize(ST_DOM_INFO)
                 dom = struct.unpack(ST_DOM_INFO, shm[idx:idx+len])
                 doms.append(dom)
+#              (last_update_time, start_time, runnable_start_time, 
blocked_start_time,
+#               ns_since_boot, ns_oncpu_since_boot, runnable_at_last_update,
+#               runnable, in_use, domid, name) = dom
+#              dom_in_use.append(in_use)
+                dom_in_use.append(dom[8])
                 idx += len
 
             len = struct.calcsize("4i")
@@ -293,6 +307,7 @@
         [h1, l1, f1] = summarize(startat, endat, 10**9, samples)
         [h2, l2, f2] = summarize(startat, endat, 10 * 10**9, samples)
 
+
         # the actual display code
         row = 0
         display(stdscr, row, 1, "CPU = %d" % cpu, _c.A_STANDOUT)
@@ -305,6 +320,9 @@
         total_h2_cpu = 0
 
         for dom in range(0, NDOMAINS):
+            if not dom_in_use[dom]:
+                continue
+
             if h1[dom][0][1] > 0 or dom == NDOMAINS - 1:
                 # display gotten
                 row += 1 
@@ -475,6 +493,7 @@
 
 def writelog():
     global options
+    global dom_in_use
 
     ncpu = 1        # number of cpu's
     slen = 0        # size of shared structure inc. padding
@@ -490,11 +509,13 @@
 
     while options.duration == 0 or interval < (options.duration * 1000):
         for cpuidx in range(0, ncpu):
+
             idx = cpuidx * slen      # offset needed in mmap file
 
 
             samples = []
             doms = []
+            dom_in_use = []
 
             for i in range(0, NSAMPLES):
                 len = struct.calcsize(ST_QDATA)
@@ -505,7 +526,11 @@
             for i in range(0, NDOMAINS):
                 len = struct.calcsize(ST_DOM_INFO)
                 dom = struct.unpack(ST_DOM_INFO, shm[idx:idx+len])
-                doms.append(dom)
+#                doms.append(dom)
+#              (last_update_time, start_time, runnable_start_time, 
blocked_start_time,
+#               ns_since_boot, ns_oncpu_since_boot, runnable_at_last_update,
+#               runnable, in_use, domid, name) = dom
+                dom_in_use.append(dom[8])
                 idx += len
 
             len = struct.calcsize("4i")
@@ -524,6 +549,8 @@
 
             [h1,l1, f1] = summarize(startat, endat, options.interval * 10**6, 
samples)
             for dom in range(0, NDOMAINS):
+                if not dom_in_use[dom]:
+                    continue
                 if h1[dom][0][1] > 0 or dom == NDOMAINS - 1:
                     outfiles[dom].write("%.3f %d %d %.3f %.3f %.3f %.3f %.3f 
%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n" %
                                      (interval, cpuidx, dom,
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c    Fri Dec  2 18:12:11 2005
+++ b/tools/xenstat/libxenstat/src/xenstat.c    Fri Dec  2 18:52:25 2005
@@ -702,19 +702,12 @@
 {
        char path[80];
        char *name;
-       struct xs_transaction_handle *xstranshandle;
 
        snprintf(path, sizeof(path),"/local/domain/%i/name", domain_id);
        
-       xstranshandle = xs_transaction_start(handle->xshandle);
-       if (xstranshandle == NULL) {
-               perror("Unable to get transcation handle from xenstore\n");
-               exit(1); /* Change this */
-       }
-
-       name = (char *) xs_read(handle->xshandle, xstranshandle, path, NULL);
-       
-       xs_transaction_end(handle->xshandle, xstranshandle, false);
+       name = xs_read(handle->xshandle, NULL, path, NULL);
+       if (name == NULL)
+               name = strdup(" ");
 
        return name;
 }      
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xenstore/fake_libxc.c
--- a/tools/xenstore/fake_libxc.c       Fri Dec  2 18:12:11 2005
+++ b/tools/xenstore/fake_libxc.c       Fri Dec  2 18:52:25 2005
@@ -34,7 +34,7 @@
 
 static int sigfd;
 static int xs_test_pid;
-static uint16_t port;
+static evtchn_port_t port;
 
 /* The event channel maps to a signal, shared page to an mmapped file. */
 void evtchn_notify(int local_port)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c  Fri Dec  2 18:12:11 2005
+++ b/tools/xenstore/xenstore_client.c  Fri Dec  2 18:52:25 2005
@@ -109,7 +109,7 @@
            necessary.
         */
 
-        char *path = argv[optind];
+        char *slash, *path = argv[optind];
 
         if (tidy) {
             /* Copy path, because we can't modify argv because we will need it
@@ -123,7 +123,7 @@
                 return 1;
             }
 
-            char *slash = strrchr(p, '/');
+            slash = strrchr(p, '/');
             if (slash) {
                 char *val;
                 *slash = '\0';
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Fri Dec  2 18:12:11 2005
+++ b/tools/xenstore/xenstored_core.c   Fri Dec  2 18:52:25 2005
@@ -1009,6 +1009,15 @@
 }
 
 
+static void internal_rm(const char *name)
+{
+       char *tname = talloc_strdup(talloc_autofree_context(), name);
+       struct node *node = read_node(NULL, tname);
+       if (node)
+               _rm(NULL, node, tname);
+}
+
+
 static void do_rm(struct connection *conn, const char *name)
 {
        struct node *node;
@@ -1417,7 +1426,24 @@
        tdbname = talloc_strdup(talloc_autofree_context(), xs_daemon_tdb());
        tdb_ctx = tdb_open(tdbname, 0, TDB_FLAGS, O_RDWR, 0);
 
-       if (!tdb_ctx) {
+       if (tdb_ctx) {
+               /* XXX When we make xenstored able to restart, this will have
+                  to become cleverer, checking for existing domains and not
+                  removing the corresponding entries, but for now xenstored
+                  cannot be restarted without losing all the registered
+                  watches, which breaks all the backend drivers anyway.  We
+                  can therefore get away with just clearing /local and
+                  expecting Xend to put the appropriate entries back in.
+
+                  When this change is made it is important to note that
+                  dom0's entries must be cleaned up on reboot _before_ this
+                  daemon starts, otherwise the backend drivers and dom0's
+                  balloon driver will pick up stale entries.  In the case of
+                  the balloon driver, this can be fatal.
+               */
+               internal_rm("/local");
+       }
+       else {
                tdb_ctx = tdb_open(tdbname, 7919, TDB_FLAGS, O_RDWR|O_CREAT,
                                   0640);
                if (!tdb_ctx)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Fri Dec  2 18:12:11 2005
+++ b/tools/xenstore/xenstored_domain.c Fri Dec  2 18:52:25 2005
@@ -41,7 +41,7 @@
 #include <xen/linux/evtchn.h>
 
 static int *xc_handle;
-static int virq_port;
+static evtchn_port_t virq_port;
 
 int eventchn_fd = -1; 
 
@@ -53,11 +53,11 @@
        unsigned int domid;
 
        /* Event channel port */
-       uint16_t port;
+       evtchn_port_t port;
 
        /* The remote end of the event channel, used only to validate
           repeated domain introductions. */
-       uint16_t remote_port;
+       evtchn_port_t remote_port;
 
        /* The mfn associated with the event channel, used only to validate
           repeated domain introductions. */
@@ -224,7 +224,7 @@
 /* We scan all domains rather than use the information given here. */
 void handle_event(void)
 {
-       uint16_t port;
+       evtchn_port_t port;
 
        if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
                barf_perror("Failed to read from event fd");
@@ -314,7 +314,7 @@
        char *vec[3];
        unsigned int domid;
        unsigned long mfn;
-       uint16_t port;
+       evtchn_port_t port;
 
        if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
                send_error(conn, EINVAL);
@@ -460,7 +460,8 @@
 
 static int dom0_init(void) 
 { 
-        int rc, fd, port; 
+        int rc, fd;
+       evtchn_port_t port; 
         unsigned long mfn; 
         char str[20]; 
         struct domain *dom0; 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/configure.ac
--- a/tools/xm-test/configure.ac        Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/configure.ac        Fri Dec  2 18:52:25 2005
@@ -35,6 +35,7 @@
     Makefile 
     ramdisk/Makefile
     tests/Makefile
+    tests/_sanity/Makefile
     tests/block-list/Makefile
     tests/block-create/Makefile
     tests/block-destroy/Makefile
@@ -50,6 +51,7 @@
     tests/memmax/Makefile
     tests/memset/Makefile
     tests/migrate/Makefile
+    tests/network-attach/Makefile
     tests/pause/Makefile
     tests/reboot/Makefile
     tests/restore/Makefile
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/lib/XmTestLib/Console.py
--- a/tools/xm-test/lib/XmTestLib/Console.py    Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/lib/XmTestLib/Console.py    Fri Dec  2 18:52:25 2005
@@ -66,37 +66,25 @@
         self.historySaveCmds  = historySaveCmds
         self.debugMe          = False
         self.limit            = None
-        self.delay            = 2
 
         consoleCmd = ["/usr/sbin/xm", "xm", "console", domain]
 
-        start = time.time()
-
-        while (time.time() - start) < self.TIMEOUT:
-            if verbose:
-                print "Console executing: %s" % str(consoleCmd)
-
-            pid, fd = pty.fork()
-
-            if pid == 0:
-                os.execvp("/usr/sbin/xm", consoleCmd[1:])
-
-            self.consolePid = pid
-            self.consoleFd  = fd
-
-            tty.setraw(self.consoleFd, termios.TCSANOW)
-            
-            bytes = self.__chewall(self.consoleFd)
-
-            if bytes > 0:
-                return
-
-            if verbose:
-                print "Console didn't attach, waiting %i sec..." % self.delay
-            time.sleep(self.delay)
-
-        raise ConsoleError("Console didn't respond after %i secs" % 
self.TIMEOUT)
-    
+        if verbose:
+            print "Console executing: %s" % str(consoleCmd)
+
+        pid, fd = pty.fork()
+
+        if pid == 0:
+            os.execvp("/usr/sbin/xm", consoleCmd[1:])
+
+        self.consolePid = pid
+        self.consoleFd  = fd
+
+        tty.setraw(self.consoleFd, termios.TCSANOW)
+
+        self.__chewall(self.consoleFd)
+
+
     def __addToHistory(self, line):
         self.historyBuffer.append(line)
         self.historyLines += 1
@@ -145,8 +133,8 @@
                     if self.debugMe:
                         sys.stdout.write(foo)
                     bytes += 1
-                except:
-                    timeout += 1
+                except Exception, exn:
+                    raise ConsoleError(str(exn))
 
             else:
                 timeout += 1
@@ -174,7 +162,7 @@
 
         os.write(self.consoleFd, "%s\n" % command)
 
-        while 1==1:
+        while True:
             i, o, e = select.select([self.consoleFd], [], [], self.TIMEOUT)
 
             if self.consoleFd in i:
@@ -183,9 +171,10 @@
                     if self.debugMe:
                         sys.stdout.write(str)
                     bytes += 1
-                except:
-                    raise ConsoleError("Failed to read from console (fd=%i)"
-                                       % self.consoleFd)
+                except Exception, exn:
+                    raise ConsoleError(
+                        "Failed to read from console (fd=%i): %s" %
+                        (self.consoleFd, exn))
             else:
                 raise ConsoleError("Timed out waiting for console")
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/lib/XmTestLib/Test.py
--- a/tools/xm-test/lib/XmTestLib/Test.py       Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/lib/XmTestLib/Test.py       Fri Dec  2 18:52:25 2005
@@ -161,6 +161,31 @@
     print "*** Test %s started at %s %s" % (name, t,
                                             time.tzname[time.daylight])
 
+#
+# Try to start a domain and attach a console to it to see if
+# the console system is working
+#
+def isConsoleDead():
+
+    from XmTestLib import XmTestDomain, DomainError, XmConsole, ConsoleError
+
+    domain = XmTestDomain()
+
+    try:
+        domain.start()
+        console = XmConsole(domain.getName())
+        console.runCmd("ls")
+    except DomainError, e:
+        return True
+    except ConsoleError, e:
+        domain.destroy()
+        return True
+
+    domain.destroy()
+
+    return False
+    
+
 if __name__ == "__main__":
 
     timeStamp()
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/lib/XmTestLib/XenDomain.py
--- a/tools/xm-test/lib/XmTestLib/XenDomain.py  Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/lib/XmTestLib/XenDomain.py  Fri Dec  2 18:52:25 2005
@@ -89,7 +89,7 @@
         ret, output = traceCommand(commandLine);
 
         try:
-            self.domID = int(domid(self.domName));
+            self.domID = self.getId()
         except:
             self.domID = -1;
 
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/lib/XmTestLib/Xm.py
--- a/tools/xm-test/lib/XmTestLib/Xm.py Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/lib/XmTestLib/Xm.py Fri Dec  2 18:52:25 2005
@@ -47,20 +47,13 @@
 def domid(name):
     status, output = traceCommand("xm domid " + name);
 
-    if re.search("Traceback", output):
-        print "*** xm domid failed with:"
-        print output
-        for i in range(0,10):
-            status, output = traceCommand("xm list")
-            status, output = traceCommand("xm domid " + name);
-            if not re.search("Traceback", output):
-                break
-        
+    if status != 0 or "Traceback" in output:
+        return -1
     try:
-        id = int(output);
+        return int(output)
     except:
-        id = -1;
-    return id;
+        raise XmError("xm domid failed", trace=output, status=status)
+
 
 def domname(id):
     status, output = traceCommand("xm domname " + str(id));
@@ -75,7 +68,7 @@
 
 def getRunningDomains():
     status, output = traceCommand("xm list");
-    if "Traceback" in output:
+    if status != 0 or "Traceback" in output:
         raise XmError("xm failed", trace=output, status=status)
     
     lines = output.splitlines();
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/lib/XmTestReport/OSReport.py
--- a/tools/xm-test/lib/XmTestReport/OSReport.py        Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/lib/XmTestReport/OSReport.py        Fri Dec  2 18:52:25 2005
@@ -97,7 +97,7 @@
                      "cores_per_socket" : "Unknown",
                      "threads_per_core" : "Unknown",
                      "cpu_mhz"          : "Unknown",
-                     "memory"           : "Unknown"}
+                     "total_memory"     : "Unknown"}
 
         xen = self.__getXenInfo(xenValues)
         cpu = self.__getCpuInfo(cpuValues)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/runtest.sh
--- a/tools/xm-test/runtest.sh  Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/runtest.sh  Fri Dec  2 18:52:25 2005
@@ -14,6 +14,7 @@
     echo "  -q          : run a quick test set"
     echo "  -e <email>  : set email address for report"
     echo "  -s <report> : just submit report <report>"
+    echo "  -h | --help : show this help"
 }
 
 # Just submit the report
@@ -83,6 +84,15 @@
     # See if xend is running
     if ! xm list >/dev/null 2>&1; then
        echo "'xm list' failed: is xend running?"
+       exit 1
+    fi
+
+    # Run a few sample tests to make sure things are working
+    # before we take the plunge
+    echo "Running sanity checks..."
+    make -C tests/_sanity check 2>&1 | grep REASON
+    if [ $? -eq 0 ]; then
+       echo "Sanity checks failed"
        exit 1
     fi
 
@@ -119,7 +129,7 @@
 # Run the tests
 run_tests() {
     output=$1
-    echo Running tests...
+    echo Running real tests...
     TEST_VERBOSE=1 make -k check > $output 2>&1
 }
 
@@ -209,6 +219,10 @@
       -s)
          run=no
          ;;
+      -h|--help)
+          usage
+          exit 0
+          ;;
       *)
          REPORT=$1
          break
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/tests/Makefile.am
--- a/tools/xm-test/tests/Makefile.am   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/Makefile.am   Fri Dec  2 18:52:25 2005
@@ -13,6 +13,7 @@
                list            \
                memmax          \
                memset          \
+               network-attach  \
                pause           \
                reboot          \
                sedf            \
@@ -24,15 +25,7 @@
                enforce_dom0_cpus       \
                save restore migrate
 
-DISABLED_TESTS = save  \
-               restore \
-               migrate
-
-TESTS =
-
-XFAIL_TESTS = 
-
-EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) $(SUBDIRS) $(DISABLED_TESTS) 
Makefile.am.template
+EXTRA_DIST = $(SUBDIRS) Makefile.am.template
 
 %.test: %.py
        cp $< $@
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/block-create/Makefile.am
--- a/tools/xm-test/tests/block-create/Makefile.am      Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/block-create/Makefile.am      Fri Dec  2 18:52:25 2005
@@ -8,9 +8,9 @@
        06_block_attach_baddomain_neg.test \
        07_block_attach_baddevice_neg.test \
        08_block_attach_bad_filedevice_neg.test \
-       09_block_attach_and_dettach_device_check_data_pos.test
-
-DISABLED = 
+       09_block_attach_and_dettach_device_check_data_pos.test \
+       11_block_attach_shared_dom0.test \
+       12_block_attach_shared_domU.test
 
 EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
 
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py
--- a/tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py Fri Dec 
 2 18:12:11 2005
+++ b/tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py Fri Dec 
 2 18:52:25 2005
@@ -16,8 +16,7 @@
 
 status, output = traceCommand("xm block-attach %s phy:/dev/ram0 hda1 w" % 
domain.getName())
 if status != 0:
-    # Disabled for now, since block-attach doesn't work
-    #FAIL("Failed to attach block device")
+    FAIL("Failed to attach block device")
     pass
 
 try:
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/block-destroy/Makefile.am
--- a/tools/xm-test/tests/block-destroy/Makefile.am     Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/block-destroy/Makefile.am     Fri Dec  2 18:52:25 2005
@@ -5,7 +5,8 @@
        02_block-destroy_rtblock_pos.test       \
        03_block-destroy_nonexist_neg.test      \
        04_block-destroy_nonattached_neg.test   \
-       05_block-destroy_byname_pos.test
+       05_block-destroy_byname_pos.test        \
+       06_block-destroy_check_list_pos.test
 
 XFAIL_TESTS = 
 
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py
--- a/tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py   Fri Dec 
 2 18:12:11 2005
+++ b/tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py   Fri Dec 
 2 18:52:25 2005
@@ -30,7 +30,7 @@
 s, o = traceCommand("xm block-list %s" % domain.getName())
 if s != 0:
     FAIL("block-list failed")
-if not o.find("769"):
+if o.find("769") == -1:
     FAIL("block-list didn't show the block device I just attached!")
 
 s, o = traceCommand("xm block-attach %s phy:/dev/ram1 hda2 w" % 
domain.getName())
@@ -40,25 +40,31 @@
 s, o = traceCommand("xm block-list %s" % domain.getName())
 if s != 0:
     FAIL("block-list failed")
-if not o.find("770"):
+if o.find("770") == -1:
     FAIL("block-list didn't show the other block device I just attached!")
 
 s, o = traceCommand("xm block-detach %s 769" % domain.getName())
 if s != 0:
-    FAIL("block-destroy of hda1 failed")
+    FAIL("block-detach of hda1 failed")
 
+time.sleep(1)
 s, o = traceCommand("xm block-list %s" % domain.getName())
 if s != 0:
     FAIL("block-list failed after detaching a device")
-if o.find("769"):
+if o.find("769") != -1:
     FAIL("hda1 still shown in block-list after detach!")
-if not o.find("770"):
+if o.find("770") == -1:
     FAIL("hda2 not shown after detach of hda1!")
 
 s, o = traceCommand("xm block-detach %s 770" % domain.getName())
 if s != 0:
+    FAIL("block-detach of hda2 failed")
+
+time.sleep(1)
+s, o = traceCommand("xm block-list %s" % domain.getName())
+if s != 0:
     FAIL("block-list failed after detaching another device")
-if o.find("770"):
+if o.find("770") != -1:
     FAIL("hda2 still shown in block-list after detach!")
 if o:
     FAIL("block-list still shows something after all devices detached!")
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/create/06_create_mem_neg.py
--- a/tools/xm-test/tests/create/06_create_mem_neg.py   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/create/06_create_mem_neg.py   Fri Dec  2 18:52:25 2005
@@ -31,6 +31,7 @@
 
 try:
     domain1.start()
+    eyecatcher1 = "Created"
 except DomainError, e:
     eyecatcher1 = "Fail"
 
@@ -41,7 +42,7 @@
 
 # Test 2: create a domain with mem>sys_mem
 
-mem = int(getInfo("free_memory"))
+mem = int(getInfo("total_memory"))
 extreme_mem = str(mem + 100)
 
 opts2=  {
@@ -56,6 +57,7 @@
 
 try:
     domain2.start()
+    eyecatcher2 = "Created"
 except DomainError, e:
     eyecatcher2 = "Fail"
 
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/create/14_create_blockroot_pos.py
--- a/tools/xm-test/tests/create/14_create_blockroot_pos.py     Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/create/14_create_blockroot_pos.py     Fri Dec  2 
18:52:25 2005
@@ -36,6 +36,10 @@
 
 try:
     console = XmConsole(domain.getName(), historySaveCmds=True)
+except ConsoleError, e:
+    FAIL(str(e))
+
+try:
 #    console.debugMe = True
     console.sendInput("foo")
     run = console.runCmd("ls")
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/create/15_create_smallmem_pos.py
--- a/tools/xm-test/tests/create/15_create_smallmem_pos.py      Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/create/15_create_smallmem_pos.py      Fri Dec  2 
18:52:25 2005
@@ -17,6 +17,7 @@
 
 try:
     console = XmConsole(domain.getName())
+    console.setLimit(65536)
     console.sendInput("input")
     console.runCmd("ls")
 except ConsoleError, e:
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/tests/create/Makefile.am
--- a/tools/xm-test/tests/create/Makefile.am    Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/create/Makefile.am    Fri Dec  2 18:52:25 2005
@@ -15,10 +15,6 @@
        14_create_blockroot_pos.test \
        15_create_smallmem_pos.test
 
-DISABLED_TESTS =       05_create_noroot_noram_neg.test 
-
-XFAIL_TESTS = 13_create_multinic_pos.test
-
 EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
 
 TESTS_ENVIRONMENT=@TENV@
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/info/02_info_compiledata_pos.py
--- a/tools/xm-test/tests/info/02_info_compiledata_pos.py       Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/info/02_info_compiledata_pos.py       Fri Dec  2 
18:52:25 2005
@@ -24,7 +24,7 @@
         map[pieces[0]] = pieces[1]
 
 for field in ["cores_per_socket", "threads_per_core", "cpu_mhz",
-              "memory", "free_memory", "xen_major", "xen_minor"]:
+              "total_memory", "free_memory", "xen_major", "xen_minor"]:
     val = map[field]
     if not val.isdigit():
         FAIL("Numeric field %s not all-numbers: %s" % (field, val))
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/memset/04_memset_smallmem_pos.py
--- a/tools/xm-test/tests/memset/04_memset_smallmem_pos.py      Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/memset/04_memset_smallmem_pos.py      Fri Dec  2 
18:52:25 2005
@@ -30,7 +30,7 @@
     FAIL("xm mem-set %s %i returned invalid %i != 0" %
          (domain.getName(), domain.minSafeMem(), status))
 
-console.setLimit(8192)
+console.setLimit(65536)
 
 try:
     # See if this hits the byte limit
@@ -39,13 +39,15 @@
     if e.reason == RUNAWAY:
         # Need to stop the domain before we restart the console daemon
         domain.destroy()
-        if verbose:
+        if isConsoleDead():
             print "*** Attempting restart of xenconsoled"
             s, o = traceCommand("killall xenconsoled")
             s, o = traceCommand("xenconsoled")
             if s != 0:
                 print "*** Starting xenconsoled failed: %i" % s
-        FAIL("Bug #380: I crashed the console system")
+            FAIL("Bug #380: I crashed the console system")
+        else:
+            FAIL("Bug #145: Ballooning DomU too low caused run-away")
     else:
         FAIL(str(e))
 
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/migrate/01_migrate_localhost_pos.py
--- a/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py   Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py   Fri Dec  2 
18:52:25 2005
@@ -38,8 +38,8 @@
 try:
     # Activate the console
     console.sendInput("foo")
-    # Make sure a command succeeds
-    run = console.runCmd("ls /bin")
+    # Set a variable to check on the other side
+    run = console.runCmd("foo=bar")
 except ConsoleError, e:
     FAIL(str(e))
 
@@ -66,18 +66,21 @@
 # Attach a console to it
 try:
     console = XmConsole(domain.getName(), historySaveCmds=True)
+    console.debugMe = True
 except ConsoleError, e:
     pass
+
+console.sendInput("ls")
 
 # Run 'ls'
 try:
     # Check the dmesg output on the domU
-    run = console.runCmd("ls /bin")
+    run = console.runCmd("echo xx$foo")
 except ConsoleError, e:
     FAIL(str(e))
-
-if not re.search("chmod", run["output"]):
-    FAIL("invalid console output from ls after migration")
+    
+if not re.search("bar", run["output"]):
+    FAIL("Migrated domain has been reset")
 
 # Close the console
 console.closeConsole()
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/restore/01_restore_basic_pos.py
--- a/tools/xm-test/tests/restore/01_restore_basic_pos.py       Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/restore/01_restore_basic_pos.py       Fri Dec  2 
18:52:25 2005
@@ -25,6 +25,8 @@
 # Make sure the domain isn't DOA
 try:
     console = XmConsole(domain.getName())
+    console.sendInput("input")
+    console.runCmd("foo=bar")
 except ConsoleError, e:
     FAIL(str(e))
 
@@ -63,6 +65,12 @@
 # Make sure it's alive
 try:
     newConsole = XmConsole(domain.getName())
+    # Enable debug dumping because this generates a Oops on x86_64
+    newConsole.debugMe = True
+    newConsole.sendInput("ls")
+    run = newConsole.runCmd("echo xx$foo")
+    if not re.search("bar", run["output"]):
+        FAIL("Restored domain has been reset")
 except ConsoleError, e:
     FAIL("Restored domain is dead (%s)" % str(e))
 
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/restore/04_restore_withdevices_pos.py
--- a/tools/xm-test/tests/restore/04_restore_withdevices_pos.py Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/restore/04_restore_withdevices_pos.py Fri Dec  2 
18:52:25 2005
@@ -90,6 +90,11 @@
 
 try:
     console = XmConsole(domain.getName())
+    # Enable debug dumping, as this causes an Oops on x86_64
+    console.debugMe = True
+
+    # In case the domain is rebooted
+    console.sendInput("ls")
 
     run = console.runCmd("ls | grep proc")
     if run["return"] != 0:
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/unpause/01_unpause_basic_pos.py
--- a/tools/xm-test/tests/unpause/01_unpause_basic_pos.py       Fri Dec  2 
18:12:11 2005
+++ b/tools/xm-test/tests/unpause/01_unpause_basic_pos.py       Fri Dec  2 
18:52:25 2005
@@ -70,12 +70,9 @@
 # Are we still alive after all that?
 try:
     console = XmConsole(domain.getName(), historySaveCmds=True)
+    run = console.runCmd("ls")
 except ConsoleError, e:
     FAIL(str(e))
-try:
-    run = console.runCmd("ls")
-except ConsoleError, e:
-    pass
 
 # Close the console
 console.closeConsole()
diff -r eae5812f33f1 -r 28bd01c9b596 xen/Makefile
--- a/xen/Makefile      Fri Dec  2 18:12:11 2005
+++ b/xen/Makefile      Fri Dec  2 18:52:25 2005
@@ -57,7 +57,7 @@
        $(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h
        $(MAKE) -C common
        $(MAKE) -C drivers
-ifneq ($(ACM_USE_SECURITY_POLICY),ACM_NULL_POLICY)
+ifeq ($(ACM_SECURITY),y)
        $(MAKE) -C acm
 endif
        $(MAKE) -C arch/$(TARGET_ARCH)
@@ -79,8 +79,8 @@
          echo " *"; \
          echo " */"; \
          echo ""; \
-         echo "#ifndef ACM_USE_SECURITY_POLICY"; \
-         echo "#define ACM_USE_SECURITY_POLICY $(ACM_USE_SECURITY_POLICY)"; \
+         echo "#ifndef ACM_DEFAULT_SECURITY_POLICY"; \
+         echo "#define ACM_DEFAULT_SECURITY_POLICY 
$(ACM_DEFAULT_SECURITY_POLICY)"; \
          echo "#endif") >$@
 
 # compile.h contains dynamic build info. Rebuilt on every 'make' invocation.
diff -r eae5812f33f1 -r 28bd01c9b596 xen/Rules.mk
--- a/xen/Rules.mk      Fri Dec  2 18:12:11 2005
+++ b/xen/Rules.mk      Fri Dec  2 18:52:25 2005
@@ -37,12 +37,11 @@
 ALL_OBJS := $(BASEDIR)/common/common.o
 ALL_OBJS += $(BASEDIR)/drivers/char/driver.o
 ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o
-ifneq ($(ACM_USE_SECURITY_POLICY),ACM_NULL_POLICY)
+ifeq ($(ACM_SECURITY),y)
 ALL_OBJS += $(BASEDIR)/acm/acm.o
+CFLAGS += -DACM_SECURITY
 endif
 ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o
-
-test-gcc-flag = $(shell $(CC) -v --help 2>&1 | grep -q " $(1) " && echo $(1))
 
 include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/acm/acm_core.c
--- a/xen/acm/acm_core.c        Fri Dec  2 18:12:11 2005
+++ b/xen/acm/acm_core.c        Fri Dec  2 18:52:25 2005
@@ -49,6 +49,9 @@
 extern struct acm_operations acm_chinesewall_ops, 
     acm_simple_type_enforcement_ops, acm_null_ops;
 
+/* global ACM policy  (now dynamically determined at boot time) */
+u16 acm_active_security_policy = ACM_POLICY_UNDEFINED;
+
 /* global ops structs called by the hooks */
 struct acm_operations *acm_primary_ops = NULL;
 /* called in hook if-and-only-if primary succeeds */
@@ -61,7 +64,8 @@
 
 /* until we have endian support in Xen, we discover it at runtime */
 u8 little_endian = 1;
-void acm_set_endian(void)
+void
+acm_set_endian(void)
 {
     u32 test = 1;
     if (*((u8 *)&test) == 1)
@@ -76,14 +80,82 @@
     }
 }
 
-/* initialize global security policy for Xen; policy write-locked already */
-static void
-acm_init_binary_policy(void *primary, void *secondary)
-{
-    acm_bin_pol.primary_policy_code = 0;
-    acm_bin_pol.secondary_policy_code = 0;
-    acm_bin_pol.primary_binary_policy = primary;
-    acm_bin_pol.secondary_binary_policy = secondary;
+int
+acm_init_binary_policy(u32 policy_code)
+{
+    int ret = ACM_OK;
+
+    acm_bin_pol.primary_policy_code = (policy_code & 0x0f);
+    acm_bin_pol.secondary_policy_code = (policy_code >> 4) & 0x0f;
+
+    write_lock(&acm_bin_pol_rwlock);
+
+    /* set primary policy component */
+    switch ((policy_code) & 0x0f)
+    {
+
+    case ACM_CHINESE_WALL_POLICY:
+        acm_init_chwall_policy();
+        acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
+        acm_primary_ops = &acm_chinesewall_ops;
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        acm_init_ste_policy();
+        acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+        acm_primary_ops = &acm_simple_type_enforcement_ops;
+        break;
+
+    case ACM_NULL_POLICY:
+        acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
+        acm_primary_ops = &acm_null_ops;
+        break;
+
+    default:
+        /* Unknown policy not allowed primary */
+        ret = -EINVAL;
+        goto out;
+    }
+
+    /* secondary policy component part */
+    switch ((policy_code) >> 4)
+    {
+
+    case ACM_NULL_POLICY:
+        acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+        acm_secondary_ops = &acm_null_ops;
+        break;
+
+    case ACM_CHINESE_WALL_POLICY:
+        if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY)
+        {   /* not a valid combination */
+            ret = -EINVAL;
+            goto out;
+        }
+        acm_init_chwall_policy();
+        acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY;
+        acm_secondary_ops = &acm_chinesewall_ops;
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        if (acm_bin_pol.primary_policy_code == 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+        {   /* not a valid combination */
+            ret = -EINVAL;
+            goto out;
+        }
+        acm_init_ste_policy();
+        acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+        acm_secondary_ops = &acm_simple_type_enforcement_ops;
+        break;
+
+    default:
+        ret = -EINVAL;
+        goto out;
+    }
+
+ out:
+    write_unlock(&acm_bin_pol_rwlock);
+    return ret;
 }
 
 static int
@@ -161,83 +233,35 @@
     int ret = ACM_OK;
 
     acm_set_endian();
-    write_lock(&acm_bin_pol_rwlock);
-    acm_init_binary_policy(NULL, NULL);
-
-    /* set primary policy component */
-    switch ((ACM_USE_SECURITY_POLICY) & 0x0f)
-    {
-
-    case ACM_CHINESE_WALL_POLICY:
-        acm_init_chwall_policy();
-        acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
-        acm_primary_ops = &acm_chinesewall_ops;
-        break;
-
-    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
-        acm_init_ste_policy();
-        acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
-        acm_primary_ops = &acm_simple_type_enforcement_ops;
-        break;
-
-    default:
-        /* NULL or Unknown policy not allowed primary;
-         * NULL/NULL will not compile this code */
+
+    /* first try to load the boot policy (uses its own locks) */
+    acm_setup(initrdidx, mbi, initial_images_start);
+
+    if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
+    {
+        printk("%s: Boot-Policy. Enforcing %s: Primary %s, Secondary %s.\n", 
__func__,
+               ACM_POLICY_NAME(acm_active_security_policy),
+               ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
+               ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
+        goto out;
+    }
+    /* else continue with the minimal hardcoded default startup policy */
+    printk("%s: Loading default policy (%s).\n",
+           __func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY));
+
+    if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) {
         ret = -EINVAL;
         goto out;
     }
-
-    /* secondary policy component part */
-    switch ((ACM_USE_SECURITY_POLICY) >> 4) {
-    case ACM_NULL_POLICY:
-        acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
-        acm_secondary_ops = &acm_null_ops;
-        break;
-
-    case ACM_CHINESE_WALL_POLICY:
-        if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY)
-        {   /* not a valid combination */
-            ret = -EINVAL;
-            goto out;
-        }
-        acm_init_chwall_policy();
-        acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY;
-        acm_secondary_ops = &acm_chinesewall_ops;
-        break;
-
-    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
-        if (acm_bin_pol.primary_policy_code == 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
-        {   /* not a valid combination */
-            ret = -EINVAL;
-            goto out;
-        }
-        acm_init_ste_policy();
-        acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
-        acm_secondary_ops = &acm_simple_type_enforcement_ops;
-        break;
-
-    default:
-        ret = -EINVAL;
-        goto out;
-    }
+    acm_active_security_policy = ACM_DEFAULT_SECURITY_POLICY;
 
  out:
-    write_unlock(&acm_bin_pol_rwlock);
-
     if (ret != ACM_OK)
     {
         printk("%s: Error initializing policies.\n", __func__);
         /* here one could imagine a clean panic */
         return -EINVAL;
     }
-    if (acm_setup(initrdidx, mbi, initial_images_start) != ACM_OK)
-    {
-        printk("%s: Error loading policy at boot time.\n", __func__);
-        /* ignore, just continue with the minimal hardcoded startup policy */
-    }
-    printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, 
-           ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
-           ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
     return ret;
 }
 
@@ -265,7 +289,7 @@
     ssid->primary_ssid   = NULL;
     ssid->secondary_ssid = NULL;
 
-    if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
+    if (acm_active_security_policy != ACM_NULL_POLICY)
         ssid->ssidref = ssidref;
     else
         ssid->ssidref = ACM_DEFAULT_SSID;
diff -r eae5812f33f1 -r 28bd01c9b596 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Fri Dec  2 18:12:11 2005
+++ b/xen/acm/acm_policy.c      Fri Dec  2 18:52:25 2005
@@ -56,17 +56,29 @@
     /* 2. some sanity checking */
     pol = (struct acm_policy_buffer *)policy_buffer;
 
-    if ((ntohl(pol->magic) != ACM_MAGIC) || 
-        (ntohl(pol->policy_version) != ACM_POLICY_VERSION) ||
-        (ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
+    if ((ntohl(pol->magic) != ACM_MAGIC) ||
+        (buf_size != ntohl(pol->len)) ||
+        (ntohl(pol->policy_version) != ACM_POLICY_VERSION))
+    {
+        printk("%s: ERROR in Magic, Version, or buf size.\n", __func__);
+        goto error_free;
+    }
+
+    if (acm_active_security_policy == ACM_POLICY_UNDEFINED) {
+        /* setup the policy with the boot policy */
+        if (acm_init_binary_policy((ntohl(pol->secondary_policy_code) << 4) |
+                                   ntohl(pol->primary_policy_code))) {
+            goto error_free;
+        }
+        acm_active_security_policy =
+            (acm_bin_pol.secondary_policy_code << 4) | 
acm_bin_pol.primary_policy_code;
+    }
+
+    /* once acm_active_security_policy is set, it cannot be changed */
+    if ((ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
         (ntohl(pol->secondary_policy_code) != 
acm_bin_pol.secondary_policy_code))
     {
-        printkd("%s: Wrong policy magics or versions!\n", __func__);
-        goto error_free;
-    }
-    if (buf_size != ntohl(pol->len))
-    {
-        printk("%s: ERROR in buf size.\n", __func__);
+        printkd("%s: Wrong policy type in boot policy!\n", __func__);
         goto error_free;
     }
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile    Fri Dec  2 18:12:11 2005
+++ b/xen/arch/ia64/Makefile    Fri Dec  2 18:52:25 2005
@@ -10,7 +10,7 @@
        extable.o linuxextable.o sort.o xenirq.o xentime.o \
        regionreg.o entry.o unaligned.o privop.o vcpu.o \
        irq_ia64.o irq_lsapic.o vhpt.o xenasm.o hyperprivop.o dom_fw.o \
-       grant_table.o sn_console.o # ia64_ksyms.o 
+       sn_console.o # ia64_ksyms.o 
 
 OBJS += vmx_init.o vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o\
        vmx_phy_mode.o vmx_utility.o vmx_interrupt.o vmx_entry.o vmmu.o \
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Fri Dec  2 18:12:11 2005
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Fri Dec  2 18:52:25 2005
@@ -198,7 +198,7 @@
     if (o_info) {
        memcpy((void*)d->shared_info, (void*)o_info, PAGE_SIZE);
        for_each_vcpu(d, v) {
-               v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
+               v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
        }
        /* If original page belongs to xen heap, then relinguish back
         * to xen heap. Or else, leave to domain itself to decide.
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Fri Dec  2 18:12:11 2005
+++ b/xen/arch/ia64/xen/domain.c        Fri Dec  2 18:52:25 2005
@@ -205,7 +205,7 @@
        printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs);
        memset(d->vcpu.arch.privregs, 0, PAGE_SIZE);
 #endif
-       v->vcpu_info = &(d->shared_info->vcpu_data[0]);
+       v->vcpu_info = &(d->shared_info->vcpu_info[0]);
 
        d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
 
@@ -867,7 +867,7 @@
 
        /* Mask all upcalls... */
        for ( i = 1; i < MAX_VIRT_CPUS; i++ )
-           d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+           d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
 #ifdef VALIDATE_VT 
        /* Construct a frame-allocation list for the initial domain, since these
@@ -997,7 +997,7 @@
 
        /* Mask all upcalls... */
        for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-               d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+               d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
        /* Copy the OS image. */
        printk("calling loaddomainelfimage(%p,%p)\n",d,image_start);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/acpi/boot.c
--- a/xen/arch/x86/acpi/boot.c  Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/acpi/boot.c  Fri Dec  2 18:52:25 2005
@@ -602,7 +602,8 @@
                error = acpi_parse_madt_lapic_entries();
                if (!error) {
                        acpi_lapic = 1;
-
+                       generic_bigsmp_probe();
+ 
                        /*
                         * Parse MADT IO-APIC entries
                         */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c      Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/audit.c      Fri Dec  2 18:52:25 2005
@@ -51,14 +51,38 @@
     int errors = 0;
     int shadow_refcounts = !!shadow_mode_refcounts(d);
     int shadow_enabled = !!shadow_mode_enabled(d);
-    int l2limit;
+
+    int l2limit( unsigned long mfn )
+    {
+
+        if ( shadow_mode_external(d) )
+            return L2_PAGETABLE_ENTRIES;
+
+#ifdef __i386__
+#ifdef CONFIG_X86_PAE
+        /* 32b PAE */
+        if ( (( frame_table[mfn].u.inuse.type_info & PGT_va_mask ) 
+           >> PGT_va_shift) == 3 )
+            return l2_table_offset(HYPERVISOR_VIRT_START); 
+        else
+            return L2_PAGETABLE_ENTRIES;
+#else
+        /* 32b non-PAE */
+        return DOMAIN_ENTRIES_PER_L2_PAGETABLE;
+#endif
+#else
+        /* 64b */
+        return 0; /* XXX x86/64 XXX */
+#endif
+    }
 
     void _adjust(struct pfn_info *page, int adjtype ADJUST_EXTRA_ARGS)
     {
+        int count;
+
         if ( adjtype )
         {
-            // adjust the type count
-            //
+            /* adjust the type count */
             int tcount = page->u.inuse.type_info & PGT_count_mask;
             tcount += dir;
             ttot++;
@@ -92,10 +116,8 @@
                 page->u.inuse.type_info += dir;
         }
 
-        // adjust the general count
-        //
-        int count = page->count_info & PGC_count_mask;
-        count += dir;
+        /* adjust the general count */
+        count = (page->count_info & PGC_count_mask) + dir;
         ctot++;
 
         if ( count < 0 )
@@ -122,14 +144,15 @@
 
     void adjust_l2_page(unsigned long mfn, int shadow)
     {
-        unsigned long *pt = map_domain_page(mfn);
+        l2_pgentry_t *pt = map_domain_page(mfn);
         int i;
-
-        for ( i = 0; i < l2limit; i++ )
-        {
-            if ( pt[i] & _PAGE_PRESENT )
-            {
-                unsigned long l1mfn = pt[i] >> PAGE_SHIFT;
+        u32 page_type;
+
+        for ( i = 0; i < l2limit(mfn); i++ )
+        {
+            if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT )
+            {
+               unsigned long l1mfn = l2e_get_pfn(pt[i]);
                 struct pfn_info *l1page = pfn_to_page(l1mfn);
 
                 if ( noisy )
@@ -147,8 +170,7 @@
                             continue;
                         }
 
-                        u32 page_type = l1page->u.inuse.type_info & 
PGT_type_mask;
-
+                        page_type = l1page->u.inuse.type_info & PGT_type_mask;
                         if ( page_type != PGT_l1_shadow )
                         {
                             printk("Audit %d: [Shadow L2 mfn=%lx i=%x] "
@@ -174,8 +196,7 @@
                             continue;
                         }
 
-                        u32 page_type = l1page->u.inuse.type_info & 
PGT_type_mask;
-
+                        page_type = l1page->u.inuse.type_info & PGT_type_mask;
                         if ( page_type == PGT_l2_page_table )
                         {
                             printk("Audit %d: [%x] Found %s Linear PT "
@@ -201,7 +222,7 @@
         if ( shadow_mode_translate(d) && !shadow_mode_external(d) )
         {
             unsigned long hl2mfn =
-                pt[l2_table_offset(LINEAR_PT_VIRT_START)] >> PAGE_SHIFT;
+                l2e_get_pfn(pt[l2_table_offset(LINEAR_PT_VIRT_START)]);
             struct pfn_info *hl2page = pfn_to_page(hl2mfn);
             adjust(hl2page, 0);
         }
@@ -211,14 +232,14 @@
 
     void adjust_hl2_page(unsigned long hl2mfn)
     {
-        unsigned long *pt = map_domain_page(hl2mfn);
+        l2_pgentry_t *pt = map_domain_page(hl2mfn);
         int i;
 
-        for ( i = 0; i < l2limit; i++ )
-        {
-            if ( pt[i] & _PAGE_PRESENT )
-            {
-                unsigned long gmfn = pt[i] >> PAGE_SHIFT;
+        for ( i = 0; i < l2limit(hl2mfn); i++ )
+        {
+            if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT )
+            {
+                unsigned long gmfn = l2e_get_pfn(pt[i]);
                 struct pfn_info *gpage = pfn_to_page(gmfn);
 
                 if ( gmfn < 0x100 )
@@ -258,14 +279,14 @@
 
     void adjust_l1_page(unsigned long l1mfn)
     {
-        unsigned long *pt = map_domain_page(l1mfn);
+        l1_pgentry_t *pt = map_domain_page(l1mfn);
         int i;
 
         for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
         {
-            if ( pt[i] & _PAGE_PRESENT )
-            {
-                unsigned long gmfn = pt[i] >> PAGE_SHIFT;
+            if ( l1e_get_flags(pt[i]) & _PAGE_PRESENT )
+            {
+                unsigned long gmfn = l1e_get_pfn(pt[i]);
                 struct pfn_info *gpage = pfn_to_page(gmfn);
 
                 if ( gmfn < 0x100 )
@@ -282,7 +303,7 @@
 
                 if ( noisy )
                 {
-                    if ( pt[i] & _PAGE_RW )
+                    if ( l1e_get_flags(pt[i]) & _PAGE_RW )
                     {
                         // If it's not a writable page, complain.
                         //
@@ -322,7 +343,7 @@
                     }
                 }
 
-                adjust(gpage, (pt[i] & _PAGE_RW) ? 1 : 0);
+                adjust(gpage, (l1e_get_flags(pt[i]) & _PAGE_RW) ? 1 : 0);
             }
         }
 
@@ -474,13 +495,6 @@
                             errors++;
                         }
 
-                        if ( (page->u.inuse.type_info & PGT_pinned) != 
PGT_pinned )
-                        {
-                            printk("Audit %d: L2 mfn=%lx not pinned t=%"
-                                  PRtype_info "\n",
-                                   d->domain_id, mfn, page->u.inuse.type_info);
-                            errors++;
-                        }
                     }
                 }
 
@@ -553,15 +567,6 @@
         }
     }
 
-#ifdef __i386__
-    if ( shadow_mode_external(d) )
-        l2limit = L2_PAGETABLE_ENTRIES;
-    else
-        l2limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
-#else
-    l2limit = 0; /* XXX x86/64 XXX */
-#endif
-
     adjust_for_pgtbase();
 
     adjust_guest_pages();
@@ -613,16 +618,17 @@
                              unsigned long mfn)
     {
         struct pfn_info *page = &frame_table[mfn];
-        unsigned long *pt = map_domain_page(mfn);
+        l1_pgentry_t *pt = map_domain_page(mfn);
         int i;
 
         for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
         {
-            if ( (pt[i] & _PAGE_PRESENT) && ((pt[i] >> PAGE_SHIFT) == xmfn) )
+            if ( (l1e_get_flags(pt[i]) & _PAGE_PRESENT) && 
+                 (l1e_get_pfn(pt[i]) == xmfn) )
                 printk("     found dom=%d mfn=%lx t=%" PRtype_info " c=%08x "
-                       "pt[i=%x]=%lx\n",
+                       "pt[i=%x]=%" PRIpte "\n",
                        d->domain_id, mfn, page->u.inuse.type_info,
-                       page->count_info, i, pt[i]);
+                       page->count_info, i, l1e_get_intpte(pt[i]));
         }
 
         unmap_domain_page(pt);           
@@ -741,6 +747,7 @@
     while ( list_ent != &d->page_list )
     {
         u32 page_type;
+        unsigned long pfn;
 
         page = list_entry(list_ent, struct pfn_info, list);
         mfn = page_to_pfn(page);
@@ -797,7 +804,7 @@
                 printk("out of sync page mfn=%lx is not a page table\n", mfn);
                 errors++;
             }
-            unsigned long pfn = __mfn_to_gpfn(d, mfn);
+            pfn = __mfn_to_gpfn(d, mfn);
             if ( !__shadow_status(d, pfn, PGT_snapshot) )
             {
                 printk("out of sync page mfn=%lx doesn't have a snapshot\n",
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/dm/i8259.c
--- a/xen/arch/x86/dm/i8259.c   Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/dm/i8259.c   Fri Dec  2 18:52:25 2005
@@ -31,7 +31,7 @@
 #include <xen/sched.h>
 #include <public/io/ioreq.h>
 #include <asm/vmx.h>
-#include <public/io/vmx_vpic.h>
+#include <asm/vmx_vpic.h>
 #include <asm/current.h>
 #include <asm/vmx_vioapic.h>
 #include <asm/vmx_vlapic.h>
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/dm/vmx_vioapic.c
--- a/xen/arch/x86/dm/vmx_vioapic.c     Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/dm/vmx_vioapic.c     Fri Dec  2 18:52:25 2005
@@ -39,7 +39,7 @@
 #include <xen/sched.h>
 #include <public/io/ioreq.h>
 #include <asm/vmx.h>
-#include <public/io/vmx_vpic.h>
+#include <asm/vmx_vpic.h>
 #include <asm/current.h>
 
 static void ioapic_enable(vmx_vioapic_t *s, uint8_t enable)
@@ -52,8 +52,6 @@
 
 static void ioapic_dump_redir(vmx_vioapic_t *s, uint8_t entry)
 {
-    ASSERT(s);
-
     RedirStatus redir = s->redirtbl[entry];
 
     VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_dump_redir "
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/dom0_ops.c   Fri Dec  2 18:52:25 2005
@@ -144,7 +144,7 @@
         unsigned int p;
 
         ret = -EINVAL;
-        if ( (fp + np) >= 65536 )
+        if ( (fp + np) > 65536 )
             break;
 
         ret = -ESRCH;
@@ -248,7 +248,7 @@
 
     case DOM0_GETPAGEFRAMEINFO2:
     {
-#define GPF2_BATCH 128
+#define GPF2_BATCH (PAGE_SIZE / sizeof(unsigned long)) 
         int n,j;
         int num = op->u.getpageframeinfo2.num;
         domid_t dom = op->u.getpageframeinfo2.domain;
@@ -285,12 +285,9 @@
                 struct pfn_info *page;
                 unsigned long mfn = l_arr[j];
 
-                if ( unlikely(mfn >= max_page) )
-                    goto e2_err;
-
                 page = &frame_table[mfn];
-  
-                if ( likely(get_page(page, d)) )
+
+                if ( likely(pfn_valid(mfn) && get_page(page, d)) ) 
                 {
                     unsigned long type = 0;
 
@@ -316,10 +313,7 @@
                     put_page(page);
                 }
                 else
-                {
-                e2_err:
                     l_arr[j] |= XTAB;
-                }
 
             }
 
@@ -329,7 +323,7 @@
                 break;
             }
 
-            n += j;
+            n += k;
         }
 
         free_xenheap_page(l_arr);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/domain.c     Fri Dec  2 18:52:25 2005
@@ -266,7 +266,7 @@
 
     d->shared_info = alloc_xenheap_page();
     memset(d->shared_info, 0, PAGE_SIZE);
-    v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
+    v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
     v->cpumap = CPUMAP_RUNANYWHERE;
     SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
 
@@ -413,9 +413,6 @@
         if ( !pagetable_get_paddr(d->arch.phys_table) )
             d->arch.phys_table = v->arch.guest_table;
         v->arch.guest_table = mk_pagetable(0);
-
-        /* Initialize monitor page table */
-        v->arch.monitor_table = mk_pagetable(0);
 
         vmx_final_setup_guest(v);
     }
@@ -960,8 +957,7 @@
 
     ptwr_destroy(d);
 
-    /* Release device mappings of other domains */
-    gnttab_release_dev_mappings(d->grant_table);
+    gnttab_release_mappings(d);
 
     /* Drop the in-use references to page-table bases. */
     for_each_vcpu ( d, v )
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/domain_build.c       Fri Dec  2 18:52:25 2005
@@ -597,7 +597,7 @@
 
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+        d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
     for ( i = 1; i < num_online_cpus(); i++ )
         (void)alloc_vcpu(d, i, i);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/genapic/bigsmp.c
--- a/xen/arch/x86/genapic/bigsmp.c     Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/genapic/bigsmp.c     Fri Dec  2 18:52:25 2005
@@ -45,7 +45,10 @@
 
 static __init int probe_bigsmp(void)
 { 
-       dmi_check_system(bigsmp_dmi_table);
+       if (def_to_bigsmp)
+               dmi_bigsmp = 1;
+       else
+               dmi_check_system(bigsmp_dmi_table);
        return dmi_bigsmp; 
 } 
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/genapic/probe.c
--- a/xen/arch/x86/genapic/probe.c      Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/genapic/probe.c      Fri Dec  2 18:52:25 2005
@@ -29,6 +29,25 @@
        NULL,
 };
 
+static int cmdline_apic;
+
+void __init generic_bigsmp_probe(void)
+{
+       /*
+        * This routine is used to switch to bigsmp mode when
+        * - There is no apic= option specified by the user
+        * - generic_apic_probe() has choosen apic_default as the sub_arch
+        * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
+        */
+
+       if (!cmdline_apic && genapic == &apic_default)
+               if (apic_bigsmp.probe()) {
+                       genapic = &apic_bigsmp;
+                       printk(KERN_INFO "Overriding APIC driver with %s\n",
+                              genapic->name);
+               }
+}
+
 static void __init genapic_apic_force(char *str)
 {
        int i;
@@ -41,7 +60,7 @@
 void __init generic_apic_probe(void) 
 { 
        int i;
-       int changed = (genapic != NULL);
+       int changed = cmdline_apic = (genapic != NULL);
 
        for (i = 0; !changed && apic_probe[i]; i++) { 
                if (apic_probe[i]->probe()) {
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/mm.c Fri Dec  2 18:52:25 2005
@@ -521,9 +521,9 @@
     l3_pgentry_t l3e, unsigned long pfn,
     struct domain *d, unsigned long vaddr)
 {
-    ASSERT( !shadow_mode_refcounts(d) );
-
     int rc;
+
+    ASSERT(!shadow_mode_refcounts(d));
 
     if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
         return 1;
@@ -594,23 +594,26 @@
         return;
 
     e = page_get_owner(page);
-    if ( unlikely(e != d) )
-    {
-        /*
-         * Unmap a foreign page that may have been mapped via a grant table.
-         * Note that this can fail for a privileged domain that can map foreign
-         * pages via MMUEXT_SET_FOREIGNDOM. Such domains can have some mappings
-         * counted via a grant entry and some counted directly in the page
-         * structure's reference count. Note that reference counts won't get
-         * dangerously confused as long as we always try to decrement the
-         * grant entry first. We may end up with a mismatch between which
-         * mappings and which unmappings are counted via the grant entry, but
-         * really it doesn't matter as privileged domains have carte blanche.
-         */
-        if (likely(gnttab_check_unmap(e, d, pfn,
-                                      !(l1e_get_flags(l1e) & _PAGE_RW))))
-            return;
-        /* Assume this mapping was made via MMUEXT_SET_FOREIGNDOM... */
+
+    /*
+     * Check if this is a mapping that was established via a grant reference.
+     * If it was then we should not be here: we require that such mappings are
+     * explicitly destroyed via the grant-table interface.
+     * 
+     * The upshot of this is that the guest can end up with active grants that
+     * it cannot destroy (because it no longer has a PTE to present to the
+     * grant-table interface). This can lead to subtle hard-to-catch bugs,
+     * hence a special grant PTE flag can be enabled to catch the bug early.
+     * 
+     * (Note that the undestroyable active grants are not a security hole in
+     * Xen. All active grants can safely be cleaned up when the domain dies.)
+     */
+    if ( (l1e_get_flags(l1e) & _PAGE_GNTTAB) &&
+         !(d->domain_flags & (DOMF_shutdown|DOMF_dying)) )
+    {
+        MEM_LOG("Attempt to implicitly unmap a granted PTE %" PRIpte,
+                l1e_get_intpte(l1e));
+        domain_crash(d);
     }
 
     if ( l1e_get_flags(l1e) & _PAGE_RW )
@@ -1286,6 +1289,11 @@
 
 int alloc_page_type(struct pfn_info *page, unsigned long type)
 {
+    struct domain *owner = page_get_owner(page);
+
+    if ( owner != NULL )
+        mark_dirty(owner, page_to_pfn(page));
+
     switch ( type & PGT_type_mask )
     {
     case PGT_l1_page_table:
@@ -1315,16 +1323,14 @@
     struct domain *owner = page_get_owner(page);
     unsigned long gpfn;
 
-    if ( owner != NULL )
-    {
+    if ( unlikely((owner != NULL) && shadow_mode_enabled(owner)) )
+    {
+        mark_dirty(owner, page_to_pfn(page));
         if ( unlikely(shadow_mode_refcounts(owner)) )
             return;
-        if ( unlikely(shadow_mode_enabled(owner)) )
-        {
-            gpfn = __mfn_to_gpfn(owner, page_to_pfn(page));
-            ASSERT(VALID_M2P(gpfn));
-            remove_shadow(owner, gpfn, type & PGT_type_mask);
-        }
+        gpfn = __mfn_to_gpfn(owner, page_to_pfn(page));
+        ASSERT(VALID_M2P(gpfn));
+        remove_shadow(owner, gpfn, type & PGT_type_mask);
     }
 
     switch ( type & PGT_type_mask )
@@ -1877,19 +1883,18 @@
 
         case MMUEXT_SET_LDT:
         {
+            unsigned long ptr  = op.arg1.linear_addr;
+            unsigned long ents = op.arg2.nr_ents;
+
             if ( shadow_mode_external(d) )
             {
                 MEM_LOG("ignoring SET_LDT hypercall from external "
                         "domain %u", d->domain_id);
                 okay = 0;
-                break;
             }
-
-            unsigned long ptr  = op.arg1.linear_addr;
-            unsigned long ents = op.arg2.nr_ents;
-            if ( ((ptr & (PAGE_SIZE-1)) != 0) || 
-                 (ents > 8192) ||
-                 !array_access_ok(ptr, ents, LDT_ENTRY_SIZE) )
+            else if ( ((ptr & (PAGE_SIZE-1)) != 0) || 
+                      (ents > 8192) ||
+                      !array_access_ok(ptr, ents, LDT_ENTRY_SIZE) )
             {
                 okay = 0;
                 MEM_LOG("Bad args to SET_LDT: ptr=%lx, ents=%lx", ptr, ents);
@@ -2201,8 +2206,7 @@
                     {
                         shadow_lock(d);
 
-                        if ( shadow_mode_log_dirty(d) )
-                            __mark_dirty(d, mfn);
+                        __mark_dirty(d, mfn);
 
                         if ( page_is_page_table(page) &&
                              !page_out_of_sync(page) )
@@ -2261,13 +2265,7 @@
             set_pfn_from_mfn(mfn, gpfn);
             okay = 1;
 
-            /*
-             * If in log-dirty mode, mark the corresponding
-             * page as dirty.
-             */
-            if ( unlikely(shadow_mode_log_dirty(FOREIGNDOM)) &&
-                 mark_dirty(FOREIGNDOM, mfn) )
-                FOREIGNDOM->arch.shadow_dirty_block_count++;
+            mark_dirty(FOREIGNDOM, mfn);
 
             put_page(&frame_table[mfn]);
             break;
@@ -2304,7 +2302,7 @@
 }
 
 
-int update_grant_pte_mapping(
+static int create_grant_pte_mapping(
     unsigned long pte_addr, l1_pgentry_t _nl1e, struct vcpu *v)
 {
     int rc = GNTST_okay;
@@ -2317,7 +2315,6 @@
 
     ASSERT(spin_is_locked(&d->big_lock));
     ASSERT(!shadow_mode_refcounts(d));
-    ASSERT((l1e_get_flags(_nl1e) & L1_DISALLOW_MASK) == 0);
 
     gpfn = pte_addr >> PAGE_SHIFT;
     mfn = __gpfn_to_mfn(d, gpfn);
@@ -2367,7 +2364,7 @@
     return rc;
 }
 
-int clear_grant_pte_mapping(
+static int destroy_grant_pte_mapping(
     unsigned long addr, unsigned long frame, struct domain *d)
 {
     int rc = GNTST_okay;
@@ -2444,7 +2441,7 @@
 }
 
 
-int update_grant_va_mapping(
+static int create_grant_va_mapping(
     unsigned long va, l1_pgentry_t _nl1e, struct vcpu *v)
 {
     l1_pgentry_t *pl1e, ol1e;
@@ -2452,7 +2449,6 @@
     
     ASSERT(spin_is_locked(&d->big_lock));
     ASSERT(!shadow_mode_refcounts(d));
-    ASSERT((l1e_get_flags(_nl1e) & L1_DISALLOW_MASK) == 0);
 
     /*
      * This is actually overkill - we don't need to sync the L1 itself,
@@ -2475,7 +2471,8 @@
     return GNTST_okay;
 }
 
-int clear_grant_va_mapping(unsigned long addr, unsigned long frame)
+static int destroy_grant_va_mapping(
+    unsigned long addr, unsigned long frame)
 {
     l1_pgentry_t *pl1e, ol1e;
     
@@ -2508,6 +2505,74 @@
     return 0;
 }
 
+int create_grant_host_mapping(
+    unsigned long addr, unsigned long frame, unsigned int flags)
+{
+    l1_pgentry_t pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS);
+        
+    if ( (flags & GNTMAP_application_map) )
+        l1e_add_flags(pte,_PAGE_USER);
+    if ( !(flags & GNTMAP_readonly) )
+        l1e_add_flags(pte,_PAGE_RW);
+
+    if ( flags & GNTMAP_contains_pte )
+        return create_grant_pte_mapping(addr, pte, current);
+    return create_grant_va_mapping(addr, pte, current);
+}
+
+int destroy_grant_host_mapping(
+    unsigned long addr, unsigned long frame, unsigned int flags)
+{
+    if ( flags & GNTMAP_contains_pte )
+        return destroy_grant_pte_mapping(addr, frame, current->domain);
+    return destroy_grant_va_mapping(addr, frame);
+}
+
+int steal_page_for_grant_transfer(
+    struct domain *d, struct pfn_info *page)
+{
+    u32 _d, _nd, x, y;
+
+    spin_lock(&d->page_alloc_lock);
+
+    /*
+     * The tricky bit: atomically release ownership while there is just one 
+     * benign reference to the page (PGC_allocated). If that reference 
+     * disappears then the deallocation routine will safely spin.
+     */
+    _d  = pickle_domptr(d);
+    _nd = page->u.inuse._domain;
+    y   = page->count_info;
+    do {
+        x = y;
+        if (unlikely((x & (PGC_count_mask|PGC_allocated)) !=
+                     (1 | PGC_allocated)) || unlikely(_nd != _d)) { 
+            DPRINTK("gnttab_transfer: Bad page %p: ed=%p(%u), sd=%p,"
+                    " caf=%08x, taf=%" PRtype_info "\n", 
+                    (void *) page_to_pfn(page),
+                    d, d->domain_id, unpickle_domptr(_nd), x, 
+                    page->u.inuse.type_info);
+            spin_unlock(&d->page_alloc_lock);
+            return -1;
+        }
+        __asm__ __volatile__(
+            LOCK_PREFIX "cmpxchg8b %2"
+            : "=d" (_nd), "=a" (y),
+            "=m" (*(volatile u64 *)(&page->count_info))
+            : "0" (_d), "1" (x), "c" (NULL), "b" (x) );
+    } while (unlikely(_nd != _d) || unlikely(y != x));
+
+    /*
+     * Unlink from 'd'. At least one reference remains (now anonymous), so 
+     * noone else is spinning to try to delete this page from 'd'.
+     */
+    d->tot_pages--;
+    list_del(&page->list);
+
+    spin_unlock(&d->page_alloc_lock);
+
+    return 0;
+}
 
 int do_update_va_mapping(unsigned long va, u64 val64,
                          unsigned long flags)
@@ -2772,8 +2837,7 @@
     {
         shadow_lock(dom);
 
-        if ( shadow_mode_log_dirty(dom) )
-            __mark_dirty(dom, mfn);
+        __mark_dirty(dom, mfn);
 
         if ( page_is_page_table(page) && !page_out_of_sync(page) )
             shadow_mark_mfn_out_of_sync(current, gpfn, mfn);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/mpparse.c
--- a/xen/arch/x86/mpparse.c    Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/mpparse.c    Fri Dec  2 18:52:25 2005
@@ -62,6 +62,8 @@
 
 int pic_mode;
 unsigned long mp_lapic_addr;
+
+unsigned int def_to_bigsmp;
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
@@ -213,6 +215,13 @@
                ver = 0x10;
        }
        apic_version[m->mpc_apicid] = ver;
+       if ((num_processors > 8) &&
+           APIC_XAPIC(ver) &&
+           (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+               def_to_bigsmp = 1;
+       else
+               def_to_bigsmp = 0;
+
        bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
 }
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/setup.c      Fri Dec  2 18:52:25 2005
@@ -432,7 +432,7 @@
 
     BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
     BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
-    BUG_ON(sizeof(vcpu_info_t) != (sizeof(unsigned long) * 4));
+    BUG_ON(sizeof(vcpu_info_t) != 64);
 
     init_frametable();
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/shadow.c     Fri Dec  2 18:52:25 2005
@@ -47,13 +47,14 @@
 #if CONFIG_PAGING_LEVELS == 3
 static unsigned long shadow_l3_table(
     struct domain *d, unsigned long gpfn, unsigned long gmfn);
-static inline void validate_bl2e_change( struct domain *d,
-    guest_root_pgentry_t *new_gle_p, pgentry_64_t *shadow_l3, int index);
 #endif
 
 #if CONFIG_PAGING_LEVELS == 4
 static unsigned long shadow_l4_table(
     struct domain *d, unsigned long gpfn, unsigned long gmfn);
+#endif
+
+#if CONFIG_PAGING_LEVELS >= 3
 static void shadow_map_into_current(struct vcpu *v,
     unsigned long va, unsigned int from, unsigned int to);
 static inline void validate_bl2e_change( struct domain *d,
@@ -206,6 +207,7 @@
     struct pfn_info *page;
     unsigned long smfn;
     int pin = 0;
+    void *l1, *lp;
 
     // Currently, we only keep pre-zero'ed pages around for use as L1's...
     // This will change.  Soon.
@@ -231,19 +233,19 @@
                 if (!page)
                     goto no_shadow_page;
 
-                void *l1_0 = map_domain_page(page_to_pfn(page));
-                memset(l1_0, 0, PAGE_SIZE);
-                unmap_domain_page(l1_0);
-
-                void *l1_1 = map_domain_page(page_to_pfn(page+1));
-                memset(l1_1, 0, PAGE_SIZE);
-                unmap_domain_page(l1_1);
+                l1 = map_domain_page(page_to_pfn(page));
+                memset(l1, 0, PAGE_SIZE);
+                unmap_domain_page(l1);
+
+                l1 = map_domain_page(page_to_pfn(page+1));
+                memset(l1, 0, PAGE_SIZE);
+                unmap_domain_page(l1);
 #else
                 page = alloc_domheap_page(NULL);
                 if (!page)
                     goto no_shadow_page;
 
-                void *l1 = map_domain_page(page_to_pfn(page));
+                l1 = map_domain_page(page_to_pfn(page));
                 memset(l1, 0, PAGE_SIZE);
                 unmap_domain_page(l1);
 #endif
@@ -254,7 +256,7 @@
                 if (!page)
                     goto no_shadow_page;
 
-                void *l1 = map_domain_page(page_to_pfn(page));
+                l1 = map_domain_page(page_to_pfn(page));
                 memset(l1, 0, PAGE_SIZE);
                 unmap_domain_page(l1);
             }
@@ -278,7 +280,7 @@
         if (!page)
             goto no_shadow_page;
 
-        void *lp = map_domain_page(page_to_pfn(page));
+        lp = map_domain_page(page_to_pfn(page));
         memset(lp, 0, PAGE_SIZE);
         unmap_domain_page(lp);
     }
@@ -587,9 +589,11 @@
     }
 
 #ifndef NDEBUG
-    l2_pgentry_t old_sl2e;
-    __shadow_get_l2e(v, va, &old_sl2e);
-    ASSERT( !(l2e_get_flags(old_sl2e) & _PAGE_PRESENT) );
+    {
+        l2_pgentry_t old_sl2e;
+        __shadow_get_l2e(v, va, &old_sl2e);
+        ASSERT(!(l2e_get_flags(old_sl2e) & _PAGE_PRESENT));
+    }
 #endif
 
 #if CONFIG_PAGING_LEVELS >=3
@@ -669,6 +673,7 @@
     }
 }
 
+#if CONFIG_PAGING_LEVELS == 2
 static void
 shadow_set_l1e(unsigned long va, l1_pgentry_t new_spte, int create_l1_shadow)
 {
@@ -750,7 +755,6 @@
     shadow_update_min_max(l2e_get_pfn(sl2e), l1_table_offset(va));
 }
 
-#if CONFIG_PAGING_LEVELS == 2
 static void shadow_invlpg_32(struct vcpu *v, unsigned long va)
 {
     struct domain *d = v->domain;
@@ -781,6 +785,73 @@
 }
 #endif /* CONFIG_PAGING_LEVELS == 2 */
 
+#if CONFIG_PAGING_LEVELS >= 3
+static void shadow_set_l1e_64(
+    unsigned long va, pgentry_64_t *sl1e_p,
+    int create_l1_shadow)
+{
+    struct vcpu *v = current;
+    struct domain *d = v->domain;
+    pgentry_64_t sle;
+    pgentry_64_t sle_up = {0};
+    l1_pgentry_t old_spte;
+    l1_pgentry_t sl1e = *(l1_pgentry_t *)sl1e_p;
+    int i;
+    unsigned long orig_va = 0;
+
+    if ( d->arch.ops->guest_paging_levels == PAGING_L2 ) 
+    {
+        /* This is for 32-bit VMX guest on 64-bit host */
+        orig_va = va;
+        va = va & (~((1<<L2_PAGETABLE_SHIFT_32)-1));
+    }
+
+    for ( i = PAGING_L4; i >= PAGING_L2; i-- )
+    {
+        if ( !__rw_entry(v, va, &sle, SHADOW_ENTRY | GET_ENTRY | i) )
+        {
+            sl1e = l1e_empty();
+            goto out;
+        }
+        if ( !(entry_get_flags(sle) & _PAGE_PRESENT) )
+        {
+            if ( create_l1_shadow )
+            {
+                perfc_incrc(shadow_set_l3e_force_map);
+                shadow_map_into_current(v, va, i-1, i);
+                __rw_entry(v, va, &sle, SHADOW_ENTRY | GET_ENTRY | i);
+            }
+        }
+        if ( i < PAGING_L4 )
+            shadow_update_min_max(entry_get_pfn(sle_up), table_offset_64(va, 
i));
+        sle_up = sle;
+    }
+
+    if ( d->arch.ops->guest_paging_levels == PAGING_L2 )
+    {
+        va = orig_va;
+    }
+
+    if ( shadow_mode_refcounts(d) )
+    {
+        __shadow_get_l1e(v, va, &old_spte);
+        if ( l1e_has_changed(old_spte, sl1e, _PAGE_RW | _PAGE_PRESENT) )
+        {
+            if ( (l1e_get_flags(sl1e) & _PAGE_PRESENT) &&
+                 !shadow_get_page_from_l1e(sl1e, d) )
+                sl1e = l1e_empty();
+            if ( l1e_get_flags(old_spte) & _PAGE_PRESENT )
+                put_page_from_l1e(old_spte, d);
+        }
+    }
+
+out:
+    __shadow_set_l1e(v, va, &sl1e);
+
+    shadow_update_min_max(entry_get_pfn(sle_up), guest_l1_table_offset(va));
+}
+#endif /* CONFIG_PAGING_LEVELS >= 3 */
+
 static struct out_of_sync_entry *
 shadow_alloc_oos_entry(struct domain *d)
 {
@@ -884,14 +955,16 @@
     ASSERT(pfn_valid(mfn));
 
 #ifndef NDEBUG
-    u32 type = page->u.inuse.type_info & PGT_type_mask;
-    if ( shadow_mode_refcounts(d) )
-    {
-        ASSERT(type == PGT_writable_page);
-    }
-    else
-    {
-        ASSERT(type && (type < PGT_l4_page_table));
+    {
+        u32 type = page->u.inuse.type_info & PGT_type_mask;
+        if ( shadow_mode_refcounts(d) )
+        {
+            ASSERT(type == PGT_writable_page);
+        }
+        else
+        {
+            ASSERT(type && (type < PGT_l4_page_table));
+        }
     }
 #endif
 
@@ -1002,8 +1075,8 @@
     entry->next = d->arch.out_of_sync;
     d->arch.out_of_sync = entry;
 
-    FSH_LOG("mark_out_of_sync(va=%lx -> writable_pl1e=%lx)",
-            va, entry->writable_pl1e);
+    FSH_LOG("%s(va=%lx -> writable_pl1e=%lx)",
+            __func__, va, entry->writable_pl1e);
 }
 
 /*
@@ -1260,7 +1333,7 @@
         i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask)
             >> PGT_va_shift;
 
-        if ( (i >= 0 && i <= L1_PAGETABLE_ENTRIES) &&
+        if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
              !l1e_has_changed(pt[i], match, flags) &&
              fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) &&
              !prediction )
@@ -1370,6 +1443,8 @@
     int need_flush = 0, external = shadow_mode_external(d);
     int unshadow;
     int changed;
+    u32 min_max_shadow, min_max_snapshot;
+    int min_shadow, max_shadow, min_snapshot, max_snapshot;
 
     ASSERT(shadow_lock_is_acquired(d));
 
@@ -1398,7 +1473,7 @@
                 continue;
         }
 
-       FSH_LOG("resyncing t=%08x gpfn=%lx gmfn=%lx smfn=%lx snapshot_mfn=%lx",
+        FSH_LOG("resyncing t=%08x gpfn=%lx gmfn=%lx smfn=%lx snapshot_mfn=%lx",
                 stype, entry->gpfn, entry->gmfn, smfn, entry->snapshot_mfn);
 
         // Compare guest's new contents to its snapshot, validating
@@ -1414,16 +1489,16 @@
 
         unshadow = 0;
 
-        u32 min_max_shadow = pfn_to_page(smfn)->tlbflush_timestamp;
-        int min_shadow = SHADOW_MIN(min_max_shadow);
-        int max_shadow = SHADOW_MAX(min_max_shadow);
-
-        u32 min_max_snapshot =
-          pfn_to_page(entry->snapshot_mfn)->tlbflush_timestamp;
-        int min_snapshot = SHADOW_MIN(min_max_snapshot);
-        int max_snapshot = SHADOW_MAX(min_max_snapshot);
-
-        switch ( stype ) {
+        min_max_shadow = pfn_to_page(smfn)->tlbflush_timestamp;
+        min_shadow     = SHADOW_MIN(min_max_shadow);
+        max_shadow     = SHADOW_MAX(min_max_shadow);
+
+        min_max_snapshot= pfn_to_page(entry->snapshot_mfn)->tlbflush_timestamp;
+        min_snapshot    = SHADOW_MIN(min_max_snapshot);
+        max_snapshot    = SHADOW_MAX(min_max_snapshot);
+
+        switch ( stype )
+        {
         case PGT_l1_shadow:
         {
             guest_l1_pgentry_t *guest1 = guest;
@@ -1468,12 +1543,13 @@
             perfc_incr_histo(l1_entries_checked, max_shadow - min_shadow + 1, 
PT_UPDATES);
             if ( d->arch.ops->guest_paging_levels >= PAGING_L3 &&
                  unshadow_l1 ) {
-                pgentry_64_t l2e = {0};
+                pgentry_64_t l2e;
 
                 __shadow_get_l2e(entry->v, entry->va, &l2e);
 
                 if ( entry_get_flags(l2e) & _PAGE_PRESENT ) {
-                    entry_remove_flags(l2e, _PAGE_PRESENT);
+                    put_shadow_ref(entry_get_pfn(l2e));
+                    l2e = entry_empty();
                     __shadow_set_l2e(entry->v, entry->va, &l2e);
 
                     if (entry->v == current)
@@ -1611,9 +1687,9 @@
             changed = 0;
             for ( i = 0; i < GUEST_ROOT_PAGETABLE_ENTRIES; i++ )
             {
+                guest_root_pgentry_t new_root_e = guest_root[i];
                 if ( !is_guest_l4_slot(i) && !external )
                     continue;
-                guest_root_pgentry_t new_root_e = guest_root[i];
                 if ( root_entry_has_changed(
                         new_root_e, snapshot_root[i], PAGE_FLAG_MASK))
                 {
@@ -1680,6 +1756,8 @@
 {
     struct out_of_sync_entry *entry;
     int need_flush = 0;
+    l1_pgentry_t *ppte, opte, npte;
+    cpumask_t other_vcpus_mask;
 
     perfc_incrc(shadow_sync_all);
 
@@ -1695,11 +1773,10 @@
         if ( entry->writable_pl1e & (sizeof(l1_pgentry_t)-1) )
             continue;
 
-        l1_pgentry_t *ppte = (l1_pgentry_t *)(
+        ppte = (l1_pgentry_t *)(
             (char *)map_domain_page(entry->writable_pl1e >> PAGE_SHIFT) +
             (entry->writable_pl1e & ~PAGE_MASK));
-        l1_pgentry_t opte = *ppte;
-        l1_pgentry_t npte = opte;
+        opte = npte = *ppte;
         l1e_remove_flags(npte, _PAGE_RW);
 
         if ( (l1e_get_flags(npte) & _PAGE_PRESENT) &&
@@ -1713,23 +1790,15 @@
         unmap_domain_page(ppte);
     }
 
-    // XXX mafetter: SMP
-    //
-    // With the current algorithm, we've gotta flush all the TLBs
-    // before we can safely continue.  I don't think we want to
-    // do it this way, so I think we should consider making
-    // entirely private copies of the shadow for each vcpu, and/or
-    // possibly having a mix of private and shared shadow state
-    // (any path from a PTE that grants write access to an out-of-sync
-    // page table page needs to be vcpu private).
-    //
-#if 0 // this should be enabled for SMP guests...
-    flush_tlb_mask(cpu_online_map);
-#endif
+    /* Other VCPUs mustn't use the revoked writable mappings. */
+    other_vcpus_mask = d->cpumask;
+    cpu_clear(smp_processor_id(), other_vcpus_mask);
+    flush_tlb_mask(other_vcpus_mask);
+
+    /* Flush ourself later. */
     need_flush = 1;
 
-    // Second, resync all L1 pages, then L2 pages, etc...
-    //
+    /* Second, resync all L1 pages, then L2 pages, etc... */
     need_flush |= resync_all(d, PGT_l1_shadow);
 
 #if CONFIG_PAGING_LEVELS == 2
@@ -1782,8 +1851,7 @@
     SH_VVLOG("l1pte_write_fault: updating spte=0x%" PRIpte " gpte=0x%" PRIpte,
              l1e_get_intpte(spte), l1e_get_intpte(gpte));
 
-    if ( shadow_mode_log_dirty(d) )
-        __mark_dirty(d, gmfn);
+    __mark_dirty(d, gmfn);
 
     if ( mfn_is_page_table(gmfn) )
         shadow_mark_va_out_of_sync(v, gpfn, gmfn, va);
@@ -1945,9 +2013,7 @@
             domain_crash_synchronous();
         }
 
-        // if necessary, record the page table page as dirty
-        if ( unlikely(shadow_mode_log_dirty(d)) )
-            __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
+        __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
     }
 
     shadow_set_l1e(va, spte, 1);
@@ -1996,15 +2062,17 @@
     __shadow_sync_va(v, va);
 
     l1pte_propagate_from_guest(d, *(guest_l1_pgentry_t *)&val, &spte);
+#if CONFIG_PAGING_LEVELS == 2
     shadow_set_l1e(va, spte, 0);
-
+#elif CONFIG_PAGING_LEVELS >= 3
+    shadow_set_l1e_64(va, (pgentry_64_t *) &spte, 0);
+#endif
     /*
      * If we're in log-dirty mode then we need to note that we've updated
      * the PTE in the PT-holding page. We need the machine frame number
      * for this.
      */
-    if ( shadow_mode_log_dirty(d) )
-        __mark_dirty(d, va_to_l1mfn(v, va));
+    __mark_dirty(d, va_to_l1mfn(v, va));
 
     shadow_unlock(d);
 
@@ -2086,7 +2154,8 @@
 #elif CONFIG_PAGING_LEVELS == 4
         smfn = shadow_l4_table(d, gpfn, gmfn);
 #endif
-    }
+    }else
+        shadow_sync_all(d);
     if ( !get_shadow_ref(smfn) )
         BUG();
     old_smfn = pagetable_get_pfn(v->arch.shadow_table);
@@ -2681,10 +2750,10 @@
                     g2mfn, g2mfn);
                 BUG(); /* XXX Deal gracefully with failure. */
             }
-
-            if (!get_shadow_ref(s2mfn))
-                BUG();
         } 
+
+        if (!get_shadow_ref(s2mfn))
+            BUG();
             
         /* Map shadow L2 into shadow L3 */
         spl3e[L3_PAGETABLE_ENTRIES - 1] = l3e_from_pfn(s2mfn, _PAGE_PRESENT);
@@ -2749,6 +2818,7 @@
     unsigned int count;
     unsigned long sl2mfn;
     struct pfn_info *page;
+    void *l2;
 
     memset(spl4e, 0, PAGE_SIZE);
 
@@ -2763,7 +2833,7 @@
     for (count = 0; count < PDP_ENTRIES; count++)
     {
         sl2mfn = page_to_pfn(page+count);
-        void *l2 = map_domain_page(sl2mfn);
+        l2 = map_domain_page(sl2mfn);
         memset(l2, 0, PAGE_SIZE);
         unmap_domain_page(l2);
         spl4e[count] = l4e_from_pfn(sl2mfn, _PAGE_PRESENT);
@@ -3012,71 +3082,6 @@
 }
 
 
-static void shadow_set_l1e_64(
-    unsigned long va, pgentry_64_t *sl1e_p,
-    int create_l1_shadow)
-{
-    struct vcpu *v = current;
-    struct domain *d = v->domain;
-    pgentry_64_t sle;
-    pgentry_64_t sle_up = {0};
-    l1_pgentry_t old_spte;
-    l1_pgentry_t sl1e = *(l1_pgentry_t *)sl1e_p;
-    int i;
-    unsigned long orig_va = 0;
-
-    if ( d->arch.ops->guest_paging_levels == PAGING_L2 ) 
-    {
-        /* This is for 32-bit VMX guest on 64-bit host */
-        orig_va = va;
-        va = va & (~((1<<L2_PAGETABLE_SHIFT_32)-1));
-    }
-
-    for (i = PAGING_L4; i >= PAGING_L2; i--) 
-    {
-        if (!__rw_entry(v, va, &sle, SHADOW_ENTRY | GET_ENTRY | i)) {
-            printk("<%s> i = %d\n", __func__, i);
-            BUG();
-        }
-        if ( !(entry_get_flags(sle) & _PAGE_PRESENT) ) {
-            if ( create_l1_shadow ) {
-                perfc_incrc(shadow_set_l3e_force_map);
-                shadow_map_into_current(v, va, i-1, i);
-                __rw_entry(v, va, &sle, SHADOW_ENTRY | GET_ENTRY | i);
-            } else {
-#if 0
-                printk("For non VMX shadow, create_l1_shadow:%d\n", 
create_l1_shadow);
-#endif
-            }
-        }
-        if( i < PAGING_L4 )
-            shadow_update_min_max(entry_get_pfn(sle_up), table_offset_64(va, 
i));
-        sle_up = sle;
-    }
-
-    if ( d->arch.ops->guest_paging_levels == PAGING_L2 ) {
-        va = orig_va;
-    }
-
-    if ( shadow_mode_refcounts(d) )
-    {
-        __shadow_get_l1e(v, va, &old_spte);
-        ESH_LOG("old_sl1e: %lx, new_sl1e: %lx\n", l1e_get_intpte(old_spte), 
l1e_get_intpte(sl1e));
-        if ( l1e_has_changed(old_spte, sl1e, _PAGE_RW | _PAGE_PRESENT) )
-            {
-                if ( (l1e_get_flags(sl1e) & _PAGE_PRESENT) &&
-                     !shadow_get_page_from_l1e(sl1e, d) )
-                    sl1e = l1e_empty();
-                if ( l1e_get_flags(old_spte) & _PAGE_PRESENT )
-                    put_page_from_l1e(old_spte, d);
-            }
-    }
-
-    __shadow_set_l1e(v, va, &sl1e);
-
-    shadow_update_min_max(entry_get_pfn(sle_up), guest_l1_table_offset(va));
-}
-
 /* As 32-bit guest don't support 4M page yet,
  * we don't concern double compile for this function
  */
@@ -3174,11 +3179,7 @@
                 l1e_remove_flags(sl1e, _PAGE_RW);
             }
         } else {
-            /* log dirty*/
-            /*
-               if ( shadow_mode_log_dirty(d) )
-               __mark_dirty(d, gmfn);
-             */
+            /* __mark_dirty(d, gmfn); */
         }
        // printk("<%s> gpfn: %lx, mfn: %lx, sl1e: %lx\n", __func__, gpfn, mfn, 
l1e_get_intpte(sl1e));
         /* The shadow entrys need setup before shadow_mark_va_out_of_sync()*/
@@ -3461,9 +3462,7 @@
         if (unlikely(!__guest_set_l1e(v, va, &gl1e))) 
             domain_crash_synchronous();
 
-        // if necessary, record the page table page as dirty
-        if ( unlikely(shadow_mode_log_dirty(d)) )
-            __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gl2e)));
+        __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gl2e)));
     }
 
     shadow_set_l1e_64(va, (pgentry_64_t *)&sl1e, 1);
@@ -3527,10 +3526,11 @@
 
     shadow_lock(d);
 
+    __shadow_sync_va(v, va);
+
     if ( __shadow_get_l1e(v, va, &old_sl1e) )
         if ( l1e_get_flags(old_sl1e) & _PAGE_PRESENT )
-            put_page_from_l1e(old_sl1e, d);
-
+            shadow_put_page_from_l1e(old_sl1e, d);
 
     sl1e = l1e_empty();
     __shadow_set_l1e(v, va, &sl1e);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/shadow32.c   Fri Dec  2 18:52:25 2005
@@ -208,6 +208,7 @@
     struct pfn_info *page;
     unsigned long smfn;
     int pin = 0;
+    void *l1;
 
     // Currently, we only keep pre-zero'ed pages around for use as L1's...
     // This will change.  Soon.
@@ -224,7 +225,7 @@
         else
         {
             page = alloc_domheap_page(NULL);
-            void *l1 = map_domain_page(page_to_pfn(page));
+            l1 = map_domain_page(page_to_pfn(page));
             memset(l1, 0, PAGE_SIZE);
             unmap_domain_page(l1);
         }
@@ -341,14 +342,10 @@
 
     SH_VVLOG("%s: smfn=%lx freed", __func__, smfn);
 
-#ifdef __i386__
     if ( shadow_mode_external(d) )
         limit = L2_PAGETABLE_ENTRIES;
     else
         limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
-#else
-    limit = 0; /* XXX x86/64 XXX */
-#endif
 
     for ( i = 0; i < limit; i++ )
     {
@@ -558,6 +555,7 @@
     int                   i;
     struct shadow_status *x;
     struct vcpu          *v;
+    struct list_head *list_ent, *tmp;
  
     /*
      * WARNING! The shadow page table must not currently be in use!
@@ -697,15 +695,14 @@
         xfree(mfn_list);
     }
 
-    // Now free the pre-zero'ed pages from the domain
-    //
-    struct list_head *list_ent, *tmp;
+    /* Now free the pre-zero'ed pages from the domain */
     list_for_each_safe(list_ent, tmp, &d->arch.free_shadow_frames)
     {
+        struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
+
         list_del(list_ent);
         perfc_decr(free_l1_pages);
 
-        struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
         free_domheap_page(page);
     }
 
@@ -739,11 +736,9 @@
     mpl2e = (l2_pgentry_t *)map_domain_page(mmfn);
     memset(mpl2e, 0, PAGE_SIZE);
 
-#ifdef __i386__ /* XXX screws x86/64 build */
     memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
            &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
            HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
-#endif
 
     mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
         l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
@@ -795,17 +790,12 @@
         put_shadow_ref(mfn);
     }
 
-    unmap_domain_page(mpl2e);
-
     /*
      * Then free monitor_table.
-     * Note: for VMX guest, only BSP need do this free.
      */
-    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
-        mfn = pagetable_get_pfn(v->arch.monitor_table);
-        unmap_domain_page(v->arch.monitor_vtable);
-        free_domheap_page(&frame_table[mfn]);
-    }
+    mfn = pagetable_get_pfn(v->arch.monitor_table);
+    unmap_domain_page(v->arch.monitor_vtable);
+    free_domheap_page(&frame_table[mfn]);
 
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
@@ -920,9 +910,9 @@
     struct vcpu *v;
     int new_modes = (mode & ~d->arch.shadow_mode);
 
-    // Gotta be adding something to call this function.
-    ASSERT(new_modes);
-
+    if(!new_modes) /* Nothing to do - return success */
+        return 0; 
+        
     // can't take anything away by calling this function.
     ASSERT(!(d->arch.shadow_mode & ~mode));
 
@@ -1037,36 +1027,41 @@
     //
     free_shadow_pages(d);
 
-    /*
-     * Tear down it's counts by disassembling its page-table-based ref counts.
-     * Also remove CR3's gcount/tcount.
-     * That leaves things like GDTs and LDTs and external refs in tact.
-     *
-     * Most pages will be writable tcount=0.
-     * Some will still be L1 tcount=0 or L2 tcount=0.
-     * Maybe some pages will be type none tcount=0.
-     * Pages granted external writable refs (via grant tables?) will
-     * still have a non-zero tcount.  That's OK.
-     *
-     * gcounts will generally be 1 for PGC_allocated.
-     * GDTs and LDTs will have additional gcounts.
-     * Any grant-table based refs will still be in the gcount.
-     *
-     * We attempt to grab writable refs to each page (thus setting its type).
-     * Immediately put back those type refs.
-     *
-     * Assert that no pages are left with L1/L2/L3/L4 type.
-     */
-    audit_adjust_pgtables(d, -1, 1);
-
     d->arch.shadow_mode = mode;
 
     if ( shadow_mode_refcounts(d) )
     {
-        struct list_head *list_ent = d->page_list.next;
-        while ( list_ent != &d->page_list )
-        {
-            struct pfn_info *page = list_entry(list_ent, struct pfn_info, 
list);
+        struct list_head *list_ent; 
+        struct pfn_info *page;
+
+        /*
+         * Tear down its counts by disassembling its page-table-based refcounts
+         * Also remove CR3's gcount/tcount.
+         * That leaves things like GDTs and LDTs and external refs in tact.
+         *
+         * Most pages will be writable tcount=0.
+         * Some will still be L1 tcount=0 or L2 tcount=0.
+         * Maybe some pages will be type none tcount=0.
+         * Pages granted external writable refs (via grant tables?) will
+         * still have a non-zero tcount.  That's OK.
+         *
+         * gcounts will generally be 1 for PGC_allocated.
+         * GDTs and LDTs will have additional gcounts.
+         * Any grant-table based refs will still be in the gcount.
+         *
+         * We attempt to grab writable refs to each page thus setting its type
+         * Immediately put back those type refs.
+         *
+         * Assert that no pages are left with L1/L2/L3/L4 type.
+         */
+        audit_adjust_pgtables(d, -1, 1);
+
+
+        for (list_ent = d->page_list.next; list_ent != &d->page_list; 
+             list_ent = page->list.next) {
+            
+            page = list_entry(list_ent, struct pfn_info, list);
+
             if ( !get_page_type(page, PGT_writable_page) )
                 BUG();
             put_page_type(page);
@@ -1074,13 +1069,13 @@
              * We use tlbflush_timestamp as back pointer to smfn, and need to
              * clean up it.
              */
-            if ( shadow_mode_external(d) )
+            if (shadow_mode_external(d))
                 page->tlbflush_timestamp = 0;
-            list_ent = page->list.next;
-        }
-    }
-
-    audit_adjust_pgtables(d, 1, 1);
+        }
+        
+        audit_adjust_pgtables(d, 1, 1);
+  
+    }
 
     return 0;
 
@@ -1218,6 +1213,11 @@
 
 void __shadow_mode_disable(struct domain *d)
 {
+    struct vcpu *v;
+#ifndef NDEBUG
+    int i;
+#endif
+
     if ( unlikely(!shadow_mode_enabled(d)) )
         return;
 
@@ -1225,7 +1225,6 @@
     free_writable_pte_predictions(d);
 
 #ifndef NDEBUG
-    int i;
     for ( i = 0; i < shadow_ht_buckets; i++ )
     {
         if ( d->arch.shadow_ht[i].gpfn_and_flags != 0 )
@@ -1242,11 +1241,8 @@
     free_shadow_ht_entries(d);
     free_out_of_sync_entries(d);
 
-    struct vcpu *v;
     for_each_vcpu(d, v)
-    {
         update_pagetables(v);
-    }
 }
 
 static int shadow_mode_table_op(
@@ -1272,8 +1268,6 @@
 
         d->arch.shadow_fault_count       = 0;
         d->arch.shadow_dirty_count       = 0;
-        d->arch.shadow_dirty_net_count   = 0;
-        d->arch.shadow_dirty_block_count = 0;
 
         break;
    
@@ -1282,13 +1276,9 @@
 
         sc->stats.fault_count       = d->arch.shadow_fault_count;
         sc->stats.dirty_count       = d->arch.shadow_dirty_count;
-        sc->stats.dirty_net_count   = d->arch.shadow_dirty_net_count;
-        sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
 
         d->arch.shadow_fault_count       = 0;
         d->arch.shadow_dirty_count       = 0;
-        d->arch.shadow_dirty_net_count   = 0;
-        d->arch.shadow_dirty_block_count = 0;
  
         if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
@@ -1325,9 +1315,6 @@
     case DOM0_SHADOW_CONTROL_OP_PEEK:
         sc->stats.fault_count       = d->arch.shadow_fault_count;
         sc->stats.dirty_count       = d->arch.shadow_dirty_count;
-        sc->stats.dirty_net_count   = d->arch.shadow_dirty_net_count;
-        sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
- 
 
         if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
@@ -1381,8 +1368,11 @@
     switch ( op )
     {
     case DOM0_SHADOW_CONTROL_OP_OFF:
-        __shadow_sync_all(d);
-        __shadow_mode_disable(d);
+        if ( shadow_mode_enabled(d) )
+        {
+            __shadow_sync_all(d);
+            __shadow_mode_disable(d);
+        }
         break;
 
     case DOM0_SHADOW_CONTROL_OP_ENABLE_TEST:
@@ -1418,36 +1408,40 @@
 }
 
 unsigned long
-gpfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
-{
-    ASSERT( shadow_mode_translate(d) );
-
-    perfc_incrc(gpfn_to_mfn_foreign);
-
-    unsigned long va = gpfn << PAGE_SHIFT;
-    unsigned long tabpfn = pagetable_get_pfn(d->arch.phys_table);
-    l2_pgentry_t *l2 = map_domain_page(tabpfn);
-    l2_pgentry_t l2e = l2[l2_table_offset(va)];
+get_mfn_from_pfn_foreign(struct domain *d, unsigned long gpfn)
+{
+    unsigned long va, tabpfn;
+    l1_pgentry_t *l1, l1e;
+    l2_pgentry_t *l2, l2e;
+
+    ASSERT(shadow_mode_translate(d));
+
+    perfc_incrc(get_mfn_from_pfn_foreign);
+
+    va = gpfn << PAGE_SHIFT;
+    tabpfn = pagetable_get_pfn(d->arch.phys_table);
+    l2 = map_domain_page(tabpfn);
+    l2e = l2[l2_table_offset(va)];
     unmap_domain_page(l2);
     if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
     {
-        printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte 
"\n",
-               d->domain_id, gpfn, l2e_get_intpte(l2e));
+        printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n",
+               __func__, d->domain_id, gpfn, l2e_get_intpte(l2e));
         return INVALID_MFN;
     }
-    l1_pgentry_t *l1 = map_domain_page(l2e_get_pfn(l2e));
-    l1_pgentry_t l1e = l1[l1_table_offset(va)];
+    l1 = map_domain_page(l2e_get_pfn(l2e));
+    l1e = l1[l1_table_offset(va)];
     unmap_domain_page(l1);
 
 #if 0
-    printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx 
l1tab=%lx, l1e=%lx\n",
-           d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, tabpfn, l2e, 
l1tab, l1e);
+    printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, 
l1e=%lx\n",
+           __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, 
tabpfn, l2e, l1tab, l1e);
 #endif
 
     if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
     {
-        printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => 0 l1e=%" PRIpte 
"\n",
-               d->domain_id, gpfn, l1e_get_intpte(l1e));
+        printk("%s(d->id=%d, gpfn=%lx) => 0 l1e=%" PRIpte "\n",
+               __func__, d->domain_id, gpfn, l1e_get_intpte(l1e));
         return INVALID_MFN;
     }
 
@@ -1631,9 +1625,11 @@
     }
 
 #ifndef NDEBUG
-    l2_pgentry_t old_sl2e;
-    __shadow_get_l2e(v, va, &old_sl2e);
-    ASSERT( !(l2e_get_flags(old_sl2e) & _PAGE_PRESENT) );
+    {
+        l2_pgentry_t old_sl2e;
+        __shadow_get_l2e(v, va, &old_sl2e);
+        ASSERT( !(l2e_get_flags(old_sl2e) & _PAGE_PRESENT) );
+    }
 #endif
 
     if ( !get_shadow_ref(sl1mfn) )
@@ -1837,14 +1833,16 @@
     ASSERT(pfn_valid(mfn));
 
 #ifndef NDEBUG
-    u32 type = page->u.inuse.type_info & PGT_type_mask;
-    if ( shadow_mode_refcounts(d) )
-    {
-        ASSERT(type == PGT_writable_page);
-    }
-    else
-    {
-        ASSERT(type && (type < PGT_l4_page_table));
+    {
+        u32 type = page->u.inuse.type_info & PGT_type_mask;
+        if ( shadow_mode_refcounts(d) )
+        {
+            ASSERT(type == PGT_writable_page);
+        }
+        else
+        {
+            ASSERT(type && (type < PGT_l4_page_table));
+        }
     }
 #endif
 
@@ -1932,8 +1930,8 @@
     entry->next = d->arch.out_of_sync;
     d->arch.out_of_sync = entry;
 
-    FSH_LOG("mark_out_of_sync(va=%lx -> writable_pl1e=%lx)",
-            va, entry->writable_pl1e);
+    FSH_LOG("%s(va=%lx -> writable_pl1e=%lx)",
+            __func__, va, entry->writable_pl1e);
 }
 
 /*
@@ -2147,7 +2145,7 @@
         i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask) 
             >> PGT_va_shift;
 
-        if ( (i >= 0 && i <= L1_PAGETABLE_ENTRIES) &&
+        if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
              !l1e_has_changed(pt[i], match, flags) && 
              fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) &&
              !prediction )
@@ -2326,6 +2324,8 @@
     int need_flush = 0, external = shadow_mode_external(d);
     int unshadow;
     int changed;
+    u32 min_max_shadow, min_max_snapshot;
+    int min_shadow, max_shadow, min_snapshot, max_snapshot;
 
     ASSERT(shadow_lock_is_acquired(d));
 
@@ -2385,14 +2385,14 @@
             if ( !smfn )
                 break;
 
-            u32 min_max_shadow = pfn_to_page(smfn)->tlbflush_timestamp;
-            int min_shadow = SHADOW_MIN(min_max_shadow);
-            int max_shadow = SHADOW_MAX(min_max_shadow);
-
-            u32 min_max_snapshot =
+            min_max_shadow = pfn_to_page(smfn)->tlbflush_timestamp;
+            min_shadow     = SHADOW_MIN(min_max_shadow);
+            max_shadow     = SHADOW_MAX(min_max_shadow);
+
+            min_max_snapshot =
                 pfn_to_page(entry->snapshot_mfn)->tlbflush_timestamp;
-            int min_snapshot = SHADOW_MIN(min_max_snapshot);
-            int max_snapshot = SHADOW_MAX(min_max_snapshot);
+            min_snapshot     = SHADOW_MIN(min_max_snapshot);
+            max_snapshot     = SHADOW_MAX(min_max_snapshot);
 
             changed = 0;
 
@@ -2426,7 +2426,8 @@
 
                 __shadow_get_l2e(entry->v, entry->va, &l2e);
                 if (l2e_get_flags(l2e) & _PAGE_PRESENT) {
-                    l2e_remove_flags(l2e, _PAGE_PRESENT);
+                    put_shadow_ref(l2e_get_pfn(l2e)); 
+                    l2e = l2e_empty();
                     __shadow_set_l2e(entry->v, entry->va, l2e);
 
                     if (entry->v == current)
@@ -2450,13 +2451,11 @@
             changed = 0;
             for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ )
             {
-#if CONFIG_X86_PAE
-                BUG();  /* FIXME: need type_info */
-#endif
+                l2_pgentry_t new_pde = guest2[i];
+
                 if ( !is_guest_l2_slot(0,i) && !external )
                     continue;
 
-                l2_pgentry_t new_pde = guest2[i];
                 if ( l2e_has_changed(new_pde, snapshot2[i], PAGE_FLAG_MASK))
                 {
                     need_flush |= validate_pde_change(d, new_pde, &shadow2[i]);
@@ -2496,13 +2495,11 @@
             changed = 0;
             for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ )
             {
-#if CONFIG_X86_PAE
-                BUG();  /* FIXME: need type_info */
-#endif
+                l2_pgentry_t new_pde = guest2[i];
+
                 if ( !is_guest_l2_slot(0, i) && !external )
                     continue;
 
-                l2_pgentry_t new_pde = guest2[i];
                 if ( l2e_has_changed(new_pde, snapshot2[i], PAGE_FLAG_MASK) )
                 {
                     need_flush |= validate_hl2e_change(d, new_pde, 
&shadow2[i]);
@@ -2550,6 +2547,8 @@
 {
     struct out_of_sync_entry *entry;
     int need_flush = 0;
+    l1_pgentry_t *ppte, opte, npte;
+    cpumask_t other_vcpus_mask;
 
     perfc_incrc(shadow_sync_all);
 
@@ -2565,11 +2564,10 @@
         if ( entry->writable_pl1e & (sizeof(l1_pgentry_t)-1) )
             continue;
 
-        l1_pgentry_t *ppte = (l1_pgentry_t *)(
+        ppte = (l1_pgentry_t *)(
             (char *)map_domain_page(entry->writable_pl1e >> PAGE_SHIFT) +
             (entry->writable_pl1e & ~PAGE_MASK));
-        l1_pgentry_t opte = *ppte;
-        l1_pgentry_t npte = opte;
+        opte = npte = *ppte;
         l1e_remove_flags(npte, _PAGE_RW);
 
         if ( (l1e_get_flags(npte) & _PAGE_PRESENT) &&
@@ -2583,23 +2581,15 @@
         unmap_domain_page(ppte);
     }
 
-    // XXX mafetter: SMP
-    //
-    // With the current algorithm, we've gotta flush all the TLBs
-    // before we can safely continue.  I don't think we want to
-    // do it this way, so I think we should consider making
-    // entirely private copies of the shadow for each vcpu, and/or
-    // possibly having a mix of private and shared shadow state
-    // (any path from a PTE that grants write access to an out-of-sync
-    // page table page needs to be vcpu private).
-    //
-#if 0 // this should be enabled for SMP guests...
-    flush_tlb_mask(cpu_online_map);
-#endif
+    /* Other VCPUs mustn't use the revoked writable mappings. */
+    other_vcpus_mask = d->cpumask;
+    cpu_clear(smp_processor_id(), other_vcpus_mask);
+    flush_tlb_mask(other_vcpus_mask);
+
+    /* Flush ourself later. */
     need_flush = 1;
 
-    // Second, resync all L1 pages, then L2 pages, etc...
-    //
+    /* Second, resync all L1 pages, then L2 pages, etc... */
     need_flush |= resync_all(d, PGT_l1_shadow);
     if ( shadow_mode_translate(d) )
         need_flush |= resync_all(d, PGT_hl2_shadow);
@@ -2689,6 +2679,16 @@
             domain_crash_synchronous();
         }
 
+        /* User access violation in guest? */
+        if ( unlikely((regs->error_code & 4) && 
+                      !(l1e_get_flags(gpte) & _PAGE_USER)))
+        {
+            SH_VVLOG("shadow_fault - EXIT: wr fault on super page (%" PRIpte 
")", 
+                    l1e_get_intpte(gpte));
+            goto fail;
+
+        }
+
         if ( unlikely(!l1pte_write_fault(v, &gpte, &spte, va)) )
         {
             SH_VVLOG("shadow_fault - EXIT: l1pte_write_fault failed");
@@ -2702,6 +2702,16 @@
     }
     else
     {
+        /* Read-protection violation in guest? */
+        if ( unlikely((regs->error_code & 1) ))
+        {
+            SH_VVLOG("shadow_fault - EXIT: read fault on super page (%" PRIpte 
")", 
+                    l1e_get_intpte(gpte));
+            goto fail;
+
+        }
+
+
         if ( !l1pte_read_fault(d, &gpte, &spte) )
         {
             SH_VVLOG("shadow_fault - EXIT: l1pte_read_fault failed");
@@ -2726,9 +2736,7 @@
             domain_crash_synchronous();
         }
 
-        // if necessary, record the page table page as dirty
-        if ( unlikely(shadow_mode_log_dirty(d)) )
-            __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
+        __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
     }
 
     shadow_set_l1e(va, spte, 1);
@@ -2825,8 +2833,6 @@
 
     shadow_lock(d);
 
-    //printk("%s(va=%p, val=%p)\n", __func__, (void *)va, (void 
*)l1e_get_intpte(val));
-        
     // This is actually overkill - we don't need to sync the L1 itself,
     // just everything involved in getting to this L1 (i.e. we need
     // linear_pg_table[l1_linear_offset(va)] to be in sync)...
@@ -2841,10 +2847,8 @@
      * the PTE in the PT-holding page. We need the machine frame number
      * for this.
      */
-    if ( shadow_mode_log_dirty(d) )
-        __mark_dirty(d, va_to_l1mfn(v, va));
-
-// out:
+    __mark_dirty(d, va_to_l1mfn(v, va));
+
     shadow_unlock(d);
 
     return rc;
@@ -2907,6 +2911,8 @@
      */
     if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_base_page_table))) )
         smfn = shadow_l2_table(d, gpfn, gmfn);
+    else
+        shadow_sync_all(d);
     if ( !get_shadow_ref(smfn) )
         BUG();
     old_smfn = pagetable_get_pfn(v->arch.shadow_table);
@@ -3269,14 +3275,10 @@
                l2e_get_intpte(match));
     }
 
-#ifdef __i386__
     if ( shadow_mode_external(d) )
         limit = L2_PAGETABLE_ENTRIES;
     else
         limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
-#else
-    limit = 0; /* XXX x86/64 XXX */
-#endif
 
     /* Check the whole L2. */
     for ( i = 0; i < limit; i++ )
@@ -3338,14 +3340,10 @@
     spl2e = (l2_pgentry_t *) map_domain_page(smfn);
 
     /* Go back and recurse. */
-#ifdef __i386__
     if ( shadow_mode_external(d) )
         limit = L2_PAGETABLE_ENTRIES;
     else
         limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
-#else
-    limit = 0; /* XXX x86/64 XXX */
-#endif
 
     for ( i = 0; i < limit; i++ )
     {
@@ -3361,11 +3359,6 @@
 
     unmap_domain_page(spl2e);
     unmap_domain_page(gpl2e);
-
-#if 0
-    SH_VVLOG("PT verified : l2_present = %d, l1_present = %d",
-             sh_l2_present, sh_l1_present);
-#endif
 
  out:
     if ( errors )
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/shadow_public.c      Fri Dec  2 18:52:25 2005
@@ -297,13 +297,11 @@
 
     /*
      * free monitor_table.
-     * Note: for VMX guest, only BSP need do this free.
      */
-    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
-        mfn = pagetable_get_pfn(v->arch.monitor_table);
-        unmap_domain_page(v->arch.monitor_vtable);
-        free_domheap_page(&frame_table[mfn]);
-    }
+    mfn = pagetable_get_pfn(v->arch.monitor_table);
+    unmap_domain_page(v->arch.monitor_vtable);
+    free_domheap_page(&frame_table[mfn]);
+
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
 }
@@ -392,22 +390,17 @@
         put_shadow_ref(mfn);
     }
 
-    unmap_domain_page(mpl2e);
-
     /*
      * Then free monitor_table.
-     * Note: for VMX guest, only BSP need do this free.
      */
-    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
-        mfn = pagetable_get_pfn(v->arch.monitor_table);
-        unmap_domain_page(v->arch.monitor_vtable);
-        free_domheap_page(&frame_table[mfn]);
-    }
+    mfn = pagetable_get_pfn(v->arch.monitor_table);
+    unmap_domain_page(v->arch.monitor_vtable);
+    free_domheap_page(&frame_table[mfn]);
 
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
 }
-#endif 
+#endif
 
 static void
 shadow_free_snapshot(struct domain *d, struct out_of_sync_entry *entry)
@@ -786,6 +779,7 @@
     int                   i;
     struct shadow_status *x;
     struct vcpu          *v;
+    struct list_head *list_ent, *tmp;
 
     /*
      * WARNING! The shadow page table must not currently be in use!
@@ -884,15 +878,14 @@
         xfree(mfn_list);
     }
 
-    // Now free the pre-zero'ed pages from the domain
-    //
-    struct list_head *list_ent, *tmp;
+    /* Now free the pre-zero'ed pages from the domain. */
     list_for_each_safe(list_ent, tmp, &d->arch.free_shadow_frames)
     {
+        struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
+
         list_del(list_ent);
         perfc_decr(free_l1_pages);
 
-        struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
         if (d->arch.ops->guest_paging_levels == PAGING_L2)
         {
 #if CONFIG_PAGING_LEVELS >=4
@@ -912,6 +905,11 @@
 
 void __shadow_mode_disable(struct domain *d)
 {
+    struct vcpu *v;
+#ifndef NDEBUG
+    int i;
+#endif
+
     if ( unlikely(!shadow_mode_enabled(d)) )
         return;
 
@@ -919,7 +917,6 @@
     free_writable_pte_predictions(d);
 
 #ifndef NDEBUG
-    int i;
     for ( i = 0; i < shadow_ht_buckets; i++ )
     {
         if ( d->arch.shadow_ht[i].gpfn_and_flags != 0 )
@@ -936,11 +933,8 @@
     free_shadow_ht_entries(d);
     free_out_of_sync_entries(d);
 
-    struct vcpu *v;
     for_each_vcpu(d, v)
-    {
         update_pagetables(v);
-    }
 }
 
 
@@ -1083,36 +1077,40 @@
     //
     free_shadow_pages(d);
 
-    /*
-     * Tear down it's counts by disassembling its page-table-based ref counts.
-     * Also remove CR3's gcount/tcount.
-     * That leaves things like GDTs and LDTs and external refs in tact.
-     *
-     * Most pages will be writable tcount=0.
-     * Some will still be L1 tcount=0 or L2 tcount=0.
-     * Maybe some pages will be type none tcount=0.
-     * Pages granted external writable refs (via grant tables?) will
-     * still have a non-zero tcount.  That's OK.
-     *
-     * gcounts will generally be 1 for PGC_allocated.
-     * GDTs and LDTs will have additional gcounts.
-     * Any grant-table based refs will still be in the gcount.
-     *
-     * We attempt to grab writable refs to each page (thus setting its type).
-     * Immediately put back those type refs.
-     *
-     * Assert that no pages are left with L1/L2/L3/L4 type.
-     */
-    audit_adjust_pgtables(d, -1, 1);
-
     d->arch.shadow_mode = mode;
 
     if ( shadow_mode_refcounts(d) )
     {
-        struct list_head *list_ent = d->page_list.next;
-        while ( list_ent != &d->page_list )
-        {
-            struct pfn_info *page = list_entry(list_ent, struct pfn_info, 
list);
+        struct list_head *list_ent; 
+        struct pfn_info *page;
+
+        /*
+         * Tear down its counts by disassembling its page-table-based refcounts
+         * Also remove CR3's gcount/tcount.
+         * That leaves things like GDTs and LDTs and external refs in tact.
+         *
+         * Most pages will be writable tcount=0.
+         * Some will still be L1 tcount=0 or L2 tcount=0.
+         * Maybe some pages will be type none tcount=0.
+         * Pages granted external writable refs (via grant tables?) will
+         * still have a non-zero tcount.  That's OK.
+         *
+         * gcounts will generally be 1 for PGC_allocated.
+         * GDTs and LDTs will have additional gcounts.
+         * Any grant-table based refs will still be in the gcount.
+         *
+         * We attempt to grab writable refs to each page thus setting its type
+         * Immediately put back those type refs.
+         *
+         * Assert that no pages are left with L1/L2/L3/L4 type.
+         */
+        audit_adjust_pgtables(d, -1, 1);
+
+
+        for (list_ent = d->page_list.next; list_ent != &d->page_list; 
+             list_ent = page->list.next) {
+            
+            page = list_entry(list_ent, struct pfn_info, list);
             if ( !get_page_type(page, PGT_writable_page) )
                 BUG();
             put_page_type(page);
@@ -1120,13 +1118,13 @@
              * We use tlbflush_timestamp as back pointer to smfn, and need to
              * clean up it.
              */
-            if ( shadow_mode_external(d) )
+            if (shadow_mode_external(d))
                 page->tlbflush_timestamp = 0;
-            list_ent = page->list.next;
-        }
-    }
-
-    audit_adjust_pgtables(d, 1, 1);
+        }
+        
+        audit_adjust_pgtables(d, 1, 1);
+  
+    }
 
     return 0;
 
@@ -1182,8 +1180,6 @@
 
         d->arch.shadow_fault_count       = 0;
         d->arch.shadow_dirty_count       = 0;
-        d->arch.shadow_dirty_net_count   = 0;
-        d->arch.shadow_dirty_block_count = 0;
 
         break;
    
@@ -1192,15 +1188,10 @@
 
         sc->stats.fault_count       = d->arch.shadow_fault_count;
         sc->stats.dirty_count       = d->arch.shadow_dirty_count;
-        sc->stats.dirty_net_count   = d->arch.shadow_dirty_net_count;
-        sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
 
         d->arch.shadow_fault_count       = 0;
         d->arch.shadow_dirty_count       = 0;
-        d->arch.shadow_dirty_net_count   = 0;
-        d->arch.shadow_dirty_block_count = 0;
  
-
         if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
@@ -1235,8 +1226,6 @@
     case DOM0_SHADOW_CONTROL_OP_PEEK:
         sc->stats.fault_count       = d->arch.shadow_fault_count;
         sc->stats.dirty_count       = d->arch.shadow_dirty_count;
-        sc->stats.dirty_net_count   = d->arch.shadow_dirty_net_count;
-        sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
  
         if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
@@ -1290,8 +1279,11 @@
     switch ( op )
     {
     case DOM0_SHADOW_CONTROL_OP_OFF:
-        __shadow_sync_all(d);
-        __shadow_mode_disable(d);
+        if ( shadow_mode_enabled(d) )
+        {
+            __shadow_sync_all(d);
+            __shadow_mode_disable(d);
+        }
         break;
 
     case DOM0_SHADOW_CONTROL_OP_ENABLE_TEST:
@@ -1433,7 +1425,7 @@
 
 void shadow_l1_normal_pt_update(
     struct domain *d,
-    unsigned long pa, l1_pgentry_t gpte,
+    physaddr_t pa, l1_pgentry_t gpte,
     struct domain_mmap_cache *cache)
 {
     unsigned long sl1mfn;    
@@ -1458,7 +1450,7 @@
 
 void shadow_l2_normal_pt_update(
     struct domain *d,
-    unsigned long pa, l2_pgentry_t gpde,
+    physaddr_t pa, l2_pgentry_t gpde,
     struct domain_mmap_cache *cache)
 {
     unsigned long sl2mfn;
@@ -1483,7 +1475,7 @@
 #if CONFIG_PAGING_LEVELS >= 3
 void shadow_l3_normal_pt_update(
     struct domain *d,
-    unsigned long pa, l3_pgentry_t l3e,
+    physaddr_t pa, l3_pgentry_t l3e,
     struct domain_mmap_cache *cache)
 {
     unsigned long sl3mfn;
@@ -1510,7 +1502,7 @@
 #if CONFIG_PAGING_LEVELS >= 4
 void shadow_l4_normal_pt_update(
     struct domain *d,
-    unsigned long pa, l4_pgentry_t l4e,
+    physaddr_t pa, l4_pgentry_t l4e,
     struct domain_mmap_cache *cache)
 {
     unsigned long sl4mfn;
@@ -1603,36 +1595,40 @@
 }
 
 unsigned long
-gpfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
-{
-    ASSERT( shadow_mode_translate(d) );
-
-    perfc_incrc(gpfn_to_mfn_foreign);
-
-    unsigned long va = gpfn << PAGE_SHIFT;
-    unsigned long tabpfn = pagetable_get_pfn(d->arch.phys_table);
-    l2_pgentry_t *l2 = map_domain_page(tabpfn);
-    l2_pgentry_t l2e = l2[l2_table_offset(va)];
+get_mfn_from_pfn_foreign(struct domain *d, unsigned long gpfn)
+{
+    unsigned long va, tabpfn;
+    l1_pgentry_t *l1, l1e;
+    l2_pgentry_t *l2, l2e;
+
+    ASSERT(shadow_mode_translate(d));
+
+    perfc_incrc(get_mfn_from_pfn_foreign);
+
+    va = gpfn << PAGE_SHIFT;
+    tabpfn = pagetable_get_pfn(d->arch.phys_table);
+    l2 = map_domain_page(tabpfn);
+    l2e = l2[l2_table_offset(va)];
     unmap_domain_page(l2);
     if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
     {
-        printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte 
"\n",
-               d->domain_id, gpfn, l2e_get_intpte(l2e));
+        printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n",
+               __func__, d->domain_id, gpfn, l2e_get_intpte(l2e));
         return INVALID_MFN;
     }
-    l1_pgentry_t *l1 = map_domain_page(l2e_get_pfn(l2e));
-    l1_pgentry_t l1e = l1[l1_table_offset(va)];
+    l1 = map_domain_page(l2e_get_pfn(l2e));
+    l1e = l1[l1_table_offset(va)];
     unmap_domain_page(l1);
 
 #if 0
-    printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx 
l1tab=%lx, l1e=%lx\n",
-           d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, tabpfn, l2e, 
l1tab, l1e);
+    printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, 
l1e=%lx\n",
+           __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, 
tabpfn, l2e, l1tab, l1e);
 #endif
 
     if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
     {
-        printk("gpfn_to_mfn_foreign(d->id=%d, gpfn=%lx) => 0 l1e=%" PRIpte 
"\n",
-               d->domain_id, gpfn, l1e_get_intpte(l1e));
+        printk("%s(d->id=%d, gpfn=%lx) => 0 l1e=%" PRIpte "\n",
+               __func__, d->domain_id, gpfn, l1e_get_intpte(l1e));
         return INVALID_MFN;
     }
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/time.c       Fri Dec  2 18:52:25 2005
@@ -683,8 +683,11 @@
 
 static inline void __update_dom_time(struct vcpu *v)
 {
-    struct cpu_time       *t = &cpu_time[smp_processor_id()];
-    struct vcpu_time_info *u = &v->domain->shared_info->vcpu_time[v->vcpu_id];
+    struct cpu_time       *t;
+    struct vcpu_time_info *u;
+
+    t = &cpu_time[smp_processor_id()];
+    u = &v->domain->shared_info->vcpu_info[v->vcpu_id].time;
 
     version_update_begin(&u->version);
 
@@ -698,7 +701,7 @@
 
 void update_dom_time(struct vcpu *v)
 {
-    if ( v->domain->shared_info->vcpu_time[v->vcpu_id].tsc_timestamp != 
+    if ( v->domain->shared_info->vcpu_info[v->vcpu_id].time.tsc_timestamp != 
          cpu_time[smp_processor_id()].local_tsc_stamp )
         __update_dom_time(v);
 }
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/vmx.c        Fri Dec  2 18:52:25 2005
@@ -43,8 +43,8 @@
 #endif
 #include <public/sched.h>
 #include <public/io/ioreq.h>
-#include <public/io/vmx_vpic.h>
-#include <public/io/vmx_vlapic.h>
+#include <asm/vmx_vpic.h>
+#include <asm/vmx_vlapic.h>
 
 int hvm_enabled;
 
@@ -61,23 +61,30 @@
 {
     v->arch.schedule_tail = arch_vmx_do_launch;
 
-    if ( v == v->domain->vcpu[0] )
+    if ( v->vcpu_id == 0 )
     {
-        v->domain->arch.vmx_platform.lapic_enable =
-            v->arch.guest_context.user_regs.ecx;
+        struct domain *d = v->domain;
+        struct vcpu *vc;
+
+        d->arch.vmx_platform.lapic_enable = 
v->arch.guest_context.user_regs.ecx;
         v->arch.guest_context.user_regs.ecx = 0;
         VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "lapic enable is %d.\n",
-                    v->domain->arch.vmx_platform.lapic_enable);
+                    d->arch.vmx_platform.lapic_enable);
+
+        /* Initialize monitor page table */
+        for_each_vcpu(d, vc)
+            vc->arch.monitor_table = mk_pagetable(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,
-               sizeof(v->domain->shared_info->evtchn_mask));
+        memset(&d->shared_info->evtchn_mask[0], 0xff,
+               sizeof(d->shared_info->evtchn_mask));
 
         /* Put the domain in shadow mode even though we're going to be using
          * the shared 1:1 page table initially. It shouldn't hurt */
-        shadow_mode_enable(v->domain,
+        shadow_mode_enable(d,
                            SHM_enable|SHM_refcounts|
                            SHM_translate|SHM_external|SHM_wr_pt_pte);
     }
@@ -129,15 +136,14 @@
  */
 void vmx_load_msrs(struct vcpu *n)
 {
-    struct msr_state *host_state;
-    host_state = &percpu_msr[smp_processor_id()];
+    struct msr_state *host_state = &percpu_msr[smp_processor_id()];
+    int i;
 
     if ( !vmx_switch_on )
         return;
 
-    while (host_state->flags){
-        int i;
-
+    while ( host_state->flags )
+    {
         i = find_first_set_bit(host_state->flags);
         wrmsrl(msr_data_index[i], host_state->msr_items[i]);
         clear_bit(i, &host_state->flags);
@@ -146,11 +152,10 @@
 
 static void vmx_save_init_msrs(void)
 {
-    struct msr_state *host_state;
-    host_state = &percpu_msr[smp_processor_id()];
+    struct msr_state *host_state = &percpu_msr[smp_processor_id()];
     int i;
 
-    for (i = 0; i < VMX_MSR_COUNT; i++)
+    for ( i = 0; i < VMX_MSR_COUNT; i++ )
         rdmsrl(msr_data_index[i], host_state->msr_items[i]);
 }
 
@@ -516,23 +521,20 @@
 
     cpuid(input, &eax, &ebx, &ecx, &edx);
 
-    if (input == 1) {
+    if ( input == 1 )
+    {
         if ( vmx_apic_support(v->domain) &&
-                !vlapic_global_enabled((VLAPIC(v))) )
+             !vlapic_global_enabled((VLAPIC(v))) )
             clear_bit(X86_FEATURE_APIC, &edx);
-#ifdef __i386__
-        clear_bit(X86_FEATURE_PSE, &edx);
-        clear_bit(X86_FEATURE_PAE, &edx);
-        clear_bit(X86_FEATURE_PSE36, &edx);
-#else
-        struct vcpu *v = current;
-        if (v->domain->arch.ops->guest_paging_levels == PAGING_L2)
+
+#ifdef __x86_64__
+        if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
+#endif
         {
             clear_bit(X86_FEATURE_PSE, &edx);
             clear_bit(X86_FEATURE_PAE, &edx);
             clear_bit(X86_FEATURE_PSE36, &edx);
         }
-#endif
 
         /* Unsupportable for virtualised CPUs. */
         clear_bit(X86_FEATURE_VMXE & 31, &ecx);
@@ -1084,6 +1086,7 @@
     unsigned long eip;
     int paging_enabled;
     unsigned long vm_entry_value;
+
     /*
      * CR0: We don't want to lose PE and PG.
      */
@@ -1140,14 +1143,17 @@
 #endif
         }
 
-        unsigned long crn;
-        /* update CR4's PAE if needed */
-        __vmread(GUEST_CR4, &crn);
-        if ( (!(crn & X86_CR4_PAE)) &&
-             test_bit(VMX_CPU_STATE_PAE_ENABLED,
-                      &v->arch.arch_vmx.cpu_state)){
-            VMX_DBG_LOG(DBG_LEVEL_1, "enable PAE on cr4\n");
-            __vmwrite(GUEST_CR4, crn | X86_CR4_PAE);
+        {
+            unsigned long crn;
+            /* update CR4's PAE if needed */
+            __vmread(GUEST_CR4, &crn);
+            if ( (!(crn & X86_CR4_PAE)) &&
+                 test_bit(VMX_CPU_STATE_PAE_ENABLED,
+                          &v->arch.arch_vmx.cpu_state) )
+            {
+                VMX_DBG_LOG(DBG_LEVEL_1, "enable PAE on cr4\n");
+                __vmwrite(GUEST_CR4, crn | X86_CR4_PAE);
+            }
         }
 #endif
         /*
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c      Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/vmx_intercept.c      Fri Dec  2 18:52:25 2005
@@ -21,7 +21,7 @@
 #include <xen/types.h>
 #include <asm/vmx.h>
 #include <asm/vmx_platform.h>
-#include <asm/vmx_virpit.h>
+#include <asm/vmx_vpit.h>
 #include <asm/vmx_intercept.h>
 #include <asm/vmx_vlapic.h>
 #include <public/io/ioreq.h>
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c     Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/vmx_io.c     Fri Dec  2 18:52:25 2005
@@ -32,13 +32,12 @@
 #include <asm/vmx.h>
 #include <asm/vmx_vmcs.h>
 #include <asm/vmx_platform.h>
-#include <asm/vmx_virpit.h>
+#include <asm/vmx_vpit.h>
 #include <asm/apic.h>
 #include <asm/shadow.h>
-
+#include <asm/vmx_vpic.h>
 #include <asm/vmx_vlapic.h>
 #include <public/io/ioreq.h>
-#include <public/io/vmx_vpic.h>
 
 #ifdef CONFIG_VMX
 #if defined (__i386__)
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/x86_32/mm.c  Fri Dec  2 18:52:25 2005
@@ -27,6 +27,7 @@
 #include <asm/page.h>
 #include <asm/flushtlb.h>
 #include <asm/fixmap.h>
+#include <public/memory.h>
 
 extern l1_pgentry_t *mapcache;
 
@@ -106,7 +107,10 @@
         idle_pg_table_l2[l2_linear_offset(RO_MPT_VIRT_START) + i] =
             l2e_from_page(pg, (__PAGE_HYPERVISOR | _PAGE_PSE) & ~_PAGE_RW);
     }
-    memset((void *)RDWR_MPT_VIRT_START, 0x55, mpt_size);
+
+    /* Fill with an obvious debug pattern. */
+    for ( i = 0; i < (mpt_size / BYTES_PER_LONG); i++)
+        set_pfn_from_mfn(i, 0x55555555);
 
     /* Create page tables for ioremap(). */
     for ( i = 0; i < (IOREMAP_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
@@ -181,6 +185,41 @@
     }
 }
 
+long arch_memory_op(int op, void *arg)
+{
+    struct xen_machphys_mfn_list xmml;
+    unsigned long mfn;
+    unsigned int i, max;
+    long rc = 0;
+
+    switch ( op )
+    {
+    case XENMEM_machphys_mfn_list:
+        if ( copy_from_user(&xmml, arg, sizeof(xmml)) )
+            return -EFAULT;
+
+        max = min_t(unsigned int, xmml.max_extents, mpt_size >> 21);
+
+        for ( i = 0; i < max; i++ )
+        {
+            mfn = l2e_get_pfn(idle_pg_table_l2[l2_linear_offset(
+                RDWR_MPT_VIRT_START + (i << 21))]) + l1_table_offset(i << 21);
+            if ( put_user(mfn, &xmml.extent_start[i]) )
+                return -EFAULT;
+        }
+
+        if ( put_user(i, &((struct xen_machphys_mfn_list *)arg)->nr_extents) )
+            return -EFAULT;
+
+        break;
+
+    default:
+        rc = -ENOSYS;
+        break;
+    }
+
+    return rc;
+}
 
 long do_stack_switch(unsigned long ss, unsigned long esp)
 {
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/x86_32/traps.c       Fri Dec  2 18:52:25 2005
@@ -93,7 +93,7 @@
 #ifdef CONFIG_X86_PAE
     ptab = map_domain_page(mfn);
     ent  = ptab[l3_table_offset(addr)];
-    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
+    pfn  = get_pfn_from_mfn((u32)(ent >> PAGE_SHIFT)); 
     printk(" L3 = %"PRIpte" %08lx\n", ent, pfn);
     unmap_domain_page(ptab);
     if ( !(ent & _PAGE_PRESENT) )
@@ -103,7 +103,7 @@
 
     ptab = map_domain_page(mfn);
     ent  = ptab[l2_table_offset(addr)];
-    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
+    pfn  = get_pfn_from_mfn((u32)(ent >> PAGE_SHIFT));
     printk("  L2 = %"PRIpte" %08lx %s\n", ent, pfn, 
            (ent & _PAGE_PSE) ? "(PSE)" : "");
     unmap_domain_page(ptab);
@@ -113,7 +113,7 @@
 
     ptab = map_domain_page(ent >> PAGE_SHIFT);
     ent  = ptab[l1_table_offset(addr)];
-    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
+    pfn  = get_pfn_from_mfn((u32)(ent >> PAGE_SHIFT));
     printk("   L1 = %"PRIpte" %08lx\n", ent, pfn);
     unmap_domain_page(ptab);
 }
@@ -167,6 +167,7 @@
 
 void __init percpu_traps_init(void)
 {
+    struct tss_struct *tss = &doublefault_tss;
     asmlinkage int hypercall(void);
 
     if ( smp_processor_id() != 0 )
@@ -184,7 +185,6 @@
      * Make a separate task for double faults. This will get us debug output if
      * we blow the kernel stack.
      */
-    struct tss_struct *tss = &doublefault_tss;
     memset(tss, 0, sizeof(*tss));
     tss->ds     = __HYPERVISOR_DS;
     tss->es     = __HYPERVISOR_DS;
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Fri Dec  2 18:12:11 2005
+++ b/xen/arch/x86/x86_64/mm.c  Fri Dec  2 18:52:25 2005
@@ -28,6 +28,7 @@
 #include <asm/flushtlb.h>
 #include <asm/fixmap.h>
 #include <asm/msr.h>
+#include <public/memory.h>
 
 struct pfn_info *alloc_xen_pagetable(void)
 {
@@ -172,6 +173,50 @@
             page_set_owner(&frame_table[m2p_start_mfn+i], dom_xen);
         }
     }
+}
+
+long arch_memory_op(int op, void *arg)
+{
+    struct xen_machphys_mfn_list xmml;
+    l3_pgentry_t l3e;
+    l2_pgentry_t l2e;
+    unsigned long mfn, v;
+    unsigned int i;
+    long rc = 0;
+
+    switch ( op )
+    {
+    case XENMEM_machphys_mfn_list:
+        if ( copy_from_user(&xmml, arg, sizeof(xmml)) )
+            return -EFAULT;
+
+        for ( i = 0, v = RDWR_MPT_VIRT_START;
+              (i != xmml.max_extents) && (v != RDWR_MPT_VIRT_END);
+              i++, v += 1 << 21 )
+        {
+            l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(v)])[
+                l3_table_offset(v)];
+            if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+                break;
+            l2e = l3e_to_l2e(l3e)[l2_table_offset(v)];
+            if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+                break;
+            mfn = l2e_get_pfn(l2e) + l1_table_offset(v);
+            if ( put_user(mfn, &xmml.extent_start[i]) )
+                return -EFAULT;
+        }
+
+        if ( put_user(i, &((struct xen_machphys_mfn_list *)arg)->nr_extents) )
+            return -EFAULT;
+
+        break;
+
+    default:
+        rc = -ENOSYS;
+        break;
+    }
+
+    return rc;
 }
 
 long do_stack_switch(unsigned long ss, unsigned long esp)
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/Makefile
--- a/xen/common/Makefile       Fri Dec  2 18:12:11 2005
+++ b/xen/common/Makefile       Fri Dec  2 18:52:25 2005
@@ -1,9 +1,5 @@
 
 include $(BASEDIR)/Rules.mk
-
-ifeq ($(TARGET_ARCH),ia64)
-OBJS := $(subst grant_table.o,,$(OBJS))
-endif
 
 ifneq ($(perfc),y)
 OBJS := $(subst perfc.o,,$(OBJS))
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c      Fri Dec  2 18:12:11 2005
+++ b/xen/common/acm_ops.c      Fri Dec  2 18:52:25 2005
@@ -29,7 +29,7 @@
 #include <public/sched_ctl.h>
 #include <acm/acm_hooks.h>
 
-#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+#ifndef ACM_SECURITY
 
 long do_acm_op(struct acm_op * u_acm_op)
 {
@@ -49,15 +49,11 @@
 
 int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops)
 {
-    /* all policy management functions are restricted to privileged domains,
-     * soon we will introduce finer-grained privileges for policy operations
-     */
+    /* currently, policy management functions are restricted to privileged 
domains */
     if (!IS_PRIV(d))
-    {
-        printk("%s: ACM management authorization denied ERROR!\n", __func__);
-        return ACM_ACCESS_DENIED;
-    }
-    return ACM_ACCESS_PERMITTED;
+        return -EPERM;
+
+    return 0;
 }
 
 long do_acm_op(struct acm_op * u_acm_op)
@@ -65,10 +61,8 @@
     long ret = 0;
     struct acm_op curop, *op = &curop;
 
-    /* check here policy decision for policy commands */
-    /* for now allow DOM0 only, later indepedently    */
     if (acm_authorize_acm_ops(current->domain, POLICY))
-        return -EACCES;
+        return -EPERM;
 
     if (copy_from_user(op, u_acm_op, sizeof(*op)))
         return -EFAULT;
@@ -80,43 +74,32 @@
     {
     case ACM_SETPOLICY:
     {
-        if (acm_authorize_acm_ops(current->domain, SETPOLICY))
-            return -EACCES;
-        printkd("%s: setting policy.\n", __func__);
-        ret = acm_set_policy(op->u.setpolicy.pushcache,
-                             op->u.setpolicy.pushcache_size, 1);
-        if (ret == ACM_OK)
-            ret = 0;
-        else
-            ret = -ESRCH;
+        ret = acm_authorize_acm_ops(current->domain, SETPOLICY);
+        if (!ret)
+            ret = acm_set_policy(op->u.setpolicy.pushcache,
+                                 op->u.setpolicy.pushcache_size, 1);
     }
     break;
 
     case ACM_GETPOLICY:
     {
-        if (acm_authorize_acm_ops(current->domain, GETPOLICY))
-            return -EACCES;
-        printkd("%s: getting policy.\n", __func__);
-        ret = acm_get_policy(op->u.getpolicy.pullcache,
-                             op->u.getpolicy.pullcache_size);
-        if (ret == ACM_OK)
-            ret = 0;
-        else
-            ret = -ESRCH;
+        ret = acm_authorize_acm_ops(current->domain, GETPOLICY);
+        if (!ret)
+            ret = acm_get_policy(op->u.getpolicy.pullcache,
+                                 op->u.getpolicy.pullcache_size);
+        if (!ret)
+            copy_to_user(u_acm_op, op, sizeof(*op));
     }
     break;
 
     case ACM_DUMPSTATS:
     {
-        if (acm_authorize_acm_ops(current->domain, DUMPSTATS))
-            return -EACCES;
-        printkd("%s: dumping statistics.\n", __func__);
-        ret = acm_dump_statistics(op->u.dumpstats.pullcache,
-                                  op->u.dumpstats.pullcache_size);
-        if (ret == ACM_OK)
-            ret = 0;
-        else
-            ret = -ESRCH;
+        ret = acm_authorize_acm_ops(current->domain, DUMPSTATS);
+        if (!ret)
+            ret = acm_dump_statistics(op->u.dumpstats.pullcache,
+                                      op->u.dumpstats.pullcache_size);
+        if (!ret)
+            copy_to_user(u_acm_op, op, sizeof(*op));
     }
     break;
 
@@ -124,31 +107,39 @@
     {
         ssidref_t ssidref;
 
-        if (acm_authorize_acm_ops(current->domain, GETSSID))
-            return -EACCES;
-        printkd("%s: getting SSID.\n", __func__);
+        ret = acm_authorize_acm_ops(current->domain, GETSSID);
+        if (ret)
+            break;
+
         if (op->u.getssid.get_ssid_by == SSIDREF)
             ssidref = op->u.getssid.id.ssidref;
-        else if (op->u.getssid.get_ssid_by == DOMAINID) {
+        else if (op->u.getssid.get_ssid_by == DOMAINID)
+        {
             struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
             if (!subj)
-                return -ESRCH; /* domain not found */
-            if (subj->ssid == NULL) {
+            {
+                ret = -ESRCH; /* domain not found */
+                break;
+            }
+            if (subj->ssid == NULL)
+            {
                 put_domain(subj);
-                return -ESRCH;
+                ret = -ESRCH;
+                break;
             }
             ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
             put_domain(subj);
-        } else
-            return -ESRCH;
-
+        }
+        else
+        {
+            ret = -ESRCH;
+            break;
+        }
         ret = acm_get_ssid(ssidref,
                            op->u.getssid.ssidbuf,
                            op->u.getssid.ssidbuf_size);
-        if (ret == ACM_OK)
-            ret = 0;
-        else
-            ret = -ESRCH;
+        if (!ret)
+            copy_to_user(u_acm_op, op, sizeof(*op));
     }
     break;
 
@@ -156,50 +147,75 @@
     {
         ssidref_t ssidref1, ssidref2;
 
-        if (acm_authorize_acm_ops(current->domain, GETDECISION)) {
-            ret = -EACCES;
-            goto out;
-        }
-        printkd("%s: getting access control decision.\n", __func__);
-        if (op->u.getdecision.get_decision_by1 == SSIDREF) {
+        ret = acm_authorize_acm_ops(current->domain, GETDECISION);
+        if (ret)
+            break;
+
+        if (op->u.getdecision.get_decision_by1 == SSIDREF)
             ssidref1 = op->u.getdecision.id1.ssidref;
-        }
-        else if (op->u.getdecision.get_decision_by1 == DOMAINID) {
+        else if (op->u.getdecision.get_decision_by1 == DOMAINID)
+        {
             struct domain *subj = 
find_domain_by_id(op->u.getdecision.id1.domainid);
-            if (!subj) {
+            if (!subj)
+            {
                 ret = -ESRCH; /* domain not found */
-                goto out;
-            }
-            if (subj->ssid == NULL) {
+                break;
+            }
+            if (subj->ssid == NULL)
+            {
                 put_domain(subj);
                 ret = -ESRCH;
+                break;
             }
             ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
             put_domain(subj);
-        } else {
-            ret = -ESRCH;
-            goto out;
-        }
-        if (op->u.getdecision.get_decision_by2 == SSIDREF) {
+        }
+        else
+        {
+            ret = -ESRCH;
+            break;
+        }
+        if (op->u.getdecision.get_decision_by2 == SSIDREF)
             ssidref2 = op->u.getdecision.id2.ssidref;
-        }
-        else if (op->u.getdecision.get_decision_by2 == DOMAINID) {
+        else if (op->u.getdecision.get_decision_by2 == DOMAINID)
+        {
             struct domain *subj = 
find_domain_by_id(op->u.getdecision.id2.domainid);
-            if (!subj) {
+            if (!subj)
+            {
                 ret = -ESRCH; /* domain not found */
-                goto out;
-            }
-            if (subj->ssid == NULL) {
+                break;;
+            }
+            if (subj->ssid == NULL)
+            {
                 put_domain(subj);
-                return -ESRCH;
+                ret = -ESRCH;
+                break;
             }
             ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
             put_domain(subj);
-        } else {
-            ret = -ESRCH;
-            goto out;
+        }
+        else
+        {
+            ret = -ESRCH;
+            break;
         }
         ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
+
+        if (ret == ACM_ACCESS_PERMITTED)
+        {
+            op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
+            ret = 0;
+        }
+        else if  (ret == ACM_ACCESS_DENIED)
+        {
+            op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
+            ret = 0;
+        }
+        else
+            ret = -ESRCH;
+
+        if (!ret)
+            copy_to_user(u_acm_op, op, sizeof(*op));
     }
     break;
 
@@ -207,20 +223,6 @@
         ret = -ESRCH;
     }
 
- out:
-    if (ret == ACM_ACCESS_PERMITTED) {
-        op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
-        ret = 0;
-    } else if  (ret == ACM_ACCESS_DENIED) {
-        op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
-        ret = 0;
-    } else {
-        op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
-        if (ret > 0)
-            ret = -ret;
-    }
-    /* copy decision back to user space */
-    copy_to_user(u_acm_op, op, sizeof(*op));
     return ret;
 }
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Fri Dec  2 18:12:11 2005
+++ b/xen/common/dom0_ops.c     Fri Dec  2 18:52:25 2005
@@ -102,7 +102,7 @@
         return -EACCES;
 
     if ( acm_pre_dom0_op(op, &ssid) )
-        return -EACCES;
+        return -EPERM;
 
     spin_lock(&dom0_lock);
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/domain.c
--- a/xen/common/domain.c       Fri Dec  2 18:12:11 2005
+++ b/xen/common/domain.c       Fri Dec  2 18:52:25 2005
@@ -293,11 +293,7 @@
     struct vcpu *v;
 
     for_each_vcpu( d, v )
-    {
-        BUG_ON(v == current);
-        atomic_inc(&v->pausecnt);
-        vcpu_sleep_sync(v);
-    }
+        vcpu_pause(v);
 
     sync_pagetable_state(d);
 }
@@ -376,14 +372,10 @@
 int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) 
 {
     struct vcpu *v = d->vcpu[vcpuid];
-    int rc;
 
     BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
 
-    if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
-        return rc;
-
-    return rc;
+    return arch_set_info_guest(v, ctxt);
 }
 
 long do_vcpu_op(int cmd, int vcpuid, void *arg)
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Fri Dec  2 18:12:11 2005
+++ b/xen/common/grant_table.c  Fri Dec  2 18:52:25 2005
@@ -31,17 +31,11 @@
 #include <acm/acm_hooks.h>
 #include <xen/trace.h>
 
-#if defined(CONFIG_X86_64)
-#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#else
-#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY)
-#endif
-
-#define PIN_FAIL(_lbl, _rc, _f, _a...)   \
-    do {                           \
-        DPRINTK( _f, ## _a );      \
-        rc = (_rc);                \
-        goto _lbl;                 \
+#define PIN_FAIL(_lbl, _rc, _f, _a...)          \
+    do {                                        \
+        DPRINTK( _f, ## _a );                   \
+        rc = (_rc);                             \
+        goto _lbl;                              \
     } while ( 0 )
 
 static inline int
@@ -80,7 +74,7 @@
     grant_ref_t    ref;
     struct domain *ld, *rd;
     struct vcpu   *led;
-    u16            dev_hst_ro_flags;
+    u32            dev_hst_ro_flags;
     int            handle;
     u64            addr;
     unsigned long  frame = 0;
@@ -120,13 +114,13 @@
                    (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
     {
         DPRINTK("Bad ref (%d) or flags (%x).\n", ref, dev_hst_ro_flags);
-        (void)__put_user(GNTST_bad_gntref, &uop->handle);
+        (void)__put_user(GNTST_bad_gntref, &uop->status);
         return GNTST_bad_gntref;
     }
 
     if ( acm_pre_grant_map_ref(dom) )
     {
-        (void)__put_user(GNTST_permission_denied, &uop->handle);
+        (void)__put_user(GNTST_permission_denied, &uop->status);
         return GNTST_permission_denied;
     }
 
@@ -136,7 +130,7 @@
         if ( rd != NULL )
             put_domain(rd);
         DPRINTK("Could not find domain %d\n", dom);
-        (void)__put_user(GNTST_bad_domain, &uop->handle);
+        (void)__put_user(GNTST_bad_domain, &uop->status);
         return GNTST_bad_domain;
     }
 
@@ -151,7 +145,7 @@
         {
             put_domain(rd);
             DPRINTK("Maptrack table is at maximum size.\n");
-            (void)__put_user(GNTST_no_device_space, &uop->handle);
+            (void)__put_user(GNTST_no_device_space, &uop->status);
             return GNTST_no_device_space;
         }
 
@@ -161,7 +155,7 @@
         {
             put_domain(rd);
             DPRINTK("No more map handles available.\n");
-            (void)__put_user(GNTST_no_device_space, &uop->handle);
+            (void)__put_user(GNTST_no_device_space, &uop->status);
             return GNTST_no_device_space;
         }
 
@@ -240,7 +234,7 @@
 
         /* rmb(); */ /* not on x86 */
 
-        frame = __gpfn_to_mfn_foreign(rd, sha->frame);
+        frame = __gpfn_to_mfn(rd, sha->frame);
 
         if ( unlikely(!pfn_valid(frame)) ||
              unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
@@ -336,20 +330,7 @@
 
     if ( dev_hst_ro_flags & GNTMAP_host_map )
     {
-        /* Write update into the pagetable. */
-        l1_pgentry_t pte;
-        pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS);
-        
-        if ( (dev_hst_ro_flags & GNTMAP_application_map) )
-            l1e_add_flags(pte,_PAGE_USER);
-        if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
-            l1e_add_flags(pte,_PAGE_RW);
-
-        if ( dev_hst_ro_flags & GNTMAP_contains_pte )
-            rc = update_grant_pte_mapping(addr, pte, led);
-        else
-            rc = update_grant_va_mapping(addr, pte, led);
-
+        rc = create_grant_host_mapping(addr, frame, dev_hst_ro_flags);
         if ( rc < 0 )
         {
             /* Failure: undo and abort. */
@@ -389,6 +370,7 @@
 
     (void)__put_user((u64)frame << PAGE_SHIFT, &uop->dev_bus_addr);
     (void)__put_user(handle, &uop->handle);
+    (void)__put_user(GNTST_okay, &uop->status);
 
     put_domain(rd);
     return rc;
@@ -396,7 +378,7 @@
 
  unlock_out:
     spin_unlock(&rd->grant_table->lock);
-    (void)__put_user(rc, &uop->handle);
+    (void)__put_user(rc, &uop->status);
     put_maptrack_handle(ld->grant_table, handle);
     return rc;
 }
@@ -419,7 +401,7 @@
 {
     domid_t          dom;
     grant_ref_t      ref;
-    u16              handle;
+    grant_handle_t   handle;
     struct domain   *ld, *rd;
     active_grant_entry_t *act;
     grant_entry_t   *sha;
@@ -494,16 +476,8 @@
          (flags & GNTMAP_host_map) &&
          ((act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) > 0))
     {
-        if ( flags & GNTMAP_contains_pte )
-        {
-            if ( (rc = clear_grant_pte_mapping(addr, frame, ld)) < 0 )
-                goto unmap_out;
-        }
-        else
-        {
-            if ( (rc = clear_grant_va_mapping(addr, frame)) < 0 )
-                goto unmap_out;
-        }
+        if ( (rc = destroy_grant_host_mapping(addr, frame, flags)) < 0 )
+            goto unmap_out;
 
         map->ref_and_flags &= ~GNTMAP_host_map;
 
@@ -518,13 +492,12 @@
     }
 
     /* If just unmapped a writable mapping, mark as dirtied */
-    if ( unlikely(shadow_mode_log_dirty(rd)) &&
-        !( flags & GNTMAP_readonly ) )
-         mark_dirty(rd, frame);
+    if ( !(flags & GNTMAP_readonly) )
+         gnttab_log_dirty(rd, frame);
 
     /* If the last writable mapping has been removed, put_page_type */
-    if ( ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask) ) == 0) &&
-         ( !( flags & GNTMAP_readonly ) ) )
+    if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
+         !(flags & GNTMAP_readonly) )
     {
         clear_bit(_GTF_writing, &sha->flags);
         put_page_type(&frame_table[frame]);
@@ -605,9 +578,8 @@
         ASSERT(d->grant_table != NULL);
         (void)put_user(GNTST_okay, &uop->status);
         for ( i = 0; i < op.nr_frames; i++ )
-            (void)put_user(
-                (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
-                &uop->frame_list[i]);
+            (void)put_user(gnttab_shared_mfn(d, d->grant_table, i),
+                           &uop->frame_list[i]);
     }
 
     put_domain(d);
@@ -704,80 +676,45 @@
     struct domain *d = current->domain;
     struct domain *e;
     struct pfn_info *page;
-    u32 _d, _nd, x, y;
     int i;
-    int result = GNTST_okay;
     grant_entry_t *sha;
+    gnttab_transfer_t gop;
 
     for ( i = 0; i < count; i++ )
     {
-        gnttab_transfer_t *gop = &uop[i];
-
-        page = &frame_table[gop->mfn];
-        
-        if ( unlikely(IS_XEN_HEAP_FRAME(page)))
+        /* Read from caller address space. */
+        if ( unlikely(__copy_from_user(&gop, &uop[i], sizeof(gop))) )
+        {
+            DPRINTK("gnttab_transfer: error reading req %d/%d\n", i, count);
+            (void)__put_user(GNTST_bad_page, &uop[i].status);
+            return -EFAULT; /* This is *very* fatal. */
+        }
+
+        /* Check the passed page frame for basic validity. */
+        page = &frame_table[gop.mfn];
+        if ( unlikely(!pfn_valid(gop.mfn) || IS_XEN_HEAP_FRAME(page)) )
         { 
-            printk("gnttab_transfer: xen heap frame mfn=%lx\n", 
-                   (unsigned long) gop->mfn);
-            gop->status = GNTST_bad_virt_addr;
+            DPRINTK("gnttab_transfer: out-of-range or xen frame %lx\n",
+                    (unsigned long)gop.mfn);
+            (void)__put_user(GNTST_bad_page, &uop[i].status);
             continue;
         }
-        
-        if ( unlikely(!pfn_valid(page_to_pfn(page))) )
-        {
-            printk("gnttab_transfer: invalid pfn for mfn=%lx\n", 
-                   (unsigned long) gop->mfn);
-            gop->status = GNTST_bad_virt_addr;
+
+        if ( steal_page_for_grant_transfer(d, page) < 0 )
+        {
+            (void)__put_user(GNTST_bad_page, &uop[i].status);
             continue;
         }
 
-        if ( unlikely((e = find_domain_by_id(gop->domid)) == NULL) )
-        {
-            printk("gnttab_transfer: can't find domain %d\n", gop->domid);
-            gop->status = GNTST_bad_domain;
+        /* Find the target domain. */
+        if ( unlikely((e = find_domain_by_id(gop.domid)) == NULL) )
+        {
+            DPRINTK("gnttab_transfer: can't find domain %d\n", gop.domid);
+            (void)__put_user(GNTST_bad_domain, &uop[i].status);
+            page->count_info &= ~(PGC_count_mask|PGC_allocated);
+            free_domheap_page(page);
             continue;
         }
-
-        spin_lock(&d->page_alloc_lock);
-
-        /*
-         * The tricky bit: atomically release ownership while
-         * there is just one benign reference to the page
-         * (PGC_allocated). If that reference disappears then the
-         * deallocation routine will safely spin.
-         */
-        _d  = pickle_domptr(d);
-        _nd = page->u.inuse._domain;
-        y   = page->count_info;
-        do {
-            x = y;
-            if (unlikely((x & (PGC_count_mask|PGC_allocated)) !=
-                         (1 | PGC_allocated)) || unlikely(_nd != _d)) {
-                printk("gnttab_transfer: Bad page values %p: ed=%p(%u), sd=%p,"
-                       " caf=%08x, taf=%" PRtype_info "\n", 
-                       (void *) page_to_pfn(page),
-                        d, d->domain_id, unpickle_domptr(_nd), x, 
-                        page->u.inuse.type_info);
-                spin_unlock(&d->page_alloc_lock);
-                put_domain(e);
-                return 0;
-            }
-            __asm__ __volatile__(
-                LOCK_PREFIX "cmpxchg8b %2"
-                : "=d" (_nd), "=a" (y),
-                "=m" (*(volatile u64 *)(&page->count_info))
-                : "0" (_d), "1" (x), "c" (NULL), "b" (x) );
-        } while (unlikely(_nd != _d) || unlikely(y != x));
-
-        /*
-         * Unlink from 'd'. At least one reference remains (now
-         * anonymous), so noone else is spinning to try to delete
-         * this page from 'd'.
-         */
-        d->tot_pages--;
-        list_del(&page->list);
-
-        spin_unlock(&d->page_alloc_lock);
 
         spin_lock(&e->page_alloc_lock);
 
@@ -788,16 +725,19 @@
          */
         if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) ||
              unlikely(e->tot_pages >= e->max_pages) ||
-             unlikely(!gnttab_prepare_for_transfer(e, d, gop->ref)) )
-        {
-            DPRINTK("gnttab_transfer: Transferee has no reservation headroom "
-                    "(%d,%d) or provided a bad grant ref (%08x) or "
-                    "is dying (%lx)\n",
-                    e->tot_pages, e->max_pages, gop->ref, e->domain_flags);
+             unlikely(!gnttab_prepare_for_transfer(e, d, gop.ref)) )
+        {
+            if ( !test_bit(_DOMF_dying, &e->domain_flags) )
+                DPRINTK("gnttab_transfer: Transferee has no reservation "
+                        "headroom (%d,%d) or provided a bad grant ref (%08x) "
+                        "or is dying (%lx)\n",
+                        e->tot_pages, e->max_pages, gop.ref, e->domain_flags);
             spin_unlock(&e->page_alloc_lock);
             put_domain(e);
-            gop->status = result = GNTST_general_error;
-            break;
+            (void)__put_user(GNTST_general_error, &uop[i].status);
+            page->count_info &= ~(PGC_count_mask|PGC_allocated);
+            free_domheap_page(page);
+            continue;
         }
 
         /* Okay, add the page to 'e'. */
@@ -805,23 +745,23 @@
             get_knownalive_domain(e);
         list_add_tail(&page->list, &e->page_list);
         page_set_owner(page, e);
-        
+
         spin_unlock(&e->page_alloc_lock);
 
         TRACE_1D(TRC_MEM_PAGE_GRANT_TRANSFER, e->domain_id);
-        
+
         /* Tell the guest about its new page frame. */
-        sha = &e->grant_table->shared[gop->ref];
-        sha->frame = gop->mfn;
+        sha = &e->grant_table->shared[gop.ref];
+        sha->frame = gop.mfn;
         wmb();
         sha->flags |= GTF_transfer_completed;
-        
+
         put_domain(e);
-        
-        gop->status = GNTST_okay;
-    }
-
-    return result;
+
+        (void)__put_user(GNTST_okay, &uop[i].status);
+    }
+
+    return 0;
 }
 
 long 
@@ -877,108 +817,6 @@
     return rc;
 }
 
-int
-gnttab_check_unmap(
-    struct domain *rd, struct domain *ld, unsigned long frame, int readonly)
-{
-    /* Called when put_page is invoked on a page belonging to a foreign domain.
-     * Instead of decrementing the frame table ref count, locate the grant
-     * table entry, if any, and if found, decrement that count.
-     * Called a _lot_ at domain creation because pages mapped by priv domains
-     * also traverse this.
-     */
-    
-    /* Note: If the same frame is mapped multiple times, and then one of
-     *       the ptes is overwritten, which maptrack handle gets invalidated?
-     * Advice: Don't do it. Explicitly unmap.
-     */
-    
-    unsigned int handle, ref, refcount;
-    grant_table_t        *lgt, *rgt;
-    active_grant_entry_t *act;
-    grant_mapping_t      *map;
-    int found = 0;
-    
-    lgt = ld->grant_table;
-    
-    /* Fast exit if we're not mapping anything using grant tables */
-    if ( lgt->map_count == 0 )
-        return 0;
-    
-    if ( get_domain(rd) == 0 )
-    {
-        DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n",
-                rd->domain_id);
-        return 0;
-    }
-    
-    rgt = rd->grant_table;
-    
-    for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) {
-
-        map = &lgt->maptrack[handle];
-            
-        if ( map->domid != rd->domain_id )
-            continue;
-        
-        if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
-             ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) {
-
-            ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT);
-            act = &rgt->active[ref];
-                    
-            spin_lock(&rgt->lock);
-                    
-            if ( act->frame != frame ) {
-                spin_unlock(&rgt->lock);
-                continue;
-            }
-                    
-            refcount = act->pin & ( readonly ? GNTPIN_hstr_mask
-                                    : GNTPIN_hstw_mask );
-
-            if ( refcount == 0 ) {
-                spin_unlock(&rgt->lock);
-                continue;
-            }
-                    
-            /* gotcha */
-            DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
-                    rd->domain_id, ld->domain_id, frame, readonly);
-                    
-            if ( readonly )
-                act->pin -= GNTPIN_hstr_inc;
-            else {
-                act->pin -= GNTPIN_hstw_inc;
-                            
-                /* any more granted writable mappings? */
-                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) {
-                    clear_bit(_GTF_writing, &rgt->shared[ref].flags);
-                    put_page_type(&frame_table[frame]);
-                }
-            }
-                
-            if ( act->pin == 0 ) {
-                clear_bit(_GTF_reading, &rgt->shared[ref].flags);
-                put_page(&frame_table[frame]);
-            }
-
-            spin_unlock(&rgt->lock);
-                    
-            clear_bit(GNTMAP_host_map, &map->ref_and_flags);
-                    
-            if ( !(map->ref_and_flags & GNTMAP_device_map) )
-                put_maptrack_handle(lgt, handle);
-                    
-            found = 1;
-            break;
-        }
-    }
-    put_domain(rd);
-    
-    return found;
-}
-
 int 
 gnttab_prepare_for_transfer(
     struct domain *rd, struct domain *ld, grant_ref_t ref)
@@ -1096,14 +934,7 @@
     memset(t->shared, 0, NR_GRANT_FRAMES * PAGE_SIZE);
 
     for ( i = 0; i < NR_GRANT_FRAMES; i++ )
-    {
-        SHARE_PFN_WITH_DOMAIN(
-            virt_to_page((char *)t->shared + (i * PAGE_SIZE)),
-            d);
-        set_pfn_from_mfn(
-            (virt_to_phys(t->shared) >> PAGE_SHIFT) + i,
-            INVALID_M2P_ENTRY);
-    }
+        gnttab_create_shared_mfn(d, t, i);
 
     /* Okay, install the structure. */
     wmb(); /* avoid races with lock-free access to d->grant_table */
@@ -1121,70 +952,85 @@
 }
 
 void
-gnttab_release_dev_mappings(grant_table_t *gt)
-{
-    grant_mapping_t        *map;
-    domid_t                 dom;
-    grant_ref_t             ref;
-    u16                     handle;
-    struct domain          *ld, *rd;
-    unsigned long           frame;
-    active_grant_entry_t   *act;
-    grant_entry_t          *sha;
-
-    ld = current->domain;
+gnttab_release_mappings(
+    struct domain *d)
+{
+    grant_table_t        *gt = d->grant_table;
+    grant_mapping_t      *map;
+    grant_ref_t           ref;
+    grant_handle_t        handle;
+    struct domain        *rd;
+    active_grant_entry_t *act;
+    grant_entry_t        *sha;
+
+    BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
 
     for ( handle = 0; handle < gt->maptrack_limit; handle++ )
     {
         map = &gt->maptrack[handle];
-
-        if ( !(map->ref_and_flags & GNTMAP_device_map) )
+        if ( !(map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) )
             continue;
 
-        dom = map->domid;
         ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
 
         DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
-                handle, ref, map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
-
-        if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
-             unlikely(ld == rd) )
-        {
-            if ( rd != NULL )
-                put_domain(rd);
-            printk(KERN_WARNING "Grant release: No dom%d\n", dom);
-            continue;
-        }
+                handle, ref, map->ref_and_flags & MAPTRACK_GNTMAP_MASK,
+                map->domid);
+
+        rd = find_domain_by_id(map->domid);
+        BUG_ON(rd == NULL);
+
+        spin_lock(&rd->grant_table->lock);
 
         act = &rd->grant_table->active[ref];
         sha = &rd->grant_table->shared[ref];
 
-        spin_lock(&rd->grant_table->lock);
-
-        if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) )
-        {
-            frame = act->frame;
-
-            if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) &&
-                 ( (act->pin & GNTPIN_devw_mask) >  0 ) )
+        if ( map->ref_and_flags & GNTMAP_readonly )
+        {
+            if ( map->ref_and_flags & GNTMAP_device_map )
+            {
+                BUG_ON((act->pin & GNTPIN_devr_mask) == 0);
+                act->pin -= GNTPIN_devr_inc;
+            }
+
+            if ( map->ref_and_flags & GNTMAP_host_map )
+            {
+                BUG_ON((act->pin & GNTPIN_hstr_mask) == 0);
+                act->pin -= GNTPIN_hstr_inc;
+            }
+        }
+        else
+        {
+            if ( map->ref_and_flags & GNTMAP_device_map )
+            {
+                BUG_ON((act->pin & GNTPIN_devw_mask) == 0);
+                act->pin -= GNTPIN_devw_inc;
+            }
+
+            if ( map->ref_and_flags & GNTMAP_host_map )
+            {
+                BUG_ON((act->pin & GNTPIN_hstw_mask) == 0);
+                act->pin -= GNTPIN_hstw_inc;
+            }
+
+            if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
             {
                 clear_bit(_GTF_writing, &sha->flags);
-                put_page_type(&frame_table[frame]);
+                put_page_type(&frame_table[act->frame]);
             }
-
-            map->ref_and_flags &= ~GNTMAP_device_map;
-            act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask);
-            if ( act->pin == 0 )
-            {
-                clear_bit(_GTF_reading, &sha->flags);
-                map->ref_and_flags = 0;
-                put_page(&frame_table[frame]);
-            }
+        }
+
+        if ( act->pin == 0 )
+        {
+            clear_bit(_GTF_reading, &sha->flags);
+            put_page(&frame_table[act->frame]);
         }
 
         spin_unlock(&rd->grant_table->lock);
 
         put_domain(rd);
+
+        map->ref_and_flags = 0;
     }
 }
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/memory.c
--- a/xen/common/memory.c       Fri Dec  2 18:12:11 2005
+++ b/xen/common/memory.c       Fri Dec  2 18:52:25 2005
@@ -136,6 +136,7 @@
     struct domain *d;
     int rc, start_extent, op, flags = 0, preempted = 0;
     struct xen_memory_reservation reservation;
+    domid_t domid;
 
     op = cmd & ((1 << START_EXTENT_SHIFT) - 1);
 
@@ -191,13 +192,30 @@
         break;
 
     case XENMEM_maximum_ram_page:
-        if ( put_user(max_page, (unsigned long *)arg) )
+        rc = max_page;
+        break;
+
+    case XENMEM_current_reservation:
+    case XENMEM_maximum_reservation:
+        if ( get_user(domid, (domid_t *)arg) )
             return -EFAULT;
-        rc = 0;
+
+        if ( likely((domid = (unsigned long)arg) == DOMID_SELF) )
+            d = current->domain;
+        else if ( !IS_PRIV(current->domain) )
+            return -EPERM;
+        else if ( (d = find_domain_by_id(domid)) == NULL )
+            return -ESRCH;
+
+        rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages;
+
+        if ( unlikely(domid != DOMID_SELF) )
+            put_domain(d);
+
         break;
 
     default:
-        rc = -ENOSYS;
+        rc = arch_memory_op(op, arg);
         break;
     }
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Fri Dec  2 18:12:11 2005
+++ b/xen/common/page_alloc.c   Fri Dec  2 18:52:25 2005
@@ -645,7 +645,9 @@
     }
     else
     {
-        /* Freeing an anonymous domain-heap page. */
+        /* Freeing anonymous domain-heap pages. */
+        for ( i = 0; i < (1 << order); i++ )
+            pg[i].u.free.cpumask = CPU_MASK_NONE;
         free_heap_pages(pfn_dom_zone_type(page_to_pfn(pg)), pg, order);
         drop_dom_ref = 0;
     }
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/sched_bvt.c
--- a/xen/common/sched_bvt.c    Fri Dec  2 18:12:11 2005
+++ b/xen/common/sched_bvt.c    Fri Dec  2 18:52:25 2005
@@ -67,6 +67,7 @@
 #define MCU            (s32)MICROSECS(100)    /* Minimum unit */
 #define MCU_ADVANCE    10                     /* default weight */
 #define TIME_SLOP      (s32)MICROSECS(50)     /* allow time to slip a bit */
+#define CTX_MIN        (s32)MICROSECS(10)     /* Low limit for ctx_allow */
 static s32 ctx_allow = (s32)MILLISECS(5);     /* context switch allowance */
 
 static inline void __add_to_runqueue_head(struct vcpu *d)
@@ -297,7 +298,11 @@
     if ( cmd->direction == SCHED_INFO_PUT )
         ctx_allow = params->ctx_allow;
     else
+    {
+        if ( ctx_allow < CTX_MIN )
+            ctx_allow = CTX_MIN;
         params->ctx_allow = ctx_allow;
+    }
     
     return 0;
 }
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Fri Dec  2 18:12:11 2005
+++ b/xen/common/sched_sedf.c   Fri Dec  2 18:52:25 2005
@@ -704,11 +704,12 @@
     struct list_head     *waitq    = WAITQ(cpu);
 #if (EXTRA > EXTRA_OFF)
     struct sedf_vcpu_info *inf     = EDOM_INFO(current);
-    struct list_head     *extraq[] = {EXTRAQ(cpu, EXTRA_PEN_Q),
-                                      EXTRAQ(cpu, EXTRA_UTIL_Q)};
-#endif
-    struct task_slice          ret;
-    /*int i = 0;*/
+    struct list_head      *extraq[] = {
+        EXTRAQ(cpu, EXTRA_PEN_Q), EXTRAQ(cpu, EXTRA_UTIL_Q)};
+#endif
+    struct sedf_vcpu_info *runinf, *waitinf;
+    struct task_slice      ret;
+
     /*idle tasks don't need any of the following stuf*/
     if (is_idle_task(current->domain))
         goto check_waitq;
@@ -737,7 +738,6 @@
  
     /*now simply pick the first domain from the runqueue, which has the
       earliest deadline, because the list is sorted*/
-    struct sedf_vcpu_info *runinf, *waitinf;
  
     if (!list_empty(runq)) {
         runinf   = list_entry(runq->next,struct sedf_vcpu_info,list);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/schedule.c
--- a/xen/common/schedule.c     Fri Dec  2 18:12:11 2005
+++ b/xen/common/schedule.c     Fri Dec  2 18:52:25 2005
@@ -115,7 +115,7 @@
 
     if ( vcpu_id != 0 )
     {
-        v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
+        v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
         d->vcpu[v->vcpu_id-1]->next_in_list = v;
         set_bit(_VCPUF_down, &v->vcpu_flags);
     }
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/trace.c
--- a/xen/common/trace.c        Fri Dec  2 18:12:11 2005
+++ b/xen/common/trace.c        Fri Dec  2 18:52:25 2005
@@ -89,7 +89,6 @@
     {
         buf = t_bufs[i] = (struct t_buf *)&rawbuf[i*opt_tbuf_size*PAGE_SIZE];
         buf->cons = buf->prod = 0;
-        buf->nr_recs = nr_recs;
         t_recs[i] = (struct t_rec *)(buf + 1);
     }
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/common/xmalloc.c
--- a/xen/common/xmalloc.c      Fri Dec  2 18:12:11 2005
+++ b/xen/common/xmalloc.c      Fri Dec  2 18:52:25 2005
@@ -111,9 +111,7 @@
     unsigned long flags;
 
     /* We currently always return cacheline aligned. */
-#ifndef __ia64__
     BUG_ON(align > SMP_CACHE_BYTES);
-#endif
 
     /* Add room for header, pad to align next header. */
     size += sizeof(struct xmalloc_hdr);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Fri Dec  2 18:12:11 2005
+++ b/xen/drivers/char/ns16550.c        Fri Dec  2 18:52:25 2005
@@ -29,7 +29,11 @@
     int baud, data_bits, parity, stop_bits, irq;
     unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
     char *remapped_io_base;  /* Remapped virtual address of mmap I/O.  */ 
+    /* UART with IRQ line: interrupt-driven I/O. */
     struct irqaction irqaction;
+    /* UART with no IRQ line: periodically-polled I/O. */
+    struct ac_timer timer;
+    unsigned int timeout_ms;
 } ns16550_com[2] = { { 0 } };
 
 /* Register offsets */
@@ -121,6 +125,21 @@
     }
 }
 
+static void ns16550_poll(void *data)
+{
+    struct serial_port *port = data;
+    struct ns16550 *uart = port->uart;
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+    while ( ns_read_reg(uart, LSR) & LSR_DR )
+        serial_rx_interrupt(port, regs);
+
+    if ( ns_read_reg(uart, LSR) & LSR_THRE )
+        serial_tx_interrupt(port, regs);
+
+    set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+}
+
 static int ns16550_tx_empty(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
@@ -181,24 +200,36 @@
 static void ns16550_init_postirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
-    int rc;
-
-    if ( uart->irq <= 0 )
+    int rc, bits;
+
+    if ( uart->irq < 0 )
         return;
 
     serial_async_transmit(port);
 
-    uart->irqaction.handler = ns16550_interrupt;
-    uart->irqaction.name    = "ns16550";
-    uart->irqaction.dev_id  = port;
-    if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 )
-        printk("ERROR: Failed to allocate na16550 IRQ %d\n", uart->irq);
-
-    /* Master interrupt enable; also keep DTR/RTS asserted. */
-    ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);
-
-    /* Enable receive and transmit interrupts. */
-    ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);
+    if ( uart->irq == 0 )
+    {
+        /* Polled mode. Calculate time to fill RX FIFO and/or empty TX FIFO. */
+        bits = uart->data_bits + uart->stop_bits + !!uart->parity;
+        uart->timeout_ms = max_t(
+            unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);
+        init_ac_timer(&uart->timer, ns16550_poll, port, 0);
+        set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+    }
+    else
+    {
+        uart->irqaction.handler = ns16550_interrupt;
+        uart->irqaction.name    = "ns16550";
+        uart->irqaction.dev_id  = port;
+        if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 )
+            printk("ERROR: Failed to allocate na16550 IRQ %d\n", uart->irq);
+
+        /* Master interrupt enable; also keep DTR/RTS asserted. */
+        ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);
+
+        /* Enable receive and transmit interrupts. */
+        ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);
+    }
 }
 
 #ifdef CONFIG_X86
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/acm/acm_core.h
--- a/xen/include/acm/acm_core.h        Fri Dec  2 18:12:11 2005
+++ b/xen/include/acm/acm_core.h        Fri Dec  2 18:52:25 2005
@@ -28,9 +28,6 @@
 struct acm_binary_policy {
     u16 primary_policy_code;
     u16 secondary_policy_code;
-    void *primary_binary_policy;                                 
-    void *secondary_binary_policy;
- 
 };
 
 struct chwall_binary_policy {
@@ -53,6 +50,7 @@
 };
 
 /* global acm policy */
+extern u16 acm_active_security_policy;
 extern struct acm_binary_policy acm_bin_pol;
 extern struct chwall_binary_policy chwall_bin_pol;
 extern struct ste_binary_policy ste_bin_pol;
@@ -120,6 +118,7 @@
 /* protos */
 int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
 void acm_free_domain_ssid(struct acm_ssid_domain *ssid);
+int acm_init_binary_policy(u32 policy_code);
 int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer);
 int acm_get_policy(void *buf, u32 buf_size);
 int acm_dump_statistics(void *buf, u16 buf_size);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h       Fri Dec  2 18:12:11 2005
+++ b/xen/include/acm/acm_hooks.h       Fri Dec  2 18:52:25 2005
@@ -127,7 +127,7 @@
 # define traceprintk(fmt, args...)
 #endif
 
-#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+#ifndef ACM_SECURITY
 
 static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid) 
 { return 0; }
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-ia64/mm.h Fri Dec  2 18:52:25 2005
@@ -82,7 +82,7 @@
 #define PGT_l2_page_table   (2<<29) /* using this page as an L2 page table? */
 #define PGT_l3_page_table   (3<<29) /* using this page as an L3 page table? */
 #define PGT_l4_page_table   (4<<29) /* using this page as an L4 page table? */
-#define PGT_writeable_page  (5<<29) /* has writable mappings of this page? */
+#define PGT_writable_page   (5<<29) /* has writable mappings of this page? */
 #define PGT_type_mask       (5<<29) /* Bits 29-31. */
 
  /* Has this page been validated for use as its current type? */
@@ -440,4 +440,7 @@
 #define __gpa_to_mpa(_d, gpa)   \
     ((__gpfn_to_mfn((_d),(gpa)>>PAGE_SHIFT)<<PAGE_SHIFT)|((gpa)&~PAGE_MASK))
 
+/* Arch-specific portion of memory_op hypercall. */
+#define arch_memory_op(op, arg) (-ENOSYS)
+
 #endif /* __ASM_IA64_MM_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/apic.h
--- a/xen/include/asm-x86/apic.h        Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/apic.h        Fri Dec  2 18:52:25 2005
@@ -43,7 +43,7 @@
 
 static __inline void apic_write_atomic(unsigned long reg, u32 v)
 {
-       xchg((volatile u32 *)(APIC_BASE+reg), v);
+       (void)xchg((volatile u32 *)(APIC_BASE+reg), v);
 }
 
 static __inline u32 apic_read(unsigned long reg)
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/apicdef.h
--- a/xen/include/asm-x86/apicdef.h     Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/apicdef.h     Fri Dec  2 18:52:25 2005
@@ -16,6 +16,7 @@
 #define                        GET_APIC_VERSION(x)     ((x)&0xFF)
 #define                        GET_APIC_MAXLVT(x)      (((x)>>16)&0xFF)
 #define                        APIC_INTEGRATED(x)      ((x)&0xF0)
+#define                        APIC_XAPIC(x)           ((x) >= 0x14)
 #define                APIC_TASKPRI    0x80
 #define                        APIC_TPRI_MASK          0xFF
 #define                APIC_ARBPRI     0x90
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/cpufeature.h  Fri Dec  2 18:52:25 2005
@@ -94,7 +94,7 @@
 #define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
 #define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
 
-#define cpu_has_fpu            boot_cpu_has(X86_FEATURE_FPU)
+#ifdef __i386__
 #define cpu_has_vme            boot_cpu_has(X86_FEATURE_VME)
 #define cpu_has_de             boot_cpu_has(X86_FEATURE_DE)
 #define cpu_has_pse            boot_cpu_has(X86_FEATURE_PSE)
@@ -102,7 +102,6 @@
 #define cpu_has_pae            boot_cpu_has(X86_FEATURE_PAE)
 #define cpu_has_pge            boot_cpu_has(X86_FEATURE_PGE)
 #define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
-#define cpu_has_sep            boot_cpu_has(X86_FEATURE_SEP)
 #define cpu_has_mtrr           boot_cpu_has(X86_FEATURE_MTRR)
 #define cpu_has_mmx            boot_cpu_has(X86_FEATURE_MMX)
 #define cpu_has_fxsr           boot_cpu_has(X86_FEATURE_FXSR)
@@ -115,10 +114,29 @@
 #define cpu_has_k6_mtrr                boot_cpu_has(X86_FEATURE_K6_MTRR)
 #define cpu_has_cyrix_arr      boot_cpu_has(X86_FEATURE_CYRIX_ARR)
 #define cpu_has_centaur_mcr    boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
-#define cpu_has_xstore         boot_cpu_has(X86_FEATURE_XSTORE)
-#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN)
-#define cpu_has_xcrypt         boot_cpu_has(X86_FEATURE_XCRYPT)
-#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN)
+#define cpu_has_clflush                boot_cpu_has(X86_FEATURE_CLFLSH)
+#else /* __x86_64__ */
+#define cpu_has_vme            0
+#define cpu_has_de             1
+#define cpu_has_pse            1
+#define cpu_has_tsc            1
+#define cpu_has_pae            1
+#define cpu_has_pge            1
+#define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
+#define cpu_has_mtrr           1
+#define cpu_has_mmx            1
+#define cpu_has_fxsr           1
+#define cpu_has_xmm            1
+#define cpu_has_xmm2           1
+#define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
+#define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
+#define cpu_has_mp             1
+#define cpu_has_nx             boot_cpu_has(X86_FEATURE_NX)
+#define cpu_has_k6_mtrr                0
+#define cpu_has_cyrix_arr      0
+#define cpu_has_centaur_mcr    0
+#define cpu_has_clflush                boot_cpu_has(X86_FEATURE_CLFLSH)
+#endif
 
 #endif /* __ASM_I386_CPUFEATURE_H */
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/domain.h      Fri Dec  2 18:52:25 2005
@@ -49,8 +49,6 @@
 
     unsigned int shadow_fault_count;
     unsigned int shadow_dirty_count;
-    unsigned int shadow_dirty_net_count;
-    unsigned int shadow_dirty_block_count;
 
     /* full shadow mode */
     struct out_of_sync_entry *out_of_sync; /* list of out-of-sync pages */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/flushtlb.h
--- a/xen/include/asm-x86/flushtlb.h    Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/flushtlb.h    Fri Dec  2 18:52:25 2005
@@ -97,7 +97,7 @@
 extern void flush_tlb_all_pge(void);
 extern void __flush_tlb_mask(cpumask_t mask, unsigned long va);
 #define flush_tlb_mask(mask)       __flush_tlb_mask(mask,FLUSHVA_ALL)
-#define flush_tlb_one_mask(mask,v) __flush_tlb_mask(mask,v)
+#define flush_tlb_one_mask(mask,v) __flush_tlb_mask(mask,(unsigned long)(v))
 #endif
 
 #endif /* __FLUSHTLB_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 
xen/include/asm-x86/mach-generic/mach_apic.h
--- a/xen/include/asm-x86/mach-generic/mach_apic.h      Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/mach-generic/mach_apic.h      Fri Dec  2 18:52:25 2005
@@ -28,4 +28,6 @@
 #define enable_apic_mode (genapic->enable_apic_mode)
 #define phys_pkg_id (genapic->phys_pkg_id)
 
+extern void generic_bigsmp_probe(void);
+
 #endif /* __ASM_MACH_APIC_H */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/mm.h  Fri Dec  2 18:52:25 2005
@@ -379,18 +379,9 @@
 
 void propagate_page_fault(unsigned long addr, u16 error_code);
 
-extern int __sync_lazy_execstate(void);
-
-/*
- * Caller must own d's BIGLOCK, is responsible for flushing the TLB, and must 
- * hold a reference to the page.
- */
-int update_grant_va_mapping(
-    unsigned long va, l1_pgentry_t _nl1e, struct vcpu *v);
-int update_grant_pte_mapping(
-    unsigned long pte_addr, l1_pgentry_t _nl1e, struct vcpu *v);
-int clear_grant_va_mapping(unsigned long addr, unsigned long frame);
-int clear_grant_pte_mapping(
-    unsigned long addr, unsigned long frame, struct domain *d);
+int __sync_lazy_execstate(void);
+
+/* Arch-specific portion of memory_op hypercall. */
+long arch_memory_op(int op, void *arg);
 
 #endif /* __ASM_X86_MM_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/mpspec.h
--- a/xen/include/asm-x86/mpspec.h      Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/mpspec.h      Fri Dec  2 18:52:25 2005
@@ -11,6 +11,7 @@
 extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 
+extern unsigned int def_to_bigsmp;
 extern unsigned int boot_cpu_physical_apicid;
 extern int smp_found_config;
 extern void find_smp_config (void);
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h        Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/page.h        Fri Dec  2 18:52:25 2005
@@ -273,6 +273,24 @@
 #define _PAGE_AVAIL2   0x800U
 #define _PAGE_AVAIL    0xE00U
 
+/*
+ * Debug option: Ensure that granted mappings are not implicitly unmapped.
+ * WARNING: This will need to be disabled to run OSes that use the spare PTE
+ * bits themselves (e.g., *BSD).
+ */
+#ifndef NDEBUG
+#define _PAGE_GNTTAB   _PAGE_AVAIL2
+#else
+#define _PAGE_GNTTAB   0
+#endif
+
+/*
+ * Disallow unused flag bits plus PAT, PSE and GLOBAL. Also disallow GNTTAB
+ * if we are using it for grant-table debugging. Permit the NX bit if the
+ * hardware supports it.
+ */
+#define BASE_DISALLOW_MASK ((0xFFFFF180U | _PAGE_GNTTAB) & ~_PAGE_NX)
+
 #define __PAGE_HYPERVISOR \
     (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 #define __PAGE_HYPERVISOR_NOCACHE \
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/shadow.h      Fri Dec  2 18:52:25 2005
@@ -131,10 +131,10 @@
 extern void remove_shadow(struct domain *d, unsigned long gpfn, u32 stype);
 
 extern void shadow_l1_normal_pt_update(struct domain *d,
-                                       unsigned long pa, l1_pgentry_t l1e,
+                                       physaddr_t pa, l1_pgentry_t l1e,
                                        struct domain_mmap_cache *cache);
 extern void shadow_l2_normal_pt_update(struct domain *d,
-                                       unsigned long pa, l2_pgentry_t l2e,
+                                       physaddr_t pa, l2_pgentry_t l2e,
                                        struct domain_mmap_cache *cache);
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/page-guest32.h>
@@ -148,12 +148,12 @@
 
 extern unsigned long gva_to_gpa(unsigned long gva);
 extern void shadow_l3_normal_pt_update(struct domain *d,
-                                       unsigned long pa, l3_pgentry_t l3e,
+                                       physaddr_t pa, l3_pgentry_t l3e,
                                        struct domain_mmap_cache *cache);
 #endif
 #if CONFIG_PAGING_LEVELS >= 4
 extern void shadow_l4_normal_pt_update(struct domain *d,
-                                       unsigned long pa, l4_pgentry_t l4e,
+                                       physaddr_t pa, l4_pgentry_t l4e,
                                        struct domain_mmap_cache *cache);
 #endif
 extern int shadow_do_update_va_mapping(unsigned long va,
@@ -173,11 +173,12 @@
 static inline int page_is_page_table(struct pfn_info *page)
 {
     struct domain *owner = page_get_owner(page);
+    u32 type_info;
 
     if ( owner && shadow_mode_refcounts(owner) )
         return page->count_info & PGC_page_table;
 
-    u32 type_info = page->u.inuse.type_info & PGT_type_mask;
+    type_info = page->u.inuse.type_info & PGT_type_mask;
     return type_info && (type_info <= PGT_l4_page_table);
 }
 
@@ -284,23 +285,19 @@
 
 #define __mfn_to_gpfn(_d, mfn)                         \
     ( (shadow_mode_translate(_d))                      \
-      ? get_pfn_from_mfn(mfn)                                   \
+      ? get_pfn_from_mfn(mfn)                          \
       : (mfn) )
 
 #define __gpfn_to_mfn(_d, gpfn)                        \
     ({                                                 \
-        ASSERT(current->domain == (_d));               \
-        (shadow_mode_translate(_d))                    \
-        ? get_mfn_from_pfn(gpfn)                \
+        unlikely(shadow_mode_translate(_d))            \
+        ? (likely(current->domain == (_d))             \
+           ? get_mfn_from_pfn(gpfn)                    \
+           : get_mfn_from_pfn_foreign(_d, gpfn))       \
         : (gpfn);                                      \
     })
 
-#define __gpfn_to_mfn_foreign(_d, gpfn)                \
-    ( (shadow_mode_translate(_d))                      \
-      ? gpfn_to_mfn_foreign(_d, gpfn)                  \
-      : (gpfn) )
-
-extern unsigned long gpfn_to_mfn_foreign(
+extern unsigned long get_mfn_from_pfn_foreign(
     struct domain *d, unsigned long gpfn);
 
 /************************************************************************/
@@ -320,7 +317,7 @@
     unsigned long gpfn;    /* why is this here? */
     unsigned long gmfn;
     unsigned long snapshot_mfn;
-    unsigned long writable_pl1e; /* NB: this is a machine address */
+    physaddr_t writable_pl1e; /* NB: this is a machine address */
     unsigned long va;
 };
 
@@ -341,19 +338,15 @@
 #define SHADOW_REFLECTS_SNAPSHOT _PAGE_AVAIL0
 #endif
 
-#ifdef VERBOSE
+#if SHADOW_VERBOSE_DEBUG
 #define SH_LOG(_f, _a...)                                               \
     printk("DOM%uP%u: SH_LOG(%d): " _f "\n",                            \
        current->domain->domain_id , current->processor, __LINE__ , ## _a )
-#else
-#define SH_LOG(_f, _a...) ((void)0)
-#endif
-
-#if SHADOW_VERBOSE_DEBUG
 #define SH_VLOG(_f, _a...)                                              \
     printk("DOM%uP%u: SH_VLOG(%d): " _f "\n",                           \
            current->domain->domain_id, current->processor, __LINE__ , ## _a )
 #else
+#define SH_LOG(_f, _a...) ((void)0)
 #define SH_VLOG(_f, _a...) ((void)0)
 #endif
 
@@ -466,21 +459,18 @@
 
 /************************************************************************/
 
-static inline int __mark_dirty(struct domain *d, unsigned long mfn)
+static inline void __mark_dirty(struct domain *d, unsigned long mfn)
 {
     unsigned long pfn;
-    int           rc = 0;
 
     ASSERT(shadow_lock_is_acquired(d));
+
+    if ( likely(!shadow_mode_log_dirty(d)) || !VALID_MFN(mfn) )
+        return;
+
     ASSERT(d->arch.shadow_dirty_bitmap != NULL);
 
-    if ( !VALID_MFN(mfn) )
-        return rc;
-
-    // N.B. This doesn't use __mfn_to_gpfn().
-    // This wants the nice compact set of PFNs from 0..domain's max,
-    // which __mfn_to_gpfn() only returns for translated domains.
-    //
+    /* We /really/ mean PFN here, even for non-translated guests. */
     pfn = get_pfn_from_mfn(mfn);
 
     /*
@@ -489,16 +479,13 @@
      * Nothing to do here...
      */
     if ( unlikely(IS_INVALID_M2P_ENTRY(pfn)) )
-        return rc;
-
-    if ( likely(pfn < d->arch.shadow_dirty_bitmap_size) )
-    {
-        /* N.B. Can use non-atomic TAS because protected by shadow_lock. */
-        if ( !__test_and_set_bit(pfn, d->arch.shadow_dirty_bitmap) )
-        {
-            d->arch.shadow_dirty_count++;
-            rc = 1;
-        }
+        return;
+
+    /* N.B. Can use non-atomic TAS because protected by shadow_lock. */
+    if ( likely(pfn < d->arch.shadow_dirty_bitmap_size) &&
+         !__test_and_set_bit(pfn, d->arch.shadow_dirty_bitmap) )
+    {
+        d->arch.shadow_dirty_count++;
     }
 #ifndef NDEBUG
     else if ( mfn < max_page )
@@ -511,18 +498,17 @@
                frame_table[mfn].u.inuse.type_info );
     }
 #endif
-
-    return rc;
-}
-
-
-static inline int mark_dirty(struct domain *d, unsigned int mfn)
-{
-    int rc;
-    shadow_lock(d);
-    rc = __mark_dirty(d, mfn);
-    shadow_unlock(d);
-    return rc;
+}
+
+
+static inline void mark_dirty(struct domain *d, unsigned int mfn)
+{
+    if ( unlikely(shadow_mode_log_dirty(d)) )
+    {
+        shadow_lock(d);
+        __mark_dirty(d, mfn);
+        shadow_unlock(d);
+    }
 }
 
 
@@ -564,8 +550,7 @@
     if ( unlikely(shadow_mode_translate(d)) )
         update_hl2e(v, va);
 
-    if ( unlikely(shadow_mode_log_dirty(d)) )
-        __mark_dirty(d, pagetable_get_pfn(v->arch.guest_table));
+    __mark_dirty(d, pagetable_get_pfn(v->arch.guest_table));
 }
 
 static inline void
@@ -606,8 +591,8 @@
         if ( need_flush )
         {
             perfc_incrc(update_hl2e_invlpg);
-            // SMP BUG???
-            local_flush_tlb_one(&linear_pg_table[l1_linear_offset(va)]);
+            flush_tlb_one_mask(v->domain->cpumask,
+                               &linear_pg_table[l1_linear_offset(va)]);
         }
     }
 }
@@ -785,8 +770,7 @@
     SH_VVLOG("l1pte_write_fault: updating spte=0x%" PRIpte " gpte=0x%" PRIpte,
              l1e_get_intpte(spte), l1e_get_intpte(gpte));
 
-    if ( shadow_mode_log_dirty(d) )
-        __mark_dirty(d, gmfn);
+    __mark_dirty(d, gmfn);
 
     if ( mfn_is_page_table(gmfn) )
         shadow_mark_va_out_of_sync(v, gpfn, gmfn, va);
@@ -871,18 +855,7 @@
 
     if ( l2e_get_flags(gpde) & _PAGE_PRESENT )
     {
-        if ( unlikely((current->domain != d) && !shadow_mode_external(d)) )
-        {
-            // Can't use __gpfn_to_mfn() if we don't have one of this domain's
-            // page tables currently installed.
-            // This isn't common -- it only happens during shadow mode setup
-            // and mode changes.
-            //
-            mfn = gpfn_to_mfn_foreign(d, pfn);
-        }
-        else
-            mfn = __gpfn_to_mfn(d, pfn);
-
+        mfn = __gpfn_to_mfn(d, pfn);
         if ( VALID_MFN(mfn) && (mfn < max_page) )
             hl2e = l1e_from_pfn(mfn, __PAGE_HYPERVISOR);
     }
@@ -1323,46 +1296,6 @@
     return pttype;
 }
 
-/*
- * N.B. We can make this locking more fine grained (e.g., per shadow page) if
- * it ever becomes a problem, but since we need a spin lock on the hash table 
- * anyway it's probably not worth being too clever.
- */
-static inline unsigned long get_shadow_status(
-    struct domain *d, unsigned long gpfn, unsigned long stype)
-{
-    unsigned long res;
-
-    ASSERT(shadow_mode_enabled(d));
-
-    /*
-     * If we get here we know that some sort of update has happened to the
-     * underlying page table page: either a PTE has been updated, or the page
-     * has changed type. If we're in log dirty mode, we should set the
-     * appropriate bit in the dirty bitmap.
-     * N.B. The VA update path doesn't use this and is handled independently. 
-     *
-     * XXX need to think this through for vmx guests, but probably OK
-     */
-
-    shadow_lock(d);
-
-    if ( shadow_mode_log_dirty(d) )
-        __mark_dirty(d, __gpfn_to_mfn(d, gpfn));
-
-    if ( !(res = __shadow_status(d, gpfn, stype)) )
-        shadow_unlock(d);
-
-    return res;
-}
-
-
-static inline void put_shadow_status(struct domain *d)
-{
-    shadow_unlock(d);
-}
-
-
 static inline void delete_shadow_status(
     struct domain *d, unsigned long gpfn, unsigned long gmfn, unsigned int 
stype)
 {
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h        Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/vmx_platform.h        Fri Dec  2 18:52:25 2005
@@ -22,10 +22,10 @@
 
 #include <public/xen.h>
 #include <asm/e820.h>
-#include <asm/vmx_virpit.h>
+#include <asm/vmx_vpit.h>
 #include <asm/vmx_intercept.h>
 #include <asm/vmx_vioapic.h>
-#include <public/io/vmx_vpic.h>
+#include <asm/vmx_vpic.h>
 
 #define MAX_OPERAND_NUM 2
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/x86_32/page-2level.h
--- a/xen/include/asm-x86/x86_32/page-2level.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/x86_32/page-2level.h  Fri Dec  2 18:52:25 2005
@@ -1,5 +1,5 @@
-#ifndef __X86_32_PAGE_2L_H__
-#define __X86_32_PAGE_2L_H__
+#ifndef __X86_32_PAGE_2LEVEL_H__
+#define __X86_32_PAGE_2LEVEL_H__
 
 #define L1_PAGETABLE_SHIFT      12
 #define L2_PAGETABLE_SHIFT      22
@@ -52,7 +52,7 @@
 #define get_pte_flags(x) ((int)(x) & 0xFFF)
 #define put_pte_flags(x) ((intpte_t)((x) & 0xFFF))
 
-#define L1_DISALLOW_MASK (0xFFFFF180U) /* PAT/GLOBAL */
-#define L2_DISALLOW_MASK (0xFFFFF180U) /* PSE/GLOBAL */
+#define L1_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L2_DISALLOW_MASK BASE_DISALLOW_MASK
 
-#endif /* __X86_32_PAGE_2L_H__ */
+#endif /* __X86_32_PAGE_2LEVEL_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/x86_32/page-3level.h
--- a/xen/include/asm-x86/x86_32/page-3level.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/x86_32/page-3level.h  Fri Dec  2 18:52:25 2005
@@ -1,5 +1,5 @@
-#ifndef __X86_32_PAGE_3L_H__
-#define __X86_32_PAGE_3L_H__
+#ifndef __X86_32_PAGE_3LEVEL_H__
+#define __X86_32_PAGE_3LEVEL_H__
 
 #define L1_PAGETABLE_SHIFT      12
 #define L2_PAGETABLE_SHIFT      21
@@ -65,8 +65,8 @@
 #define get_pte_flags(x) (((int)((x) >> 32) & ~0xFFF) | ((int)(x) & 0xFFF))
 #define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 32) | ((x) & 0xFFF))
 
-#define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
-#define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */
-#define L3_DISALLOW_MASK (0xFFFFF1E6U)             /* must-be-zero */
+#define L1_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L2_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */
 
-#endif /* __X86_32_PAGE_3L_H__ */
+#endif /* __X86_32_PAGE_3LEVEL_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/x86_32/page.h
--- a/xen/include/asm-x86/x86_32/page.h Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/x86_32/page.h Fri Dec  2 18:52:25 2005
@@ -23,6 +23,9 @@
 extern unsigned int PAGE_HYPERVISOR_NOCACHE;
 #endif
 
+#define GRANT_PTE_FLAGS \
+    (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_GNTTAB)
+
 #endif /* __X86_32_PAGE_H__ */
 
 /*
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/x86_64/page.h
--- a/xen/include/asm-x86/x86_64/page.h Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/x86_64/page.h Fri Dec  2 18:52:25 2005
@@ -72,13 +72,16 @@
 /* Bit 23 of a 24-bit flag mask. This corresponds to bit 63 of a pte.*/
 #define _PAGE_NX (cpu_has_nx ? (1U<<23) : 0U)
 
-#define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
-#define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */
-#define L3_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* must-be-zero */
-#define L4_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* must-be-zero */
+#define L1_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L2_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)
+#define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)
 
 #define PAGE_HYPERVISOR         (__PAGE_HYPERVISOR         | _PAGE_GLOBAL)
 #define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL)
+
+#define GRANT_PTE_FLAGS \
+    (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_GNTTAB|_PAGE_USER)
 
 #endif /* __X86_64_PAGE_H__ */
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/acm.h
--- a/xen/include/public/acm.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/acm.h  Fri Dec  2 18:52:25 2005
@@ -60,6 +60,7 @@
 #define ACM_NULL_POLICY 0
 #define ACM_CHINESE_WALL_POLICY 1
 #define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2
+#define ACM_POLICY_UNDEFINED 15
 
 /* combinations have secondary policy component in higher 4bit */
 #define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY \
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/acm_ops.h
--- a/xen/include/public/acm_ops.h      Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/acm_ops.h      Fri Dec  2 18:52:25 2005
@@ -63,7 +63,7 @@
         ssidref_t    ssidref;
     } id;
     void *ssidbuf;
-    uint16_t ssidbuf_size;
+    uint32_t ssidbuf_size;
 };
 
 #define ACM_GETDECISION        8
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/arch-x86_32.h  Fri Dec  2 18:52:25 2005
@@ -134,7 +134,7 @@
 
 typedef struct {
     unsigned long cr2;
-    unsigned long pad; /* sizeof(vcpu_info_t) == 16 */
+    unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */
 } arch_vcpu_info_t;
 
 #endif
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/arch-x86_64.h  Fri Dec  2 18:52:25 2005
@@ -203,7 +203,7 @@
 
 typedef struct {
     unsigned long cr2;
-    unsigned long pad; /* sizeof(vcpu_info_t) == 32 */
+    unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
 } arch_vcpu_info_t;
 
 #endif /* !__ASSEMBLY__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/dom0_ops.h     Fri Dec  2 18:52:25 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   0xAAAA1012
+#define DOM0_INTERFACE_VERSION   0xAAAA1014
 
 /************************************************************************/
 
@@ -98,7 +98,7 @@
 typedef struct {
     /* IN variables. */
     domid_t               domain;
-    uint16_t              vcpu;
+    uint32_t              vcpu;
     /* IN/OUT parameters */
     vcpu_guest_context_t *ctxt;
 } dom0_setdomaininfo_t;
@@ -107,7 +107,7 @@
 typedef struct {
     /* IN variables. */
     uint32_t write;
-    uint32_t cpu_mask;
+    cpumap_t cpu_mask;
     uint32_t msr;
     uint32_t in1;
     uint32_t in2;
@@ -115,21 +115,6 @@
     uint32_t out1;
     uint32_t out2;
 } dom0_msr_t;
-
-#define DOM0_DEBUG            16
-typedef struct {
-    /* IN variables. */
-    domid_t  domain;
-    uint8_t  opcode;
-    uint32_t in1;
-    uint32_t in2;
-    uint32_t in3;
-    uint32_t in4;
-    /* OUT variables. */
-    uint32_t status;
-    uint32_t out1;
-    uint32_t out2;
-} dom0_debug_t;
 
 /*
  * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
@@ -182,8 +167,8 @@
 typedef struct {
     /* IN variables. */
     domid_t   domain;
-    uint16_t  vcpu;
-    cpumap_t cpumap;
+    uint32_t  vcpu;
+    cpumap_t  cpumap;
 } dom0_pincpudomain_t;
 
 /* Get trace buffers machine base address */
@@ -196,9 +181,9 @@
 #define DOM0_TBUF_SET_SIZE     3
 #define DOM0_TBUF_ENABLE       4
 #define DOM0_TBUF_DISABLE      5
-    uint8_t op;
+    uint32_t      op;
     /* IN/OUT variables */
-    unsigned long cpu_mask;
+    cpumap_t      cpu_mask;
     uint32_t      evt_mask;
     /* OUT variables */
     unsigned long buffer_mfn;
@@ -327,7 +312,7 @@
 #define DOM0_PERFCCONTROL_OP_RESET 1   /* Reset all counters to zero. */
 #define DOM0_PERFCCONTROL_OP_QUERY 2   /* Get perfctr information. */
 typedef struct {
-    uint8_t      name[80];             /*  name of perf counter */
+    uint8_t      name[80];             /* name of perf counter */
     uint32_t     nr_vals;              /* number of values for this counter */
     uint32_t     vals[64];             /* array of values */
 } dom0_perfc_desc_t;
@@ -349,16 +334,16 @@
 #define DOM0_IOPORT_PERMISSION   36
 typedef struct {
     domid_t  domain;                  /* domain to be affected */
-    uint16_t first_port;              /* first port int range */
-    uint16_t nr_ports;                /* size of port range */
-    uint16_t allow_access;            /* allow or deny access to range? */
+    uint32_t first_port;              /* first port int range */
+    uint32_t nr_ports;                /* size of port range */
+    uint8_t  allow_access;            /* allow or deny access to range? */
 } dom0_ioport_permission_t;
 
 #define DOM0_GETVCPUCONTEXT      37
 typedef struct {
     /* IN variables. */
     domid_t  domain;                  /* domain to be affected */
-    uint16_t vcpu;                    /* vcpu # */
+    uint32_t vcpu;                    /* vcpu # */
     /* OUT variables. */
     vcpu_guest_context_t *ctxt;
 } dom0_getvcpucontext_t;
@@ -367,7 +352,7 @@
 typedef struct {
     /* IN variables. */
     domid_t  domain;                  /* domain to be affected */
-    uint16_t vcpu;                    /* vcpu # */
+    uint32_t vcpu;                    /* vcpu # */
     /* OUT variables. */
     uint8_t  online;                  /* currently online (not hotplugged)? */
     uint8_t  blocked;                 /* blocked waiting for an event? */
@@ -381,35 +366,36 @@
 typedef struct {
     /* IN variables. */
     domid_t               first_domain;
-    unsigned int          max_domains;
+    uint32_t              max_domains;
     dom0_getdomaininfo_t *buffer;
     /* OUT variables. */
-    unsigned int          num_domains;
+    uint32_t              num_domains;
 } dom0_getdomaininfolist_t;
 
 #define DOM0_PLATFORM_QUIRK      39  
 #define QUIRK_NOIRQBALANCING  1
 typedef struct {
     /* IN variables. */
-    int quirk_id;
+    uint32_t quirk_id;
 } dom0_platform_quirk_t;
 
 #define DOM0_PHYSICAL_MEMORY_MAP 40
 typedef struct {
     /* IN variables. */
-    int max_map_entries;
-    /* OUT variables. */
-    int nr_map_entries;
+    uint32_t max_map_entries;
+    /* OUT variables. */
+    uint32_t nr_map_entries;
     struct dom0_memory_map_entry {
         uint64_t start, end;
-        int is_ram;
+        uint32_t flags; /* reserved */
+        uint8_t  is_ram;
     } *memory_map;
 } dom0_physical_memory_map_t;
 
 #define DOM0_MAX_VCPUS 41
 typedef struct {
-    domid_t domain;             /* domain to be affected */
-    unsigned int max;           /* maximum number of vcpus */
+    domid_t  domain;        /* domain to be affected */
+    uint32_t max;           /* maximum number of vcpus */
 } dom0_max_vcpus_t;
 
 #define DOM0_SETDOMAINHANDLE 44
@@ -433,7 +419,6 @@
         dom0_getdomaininfo_t     getdomaininfo;
         dom0_getpageframeinfo_t  getpageframeinfo;
         dom0_msr_t               msr;
-        dom0_debug_t             debug;
         dom0_settime_t           settime;
         dom0_readconsole_t       readconsole;
         dom0_pincpudomain_t      pincpudomain;
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/event_channel.h        Fri Dec  2 18:52:25 2005
@@ -8,6 +8,8 @@
 
 #ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
 #define __XEN_PUBLIC_EVENT_CHANNEL_H__
+
+typedef uint32_t evtchn_port_t;
 
 /*
  * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
@@ -20,9 +22,9 @@
 #define EVTCHNOP_alloc_unbound    6
 typedef struct evtchn_alloc_unbound {
     /* IN parameters */
-    domid_t  dom, remote_dom;
+    domid_t dom, remote_dom;
     /* OUT parameters */
-    uint32_t port;
+    evtchn_port_t port;
 } evtchn_alloc_unbound_t;
 
 /*
@@ -37,10 +39,10 @@
 #define EVTCHNOP_bind_interdomain 0
 typedef struct evtchn_bind_interdomain {
     /* IN parameters. */
-    domid_t  remote_dom;
-    uint32_t remote_port;
+    domid_t remote_dom;
+    evtchn_port_t remote_port;
     /* OUT parameters. */
-    uint32_t local_port;
+    evtchn_port_t local_port;
 } evtchn_bind_interdomain_t;
 
 /*
@@ -57,7 +59,7 @@
     uint32_t virq;
     uint32_t vcpu;
     /* OUT parameters. */
-    uint32_t port;
+    evtchn_port_t port;
 } evtchn_bind_virq_t;
 
 /*
@@ -73,7 +75,7 @@
 #define BIND_PIRQ__WILL_SHARE 1
     uint32_t flags; /* BIND_PIRQ__* */
     /* OUT parameters. */
-    uint32_t port;
+    evtchn_port_t port;
 } evtchn_bind_pirq_t;
 
 /*
@@ -86,7 +88,7 @@
 typedef struct evtchn_bind_ipi {
     uint32_t vcpu;
     /* OUT parameters. */
-    uint32_t port;
+    evtchn_port_t port;
 } evtchn_bind_ipi_t;
 
 /*
@@ -97,7 +99,7 @@
 #define EVTCHNOP_close            3
 typedef struct evtchn_close {
     /* IN parameters. */
-    uint32_t port;
+    evtchn_port_t port;
 } evtchn_close_t;
 
 /*
@@ -107,7 +109,7 @@
 #define EVTCHNOP_send             4
 typedef struct evtchn_send {
     /* IN parameters. */
-    uint32_t port;
+    evtchn_port_t port;
 } evtchn_send_t;
 
 /*
@@ -122,7 +124,7 @@
 typedef struct evtchn_status {
     /* IN parameters */
     domid_t  dom;
-    uint32_t port;
+    evtchn_port_t port;
     /* OUT parameters */
 #define EVTCHNSTAT_closed       0  /* Channel is not in use.                 */
 #define EVTCHNSTAT_unbound      1  /* Channel is waiting interdom connection.*/
@@ -134,11 +136,11 @@
     uint32_t vcpu;                 /* VCPU to which this channel is bound.   */
     union {
         struct {
-            domid_t  dom;
+            domid_t dom;
         } unbound; /* EVTCHNSTAT_unbound */
         struct {
-            domid_t  dom;
-            uint32_t port;
+            domid_t dom;
+            evtchn_port_t port;
         } interdomain; /* EVTCHNSTAT_interdomain */
         uint32_t pirq;      /* EVTCHNSTAT_pirq        */
         uint32_t virq;      /* EVTCHNSTAT_virq        */
@@ -158,7 +160,7 @@
 #define EVTCHNOP_bind_vcpu        8
 typedef struct evtchn_bind_vcpu {
     /* IN parameters. */
-    uint32_t port;
+    evtchn_port_t port;
     uint32_t vcpu;
 } evtchn_bind_vcpu_t;
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/grant_table.h  Fri Dec  2 18:52:25 2005
@@ -73,14 +73,14 @@
  */
 typedef struct grant_entry {
     /* GTF_xxx: various type and flag information.  [XEN,GST] */
-    uint16_t     flags;
+    uint16_t flags;
     /* The domain being granted foreign privileges. [GST] */
-    domid_t domid;
+    domid_t  domid;
     /*
      * GTF_permit_access: Frame that @domid is allowed to map and access. [GST]
      * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN]
      */
-    uint32_t     frame;
+    uint32_t frame;
 } grant_entry_t;
 
 /*
@@ -131,7 +131,12 @@
 /*
  * Reference to a grant entry in a specified domain's grant table.
  */
-typedef uint16_t grant_ref_t;
+typedef uint32_t grant_ref_t;
+
+/*
+ * Handle to track a mapping created via a grant reference.
+ */
+typedef uint32_t grant_handle_t;
 
 /*
  * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access
@@ -154,11 +159,12 @@
 typedef struct gnttab_map_grant_ref {
     /* IN parameters. */
     uint64_t host_addr;
+    uint32_t flags;               /* GNTMAP_* */
+    grant_ref_t ref;
     domid_t  dom;
-    grant_ref_t ref;
-    uint16_t flags;               /* GNTMAP_* */
-    /* OUT parameters. */
-    int16_t  handle;              /* +ve: handle; -ve: GNTST_* */
+    /* OUT parameters. */
+    int16_t  status;              /* GNTST_* */
+    grant_handle_t handle;
     uint64_t dev_bus_addr;
 } gnttab_map_grant_ref_t;
 
@@ -178,7 +184,7 @@
     /* IN parameters. */
     uint64_t host_addr;
     uint64_t dev_bus_addr;
-    uint16_t handle;
+    grant_handle_t handle;
     /* OUT parameters. */
     int16_t  status;              /* GNTST_* */
 } gnttab_unmap_grant_ref_t;
@@ -196,7 +202,7 @@
 typedef struct gnttab_setup_table {
     /* IN parameters. */
     domid_t  dom;
-    uint16_t nr_frames;
+    uint32_t nr_frames;
     /* OUT parameters. */
     int16_t  status;              /* GNTST_* */
     unsigned long *frame_list;
@@ -215,9 +221,12 @@
 } gnttab_dump_table_t;
 
 /*
- * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain.  The
- * foreign domain has previously registered the details of the transfer.
- * These can be identified from <handle>, a grant reference.
+ * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
+ * foreign domain has previously registered its interest in the transfer via
+ * <domid, ref>.
+ * 
+ * Note that, even if the transfer fails, the specified page no longer belongs
+ * to the calling domain *unless* the error is GNTST_bad_page.
  */
 #define GNTTABOP_transfer                4
 typedef struct {
@@ -269,6 +278,7 @@
 #define GNTST_bad_dev_addr     (-6) /* Inappropriate device address to unmap.*/
 #define GNTST_no_device_space  (-7) /* Out of space in I/O MMU.              */
 #define GNTST_permission_denied (-8) /* Not enough privilege for operation.  */
+#define GNTST_bad_page         (-9) /* Specified page was invalid for op.    */
 
 #define GNTTABOP_error_msgs {                   \
     "okay",                                     \
@@ -279,7 +289,8 @@
     "invalid virtual address",                  \
     "invalid device address",                   \
     "no spare translation slot in the I/O MMU", \
-    "permission denied"                         \
+    "permission denied",                        \
+    "bad page"                                  \
 }
 
 #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/io/blkif.h
--- a/xen/include/public/io/blkif.h     Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/io/blkif.h     Fri Dec  2 18:52:25 2005
@@ -11,6 +11,18 @@
 
 #include "ring.h"
 
+/*
+ * Front->back notifications: When enqueuing a new request, sending a
+ * notification can be made conditional on req_event (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Backends must set
+ * req_event appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
+ * 
+ * Back->front notifications: When enqueuing a new response, sending a
+ * notification can be made conditional on rsp_event (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Frontends must set
+ * rsp_event appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
+ */
+
 #ifndef blkif_vdev_t
 #define blkif_vdev_t   uint16_t
 #endif
@@ -18,9 +30,6 @@
 
 #define BLKIF_OP_READ      0
 #define BLKIF_OP_WRITE     1
-
-/* NB. Ring size must be small enough for sizeof(blkif_ring_t) <= PAGE_SIZE. */
-#define BLKIF_RING_SIZE        64
 
 /*
  * Maximum scatter/gather segments per request.
@@ -33,33 +42,24 @@
     uint8_t        operation;    /* BLKIF_OP_???                         */
     uint8_t        nr_segments;  /* number of segments                   */
     blkif_vdev_t   handle;       /* only for read/write requests         */
-    unsigned long  id;           /* private guest value, echoed in resp  */
+    uint64_t       id;           /* private guest value, echoed in resp  */
     blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
-    /* @f_a_s[4:0]=last_sect ; @f_a_s[9:5]=first_sect                        */
-    /* @f_a_s[:16]= grant reference (16 bits)                                */
-    /* @first_sect: first sector in frame to transfer (inclusive).           */
-    /* @last_sect: last sector in frame to transfer (inclusive).             */
-    unsigned long  frame_and_sects[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    struct blkif_request_segment {
+        grant_ref_t gref;        /* reference to I/O buffer frame        */
+        /* @first_sect: first sector in frame to transfer (inclusive).   */
+        /* @last_sect: last sector in frame to transfer (inclusive).     */
+        uint8_t     first_sect, last_sect;
+    } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 } blkif_request_t;
 
-#define blkif_fas(_addr, _fs, _ls) ((_addr)|((_fs)<<5)|(_ls))
-#define blkif_first_sect(_fas) (((_fas)>>5)&31)
-#define blkif_last_sect(_fas)  ((_fas)&31)
-
-#define blkif_fas_from_gref(_gref, _fs, _ls) (((_gref)<<16)|((_fs)<<5)|(_ls))
-#define blkif_gref_from_fas(_fas) ((_fas)>>16)
-
 typedef struct blkif_response {
-    unsigned long   id;              /* copied from request */
+    uint64_t        id;              /* copied from request */
     uint8_t         operation;       /* copied from request */
     int16_t         status;          /* BLKIF_RSP_???       */
 } blkif_response_t;
 
 #define BLKIF_RSP_ERROR  -1 /* non-specific 'error' */
 #define BLKIF_RSP_OKAY    0 /* non-specific 'okay'  */
-
-#define BLKIF_MAJOR(dev) ((dev)>>8)
-#define BLKIF_MINOR(dev) ((dev) & 0xff)
 
 /*
  * Generate blkif ring structures and types.
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/io/netif.h     Fri Dec  2 18:52:25 2005
@@ -9,17 +9,30 @@
 #ifndef __XEN_PUBLIC_IO_NETIF_H__
 #define __XEN_PUBLIC_IO_NETIF_H__
 
+#include "ring.h"
+
+/*
+ * Note that there is *never* any need to notify the backend when enqueuing
+ * receive requests (netif_rx_request_t). Notifications after enqueuing any
+ * other type of message should be conditional on the appropriate req_event
+ * or rsp_event field in the shared ring.
+ */
+
+/* Protocol checksum field is blank in the packet (hardware offload)? */
+#define _NETTXF_csum_blank (0)
+#define  NETTXF_csum_blank (1U<<_NETTXF_csum_blank)
+
 typedef struct netif_tx_request {
     grant_ref_t gref;      /* Reference to buffer page */
-    uint16_t offset:15;    /* Offset within buffer page */
-    uint16_t csum_blank:1; /* Proto csum field blank?   */
+    uint16_t offset;       /* Offset within buffer page */
+    uint16_t flags;        /* NETTXF_* */
     uint16_t id;           /* Echoed in response message. */
     uint16_t size;         /* Packet size in bytes.       */
 } netif_tx_request_t;
 
 typedef struct netif_tx_response {
     uint16_t id;
-    int8_t   status;
+    int16_t  status;       /* NETIF_RSP_* */
 } netif_tx_response_t;
 
 typedef struct {
@@ -27,65 +40,24 @@
     grant_ref_t gref;      /* Reference to incoming granted frame */
 } netif_rx_request_t;
 
+/* Protocol checksum already validated (e.g., performed by hardware)? */
+#define _NETRXF_csum_valid (0)
+#define  NETRXF_csum_valid (1U<<_NETRXF_csum_valid)
+
 typedef struct {
-    uint16_t offset;     /* Offset in page of start of received packet  */
-    uint16_t csum_valid; /* Protocol checksum is validated?       */
     uint16_t id;
-    int16_t  status;     /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */
+    uint16_t offset;       /* Offset in page of start of received packet  */
+    uint16_t flags;        /* NETRXF_* */
+    int16_t  status;       /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */
 } netif_rx_response_t;
 
 /*
- * We use a special capitalised type name because it is _essential_ that all 
- * arithmetic on indexes is done on an integer type of the correct size.
+ * Generate netif ring structures and types.
  */
-typedef uint32_t NETIF_RING_IDX;
 
-/*
- * Ring indexes are 'free running'. That is, they are not stored modulo the
- * size of the ring buffer. The following macros convert a free-running counter
- * into a value that can directly index a ring-buffer array.
- */
-#define MASK_NETIF_RX_IDX(_i) ((_i)&(NETIF_RX_RING_SIZE-1))
-#define MASK_NETIF_TX_IDX(_i) ((_i)&(NETIF_TX_RING_SIZE-1))
+DEFINE_RING_TYPES(netif_tx, netif_tx_request_t, netif_tx_response_t);
+DEFINE_RING_TYPES(netif_rx, netif_rx_request_t, netif_rx_response_t);
 
-#define NETIF_TX_RING_SIZE 256
-#define NETIF_RX_RING_SIZE 256
-
-/* This structure must fit in a memory page. */
-typedef struct netif_tx_interface {
-    /*
-     * Frontend places packets into ring at tx_req_prod.
-     * Frontend receives event when tx_resp_prod passes tx_event.
-     * 'req_cons' is a shadow of the backend's request consumer -- the frontend
-     * may use it to determine if all queued packets have been seen by the
-     * backend.
-     */
-    NETIF_RING_IDX req_prod;
-    NETIF_RING_IDX req_cons;
-    NETIF_RING_IDX resp_prod;
-    NETIF_RING_IDX event;
-    union {
-        netif_tx_request_t  req;
-        netif_tx_response_t resp;
-    } ring[NETIF_TX_RING_SIZE];
-} netif_tx_interface_t;
-
-/* This structure must fit in a memory page. */
-typedef struct netif_rx_interface {
-    /*
-     * Frontend places empty buffers into ring at rx_req_prod.
-     * Frontend receives event when rx_resp_prod passes rx_event.
-     */
-    NETIF_RING_IDX req_prod;
-    NETIF_RING_IDX resp_prod;
-    NETIF_RING_IDX event;
-    union {
-        netif_rx_request_t  req;
-        netif_rx_response_t resp;
-    } ring[NETIF_RX_RING_SIZE];
-} netif_rx_interface_t;
-
-/* Descriptor status values */
 #define NETIF_RSP_DROPPED         -2
 #define NETIF_RSP_ERROR           -1
 #define NETIF_RSP_OKAY             0
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/io/ring.h
--- a/xen/include/public/io/ring.h      Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/io/ring.h      Fri Dec  2 18:52:25 2005
@@ -1,7 +1,10 @@
-/*
+/******************************************************************************
+ * ring.h
+ * 
  * Shared producer-consumer ring macros.
+ *
  * Tim Deegan and Andrew Warfield November 2004.
- */ 
+ */
 
 #ifndef __XEN_PUBLIC_IO_RING_H__
 #define __XEN_PUBLIC_IO_RING_H__
@@ -22,35 +25,38 @@
  * power of two (so we can mask with (size-1) to loop around).
  */
 #define __RING_SIZE(_s, _sz) \
-    (__RD32(((_sz) - 2*sizeof(RING_IDX)) / sizeof((_s)->ring[0])))
-
-/*
- *  Macros to make the correct C datatypes for a new kind of ring.
- * 
- *  To make a new ring datatype, you need to have two message structures,
- *  let's say request_t, and response_t already defined.
- *
- *  In a header where you want the ring datatype declared, you then do:
+    (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+
+/*
+ * Macros to make the correct C datatypes for a new kind of ring.
+ * 
+ * To make a new ring datatype, you need to have two message structures,
+ * let's say request_t, and response_t already defined.
+ *
+ * In a header where you want the ring datatype declared, you then do:
  *
  *     DEFINE_RING_TYPES(mytag, request_t, response_t);
  *
- *  These expand out to give you a set of types, as you can see below.
- *  The most important of these are:
+ * These expand out to give you a set of types, as you can see below.
+ * The most important of these are:
  *  
  *     mytag_sring_t      - The shared ring.
  *     mytag_front_ring_t - The 'front' half of the ring.
  *     mytag_back_ring_t  - The 'back' half of the ring.
  *
- *  To initialize a ring in your code you need to know the location and size
- *  of the shared memory area (PAGE_SIZE, for instance). To initialise
- *  the front half:
- *
- *      mytag_front_ring_t front_ring;
- *
- *      SHARED_RING_INIT((mytag_sring_t *)shared_page);
- *      FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
- *
- *  Initializing the back follows similarly...
+ * To initialize a ring in your code you need to know the location and size
+ * of the shared memory area (PAGE_SIZE, for instance). To initialise
+ * the front half:
+ *
+ *     mytag_front_ring_t front_ring;
+ *     SHARED_RING_INIT((mytag_sring_t *)shared_page);
+ *     FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
+ *
+ * Initializing the back follows similarly (note that only the front
+ * initializes the shared ring):
+ *
+ *     mytag_back_ring_t back_ring;
+ *     BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
  */
          
 #define DEFINE_RING_TYPES(__name, __req_t, __rsp_t)                     \
@@ -63,8 +69,9 @@
                                                                         \
 /* Shared ring page */                                                  \
 struct __name##_sring {                                                 \
-    RING_IDX req_prod;                                                  \
-    RING_IDX rsp_prod;                                                  \
+    RING_IDX req_prod, req_event;                                       \
+    RING_IDX rsp_prod, rsp_event;                                       \
+    uint8_t  pad[48];                                                   \
     union __name##_sring_entry ring[1]; /* variable-length */           \
 };                                                                      \
                                                                         \
@@ -90,24 +97,25 @@
 typedef struct __name##_back_ring __name##_back_ring_t
 
 /*
- *   Macros for manipulating rings.  
- * 
- *   FRONT_RING_whatever works on the "front end" of a ring: here 
- *   requests are pushed on to the ring and responses taken off it.
- * 
- *   BACK_RING_whatever works on the "back end" of a ring: here 
- *   requests are taken off the ring and responses put on.
- * 
- *   N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.  
- *   This is OK in 1-for-1 request-response situations where the 
- *   requestor (front end) never has more than RING_SIZE()-1
- *   outstanding requests.
+ * Macros for manipulating rings.  
+ * 
+ * FRONT_RING_whatever works on the "front end" of a ring: here 
+ * requests are pushed on to the ring and responses taken off it.
+ * 
+ * BACK_RING_whatever works on the "back end" of a ring: here 
+ * requests are taken off the ring and responses put on.
+ * 
+ * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.  
+ * This is OK in 1-for-1 request-response situations where the 
+ * requestor (front end) never has more than RING_SIZE()-1
+ * outstanding requests.
  */
 
 /* Initialising empty rings */
 #define SHARED_RING_INIT(_s) do {                                       \
-    (_s)->req_prod = 0;                                                 \
-    (_s)->rsp_prod = 0;                                                 \
+    (_s)->req_prod  = (_s)->rsp_prod  = 0;                              \
+    (_s)->req_event = (_s)->rsp_event = 1;                              \
+    memset((_s)->pad, 0, sizeof((_s)->pad));                            \
 } while(0)
 
 #define FRONT_RING_INIT(_r, _s, __size) do {                            \
@@ -143,10 +151,6 @@
 #define RING_SIZE(_r)                                                   \
     ((_r)->nr_ents)
 
-/* How many empty slots are on a ring? */
-#define RING_PENDING_REQUESTS(_r)                                       \
-   ( ((_r)->req_prod_pvt - (_r)->rsp_cons) )
-   
 /* Test if there is an empty slot available on the front ring. 
  * (This is only meaningful from the front. )
  */
@@ -162,25 +166,6 @@
      (((_r)->req_cons - (_r)->rsp_prod_pvt) !=                          \
       RING_SIZE(_r)) )
       
-/* Test if there are messages waiting to be pushed. */
-#define RING_HAS_UNPUSHED_REQUESTS(_r)                                  \
-   ( (_r)->req_prod_pvt != (_r)->sring->req_prod )
-   
-#define RING_HAS_UNPUSHED_RESPONSES(_r)                                 \
-   ( (_r)->rsp_prod_pvt != (_r)->sring->rsp_prod )
-
-/* Copy the private producer pointer into the shared ring so the other end 
- * can see the updates we've made. */
-#define RING_PUSH_REQUESTS(_r) do {                                     \
-    wmb();                                                              \
-    (_r)->sring->req_prod = (_r)->req_prod_pvt;                         \
-} while (0)
-
-#define RING_PUSH_RESPONSES(_r) do {                                    \
-    wmb();                                                              \
-    (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt;                         \
-} while (0)
-
 /* Direct access to individual ring elements, by index. */
 #define RING_GET_REQUEST(_r, _idx)                                      \
  (&((_r)->sring->ring[                                                  \
@@ -196,6 +181,82 @@
 #define RING_REQUEST_CONS_OVERFLOW(_r, _cons)                           \
     (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
 
+#define RING_PUSH_REQUESTS(_r) do {                                     \
+    wmb(); /* back sees requests /before/ updated producer index */     \
+    (_r)->sring->req_prod = (_r)->req_prod_pvt;                         \
+} while (0)
+
+#define RING_PUSH_RESPONSES(_r) do {                                    \
+    wmb(); /* front sees responses /before/ updated producer index */   \
+    (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt;                         \
+} while (0)
+
+/*
+ * Notification hold-off (req_event and rsp_event):
+ * 
+ * When queueing requests or responses on a shared ring, it may not always be
+ * necessary to notify the remote end. For example, if requests are in flight
+ * in a backend, the front may be able to queue further requests without
+ * notifying the back (if the back checks for new requests when it queues
+ * responses).
+ * 
+ * When enqueuing requests or responses:
+ * 
+ *  Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument
+ *  is a boolean return value. True indicates that the receiver requires an
+ *  asynchronous notification.
+ * 
+ * After dequeuing requests or responses (before sleeping the connection):
+ * 
+ *  Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES().
+ *  The second argument is a boolean return value. True indicates that there
+ *  are pending messages on the ring (i.e., the connection should not be put
+ *  to sleep).
+ *  
+ *  These macros will set the req_event/rsp_event field to trigger a
+ *  notification on the very next message that is enqueued. If you want to
+ *  create batches of work (i.e., only receive a notification after several
+ *  messages have been enqueued) then you will need to create a customised
+ *  version of the FINAL_CHECK macro in your own code, which sets the event
+ *  field appropriately.
+ */
+
+#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do {           \
+    RING_IDX __old = (_r)->sring->req_prod;                             \
+    RING_IDX __new = (_r)->req_prod_pvt;                                \
+    wmb(); /* back sees requests /before/ updated producer index */     \
+    (_r)->sring->req_prod = __new;                                      \
+    mb(); /* back sees new requests /before/ we check req_event */      \
+    (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) <           \
+                 (RING_IDX)(__new - __old));                            \
+} while (0)
+
+#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do {          \
+    RING_IDX __old = (_r)->sring->rsp_prod;                             \
+    RING_IDX __new = (_r)->rsp_prod_pvt;                                \
+    wmb(); /* front sees responses /before/ updated producer index */   \
+    (_r)->sring->rsp_prod = __new;                                      \
+    mb(); /* front sees new responses /before/ we check rsp_event */    \
+    (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) <           \
+                 (RING_IDX)(__new - __old));                            \
+} while (0)
+
+#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do {             \
+    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
+    if (_work_to_do) break;                                             \
+    (_r)->sring->req_event = (_r)->req_cons + 1;                        \
+    mb();                                                               \
+    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
+} while (0)
+
+#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do {            \
+    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
+    if (_work_to_do) break;                                             \
+    (_r)->sring->rsp_event = (_r)->rsp_cons + 1;                        \
+    mb();                                                               \
+    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
+} while (0)
+
 #endif /* __XEN_PUBLIC_IO_RING_H__ */
 
 /*
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/io/tpmif.h
--- a/xen/include/public/io/tpmif.h     Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/io/tpmif.h     Fri Dec  2 18:52:25 2005
@@ -18,7 +18,7 @@
 
 typedef struct {
     unsigned long addr;   /* Machine address of packet.   */
-    int      ref;         /* grant table access reference */
+    grant_ref_t ref;      /* grant table access reference */
     uint16_t id;          /* Echoed in response message.  */
     uint16_t size;        /* Packet size in bytes.        */
 } tpmif_tx_request_t;
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/memory.h
--- a/xen/include/public/memory.h       Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/memory.h       Fri Dec  2 18:52:25 2005
@@ -9,15 +9,13 @@
 #ifndef __XEN_PUBLIC_MEMORY_H__
 #define __XEN_PUBLIC_MEMORY_H__
 
-/* arg == addr of struct xen_memory_reservation. */
+/*
+ * Increase or decrease the specified domain's memory reservation. Returns a
+ * -ve errcode on failure, or the # extents successfully allocated or freed.
+ * arg == addr of struct xen_memory_reservation.
+ */
 #define XENMEM_increase_reservation 0
-
-/* arg == addr of struct xen_memory_reservation. */
 #define XENMEM_decrease_reservation 1
-
-/* arg == addr of unsigned long. */
-#define XENMEM_maximum_ram_page     2
-
 typedef struct xen_memory_reservation {
 
     /*
@@ -47,6 +45,49 @@
 
 } xen_memory_reservation_t;
 
+/*
+ * Returns the maximum machine frame number of mapped RAM in this system.
+ * This command always succeeds (it never returns an error code).
+ * arg == NULL.
+ */
+#define XENMEM_maximum_ram_page     2
+
+/*
+ * Returns the current or maximum memory reservation, in pages, of the
+ * specified domain (may be DOMID_SELF). Returns -ve errcode on failure.
+ * arg == addr of domid_t.
+ */
+#define XENMEM_current_reservation  3
+#define XENMEM_maximum_reservation  4
+
+/*
+ * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
+ * mapping table. Architectures which do not have a m2p table do not implement
+ * this command.
+ * arg == addr of xen_machphys_mfn_list_t.
+ */
+#define XENMEM_machphys_mfn_list    5
+typedef struct xen_machphys_mfn_list {
+    /*
+     * Size of the 'extent_start' array. Fewer entries will be filled if the
+     * machphys table is smaller than max_extents * 2MB.
+     */
+    unsigned int max_extents;
+    
+    /*
+     * Pointer to buffer to fill with list of extent starts. If there are
+     * any large discontiguities in the machine address space, 2MB gaps in
+     * the machphys table will be represented by an MFN base of zero.
+     */
+    unsigned long *extent_start;
+
+    /*
+     * Number of extents written to the above array. This will be smaller
+     * than 'max_extents' if the machphys table is smaller than max_e * 2MB.
+     */
+    unsigned int nr_extents;
+} xen_machphys_mfn_list_t;
+
 #endif /* __XEN_PUBLIC_MEMORY_H__ */
 
 /*
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/sched_ctl.h
--- a/xen/include/public/sched_ctl.h    Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/sched_ctl.h    Fri Dec  2 18:52:25 2005
@@ -48,8 +48,8 @@
             uint64_t period;
             uint64_t slice;
             uint64_t latency;
-            uint16_t extratime;
-            uint16_t weight;
+            uint32_t extratime;
+            uint32_t weight;
         } sedf;
 
     } u;
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/trace.h
--- a/xen/include/public/trace.h        Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/trace.h        Fri Dec  2 18:52:25 2005
@@ -72,9 +72,8 @@
  * field, indexes into an array of struct t_rec's.
  */
 struct t_buf {
-    unsigned int  cons;      /* Next item to be consumed by control tools. */
-    unsigned int  prod;      /* Next item to be produced by Xen.           */
-    unsigned int  nr_recs;   /* Number of records in this trace buffer.    */
+    uint32_t cons;      /* Next item to be consumed by control tools. */
+    uint32_t prod;      /* Next item to be produced by Xen.           */
     /* 'nr_recs' records follow immediately after the meta-data header.    */
 };
 
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/xen.h  Fri Dec  2 18:52:25 2005
@@ -266,10 +266,31 @@
  */
 #define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
 
-/*
- * Per-VCPU information goes here. This will be cleaned up more when Xen 
- * actually supports multi-VCPU guests.
- */
+typedef struct vcpu_time_info {
+    /*
+     * Updates to the following values are preceded and followed by an
+     * increment of 'version'. The guest can therefore detect updates by
+     * looking for changes to 'version'. If the least-significant bit of
+     * the version number is set then an update is in progress and the guest
+     * must wait to read a consistent set of values.
+     * The correct way to interact with the version number is similar to
+     * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
+     */
+    uint32_t version;
+    uint32_t pad0;
+    uint64_t tsc_timestamp;   /* TSC at last update of time vals.  */
+    uint64_t system_time;     /* Time, in nanosecs, since boot.    */
+    /*
+     * Current system time:
+     *   system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul
+     * CPU frequency (Hz):
+     *   ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
+     */
+    uint32_t tsc_to_system_mul;
+    int8_t   tsc_shift;
+    int8_t   pad1[3];
+} vcpu_time_info_t; /* 32 bytes */
+
 typedef struct vcpu_info {
     /*
      * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
@@ -300,39 +321,15 @@
     uint8_t evtchn_upcall_mask;
     unsigned long evtchn_pending_sel;
     arch_vcpu_info_t arch;
-} vcpu_info_t;
-
-typedef struct vcpu_time_info {
-    /*
-     * Updates to the following values are preceded and followed by an
-     * increment of 'version'. The guest can therefore detect updates by
-     * looking for changes to 'version'. If the least-significant bit of
-     * the version number is set then an update is in progress and the guest
-     * must wait to read a consistent set of values.
-     * The correct way to interact with the version number is similar to
-     * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
-     */
-    uint32_t version;
-    uint64_t tsc_timestamp;   /* TSC at last update of time vals.  */
-    uint64_t system_time;     /* Time, in nanosecs, since boot.    */
-    /*
-     * Current system time:
-     *   system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul
-     * CPU frequency (Hz):
-     *   ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
-     */
-    uint32_t tsc_to_system_mul;
-    int8_t  tsc_shift;
-} vcpu_time_info_t;
+    vcpu_time_info_t time;
+} vcpu_info_t; /* 64 bytes (x86) */
 
 /*
  * Xen/kernel shared data -- pointer provided in start_info.
  * NB. We expect that this struct is smaller than a page.
  */
 typedef struct shared_info {
-    vcpu_info_t vcpu_data[MAX_VIRT_CPUS];
-
-    vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS];
+    vcpu_info_t vcpu_info[MAX_VIRT_CPUS];
 
     /*
      * A domain can create "event channels" on which it can send and receive
@@ -413,9 +410,9 @@
     unsigned long shared_info;  /* MACHINE address of shared info struct. */
     uint32_t flags;             /* SIF_xxx flags.                         */
     unsigned long store_mfn;    /* MACHINE page number of shared page.    */
-    uint16_t store_evtchn;      /* Event channel for store communication. */
+    uint32_t store_evtchn;      /* Event channel for store communication. */
     unsigned long console_mfn;  /* MACHINE address of console page.       */
-    uint16_t console_evtchn;    /* Event channel for console messages.    */
+    uint32_t console_evtchn;    /* Event channel for console messages.    */
     /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME).     */
     unsigned long pt_base;      /* VIRTUAL address of page directory.     */
     unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames.       */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h     Fri Dec  2 18:12:11 2005
+++ b/xen/include/xen/grant_table.h     Fri Dec  2 18:52:25 2005
@@ -4,7 +4,7 @@
  * Mechanism for granting foreign access to page frames, and receiving
  * page-ownership transfers.
  * 
- * Copyright (c) 2004 K A Fraser
+ * Copyright (c) 2004-2005 K A Fraser
  * 
  * 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
@@ -21,11 +21,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef __XEN_GRANT_H__
-#define __XEN_GRANT_H__
+#ifndef __XEN_GRANT_TABLE_H__
+#define __XEN_GRANT_TABLE_H__
 
 #include <xen/config.h>
 #include <public/grant_table.h>
+#include <asm/grant_table.h>
 
 /* Active grant entry - used for shadowing GTF_permit_access grants. */
 typedef struct {
@@ -51,7 +52,6 @@
 #define GNTPIN_devr_inc      (1 << GNTPIN_devr_shift)
 #define GNTPIN_devr_mask     (0xFFU << GNTPIN_devr_shift)
 
-#define ORDER_GRANT_FRAMES   2
 #define NR_GRANT_FRAMES      (1U << ORDER_GRANT_FRAMES)
 #define NR_GRANT_ENTRIES     \
     ((NR_GRANT_FRAMES << PAGE_SHIFT) / sizeof(grant_entry_t))
@@ -94,10 +94,6 @@
 void grant_table_destroy(
     struct domain *d);
 
-/* Destroy host-CPU mappings via a grant-table entry. */
-int gnttab_check_unmap(
-    struct domain *rd, struct domain *ld, unsigned long frame, int readonly);
-
 /*
  * Check that the given grant reference (rd,ref) allows 'ld' to transfer
  * ownership of a page frame. If so, lock down the grant entry.
@@ -106,8 +102,9 @@
 gnttab_prepare_for_transfer(
     struct domain *rd, struct domain *ld, grant_ref_t ref);
 
-/* Domain death release of granted device mappings of other domains.*/
+/* Domain death release of granted mappings of other domains' memory. */
 void
-gnttab_release_dev_mappings(grant_table_t *gt);
+gnttab_release_mappings(
+    struct domain *d);
 
-#endif /* __XEN_GRANT_H__ */
+#endif /* __XEN_GRANT_TABLE_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/xen/perfc_defn.h
--- a/xen/include/xen/perfc_defn.h      Fri Dec  2 18:12:11 2005
+++ b/xen/include/xen/perfc_defn.h      Fri Dec  2 18:52:25 2005
@@ -114,7 +114,7 @@
 PERFCOUNTER_CPU(validate_hl2e_calls,    "calls to validate_hl2e_change")
 PERFCOUNTER_CPU(validate_hl2e_changes,  "validate_hl2e makes changes")
 PERFCOUNTER_CPU(exception_fixed,        "pre-exception fixed")
-PERFCOUNTER_CPU(gpfn_to_mfn_foreign,    "calls to gpfn_to_mfn_foreign")
+PERFCOUNTER_CPU(get_mfn_from_pfn_foreign, "calls to get_mfn_from_pfn_foreign")
 PERFCOUNTER_CPU(remove_all_access,      "calls to remove_all_access")
 PERFCOUNTER_CPU(remove_write_access,    "calls to remove_write_access")
 PERFCOUNTER_CPU(remove_write_access_easy, "easy outs of remove_write_access")
diff -r eae5812f33f1 -r 28bd01c9b596 docs/README.xen-bugtool
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/docs/README.xen-bugtool   Fri Dec  2 18:52:25 2005
@@ -0,0 +1,16 @@
+xen-bugtool
+===========
+
+The xen-bugtool command line application will collate the Xen dmesg output,
+details of the hardware configuration of your machine, information about the
+build of Xen that you are using, plus, if you allow it, various logs.
+
+The information collated can either be posted to a Xen Bugzilla bug (this bug
+must already exist in the system, and you must be a registered user there), or
+it can be saved as a .tar.bz2 for sending or archiving.
+
+The collated logs may contain private information, and if you are at all
+worried about that, you should not use this tool, or you should explicitly
+exclude those logs from the archive.
+
+xen-bugtool is wholly interactive, so simply run it, and answer the questions.
diff -r eae5812f33f1 -r 28bd01c9b596 docs/man/xend-config.sxp.pod.5
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/docs/man/xend-config.sxp.pod.5    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,142 @@
+=head1 NAME
+
+xend-config.sxp - Xen daemon configuration file
+
+=head1 SYNOPSIS
+
+/etc/xen/xend-config.sxp
+
+=head1 DESCRIPTION
+
+The xend(1) program requires xend-config.sxp to specify operating
+parameters which determine the behavior of the daemon at runtime.
+
+The parameters are specified in S-expression format.  See the example
+configuration file in I</etc/xen/xend-config.sxp> for details.
+
+=head1 OPTIONS
+
+The following lists the daemon configuration parameters:
+
+=over 4
+
+=item I<logfile>
+
+The location of the file to record runtime log messages.  Defaults to
+I</var/log/xend.log>.
+
+=item I<loglevel>
+
+Filters out messages below the specified level.  Possible values are
+DEBUG, INFO, WARNING, ERROR, CRITICAL.  Defaults to I<DEBUG>.
+
+=item I<xend-http-server>
+
+A boolean value that tells xend whether or not to start the http
+stream socket management server.  Defaults to I<no>.
+
+=item I<xend-unix-server>
+
+A boolean value that tells xend whether or not to start the unix
+domain socket management server.  This is required for the CLI tools
+to operate.  Defaults to I<yes>.
+
+=item I<xend-relocation-server>
+
+A boolean value that tells xend whether or not to start the relocation
+server.  This is required for cross-machine migrations.  Defaults to
+I<no>.
+
+=item I<xend-unix-path>
+
+The location of the unix domain socket the xend-unix-server will use
+to communicate with the management tools.  Defaults to
+I</var/lib/xend/xend-socket>.
+
+=item I<xend-port>
+
+The port that will be used by the http management server.  Defaults to
+I<8000>.
+
+=item I<xend-relocation-port>
+
+The port that will be used by the relocation server.  Defaults to
+I<8002>.
+
+=item I<xend-address> 
+
+The address to which the http management server will bind.  Defaults
+to I<''> which means "all interfaces".
+
+=item I<xend-relocation-address>
+
+The address to which the relocation server will bind.  Defaults to
+I<''> which means "all interfaces".
+
+=item I<console-limit>
+
+The kilobyte buffer limit that will be enforced by the console server.
+This limit is set per-domain, and is needed to prevent a single domain
+from overwhelming the console server with massive amounts of data.
+Defaults to I<1024>.
+
+=item I<network-script>
+
+The name of the script in I</etc/xen/scripts> that will be run to
+setup the networking environment.  This can be any name, but in
+general is either I<network-bridge> or I<network-route>.
+
+=item I<vif-script>
+
+The name of the script in I</etc/xen/scripts> that will be run to
+setup a virtual interface when it is created or destroyed.  This needs
+to (in general) work in unison with the I<network-script>.
+
+=item I<dom0-min-mem>
+
+This specifies the minimum number of megabytes that will be reserved
+for Domain0.  If this value is positive, Domain0 will be automatically
+ballooned down to this limit to make space for new domains.  If this
+is set to 0, Domain0 will not be automatically ballooned.
+
+=item I<dom0-cpus>
+
+This specifies the number of CPUs that Domain0 will be allowed to use.
+If the value is 0, all available CPUs will be used by Domain0.
+
+=item I<enable-dump>
+
+A boolean value that tells xend whether or not core dumps of guest
+domains should be saved when a crash occurrs.  Defaults to I<no>.
+
+=back
+
+=head1 EXAMPLES
+
+An example configuration with relocation enabled for the local network:
+
+=over 4
+
+ (xend-relocation-server yes)
+ (xend-relocation-address 192.168.1.1)
+ (network-script network-bridge)
+ (vif-script vif-bridge)
+ (dom0-min-mem 0)
+ (dom0-cpus 0)
+
+=back
+
+=head1 CAVEATS
+
+Note that relocation is currently unsecured and is very dangerous if
+left enabled.  No authentication is performed, and very little sanity
+checking takes place.  Enable at your own risk.
+
+=head1 SEE ALSO
+
+B<xend>(1)
+
+=head1 AUTHOR
+
+Dan Smith <danms@xxxxxxxxxx>
+
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/i386/kernel/fixup.c
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/fixup.c Fri Dec  2 18:52:25 2005
@@ -0,0 +1,95 @@
+/******************************************************************************
+ * fixup.c
+ * 
+ * Binary-rewriting of certain IA32 instructions, on notification by Xen.
+ * Used to avoid repeated slow emulation of common instructions used by the
+ * user-space TLS (Thread-Local Storage) libraries.
+ * 
+ * **** NOTE ****
+ *  Issues with the binary rewriting have caused it to be removed. Instead
+ *  we rely on Xen's emulator to boot the kernel, and then print a banner
+ *  message recommending that the user disables /lib/tls.
+ * 
+ * Copyright (c) 2004, K A Fraser
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+
+#define DP(_f, _args...) printk(KERN_ALERT "  " _f "\n" , ## _args )
+
+fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
+{
+       static unsigned long printed = 0;
+       char info[100];
+       int i;
+
+       if (test_and_set_bit(0, &printed))
+               return;
+
+       HYPERVISOR_vm_assist(
+               VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
+
+       sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
+
+
+       DP("");
+       DP("***************************************************************");
+       DP("***************************************************************");
+       DP("** WARNING: Currently emulating unsupported memory accesses  **");
+       DP("**          in /lib/tls glibc libraries. The emulation is    **");
+       DP("**          slow. To ensure full performance you should      **");
+       DP("**          install a 'xen-friendly' (nosegneg) version of   **");
+       DP("**          the library, or disable tls support by executing **");
+       DP("**          the following as root:                           **");
+       DP("**          mv /lib/tls /lib/tls.disabled                    **");
+       DP("** Offending process: %-38.38s **", info);
+       DP("***************************************************************");
+       DP("***************************************************************");
+       DP("");
+
+       for (i = 5; i > 0; i--) {
+               printk("Pausing... %d", i);
+               mdelay(1000);
+               printk("\b\b\b\b\b\b\b\b\b\b\b\b");
+       }
+
+       printk("Continuing...\n\n");
+}
+
+static int __init fixup_init(void)
+{
+       HYPERVISOR_vm_assist(
+               VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
+       return 0;
+}
+__initcall(fixup_init);
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/char/Makefile
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/char/Makefile    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,2 @@
+
+obj-y  := mem.o
diff -r eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/drivers/xen/char/mem.c
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c       Fri Dec  2 18:52:25 2005
@@ -0,0 +1,157 @@
+/*
+ *  Originally from 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>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.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/smp_lock.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/ptrace.h>
+#include <linux/device.h>
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/hypervisor.h>
+
+static inline int uncached_access(struct file *file)
+{
+        if (file->f_flags & O_SYNC)
+                return 1;
+        /* Xen sets correct MTRR type on non-RAM for us. */
+        return 0;
+}
+
+/*
+ * This funcion reads the *physical* memory. The f_pos points directly to the 
+ * memory location. 
+ */
+static ssize_t read_mem(struct file * file, char __user * buf,
+                       size_t count, loff_t *ppos)
+{
+       unsigned long i, p = *ppos;
+       ssize_t read = -EFAULT;
+       void __iomem *v;
+
+       if ((v = ioremap(p, count)) == NULL) {
+               /*
+                * Some programs (e.g., dmidecode) groove off into weird RAM
+                * areas where no table scan possibly exist (because Xen will
+                * have stomped on them!). These programs get rather upset if
+                 * we let them know that Xen failed their access, so we fake
+                 * out a read of all zeroes. :-)
+                */
+               for (i = 0; i < count; i++)
+                       if (put_user(0, buf+i))
+                               return -EFAULT;
+               return count;
+       }
+       if (copy_to_user(buf, v, count))
+               goto out;
+
+       read = count;
+       *ppos += read;
+out:
+       iounmap(v);
+       return read;
+}
+
+static ssize_t write_mem(struct file * file, const char __user * buf, 
+                        size_t count, loff_t *ppos)
+{
+       unsigned long p = *ppos;
+       ssize_t written = -EFAULT;
+       void __iomem *v;
+
+       if ((v = ioremap(p, count)) == NULL)
+               return -EFAULT;
+       if (copy_from_user(v, buf, count))
+               goto out;
+
+       written = count;
+       *ppos += written;
+out:
+       iounmap(v);
+       return written;
+}
+
+static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+{
+       if (uncached_access(file))
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       if (direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+                                  vma->vm_end - vma->vm_start,
+                                  vma->vm_page_prot, DOMID_IO))
+               return -EAGAIN;
+
+       return 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;
+
+       down(&file->f_dentry->d_inode->i_sem);
+       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;
+       }
+       up(&file->f_dentry->d_inode->i_sem);
+       return ret;
+}
+
+static int open_mem(struct inode * inode, struct file * filp)
+{
+       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+}
+
+struct file_operations mem_fops = {
+       .llseek         = memory_lseek,
+       .read           = read_mem,
+       .write          = write_mem,
+       .mmap           = mmap_mem,
+       .open           = open_mem,
+};
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/include/asm-xen/tpmfe.h
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/tpmfe.h      Fri Dec  2 18:52:25 2005
@@ -0,0 +1,33 @@
+#ifndef TPM_FE_H
+#define TPM_FE_H
+
+struct tpmfe_device {
+       /*
+        * Let upper layer receive data from front-end
+        */
+       int (*receive)(const u8 *buffer, size_t count, const void *ptr);
+       /*
+        * Indicate the status of the front-end to the upper
+        * layer.
+        */
+       void (*status)(unsigned int flags);
+
+       /*
+        * This field indicates the maximum size the driver can
+        * transfer in one chunk. It is filled out by the front-end
+        * driver and should be propagated to the generic tpm driver
+        * for allocation of buffers.
+        */
+       unsigned int max_tx_size;
+};
+
+enum {
+       TPMFE_STATUS_DISCONNECTED = 0x0,
+       TPMFE_STATUS_CONNECTED = 0x1
+};
+
+int tpm_fe_send(const u8 * buf, size_t count, void *ptr);
+int tpm_fe_register_receiver(struct tpmfe_device *);
+void tpm_fe_unregister_receiver(void);
+
+#endif
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/README.incompatibilities
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/examples/README.incompatibilities   Fri Dec  2 18:52:25 2005
@@ -0,0 +1,31 @@
+Command Incompatibilities
+=========================
+
+Known incompatibilities with various commands on various distributions, and
+the workarounds we use.
+
+
+brctl
+-----
+
+brctl show <bridge> fails on SLES9 SP2.  Workaround is to use brctl show
+without arguments, and grep, though this would be difficult were you to need
+to check for a specific bridge-interface pair, since brctl does not show the 
+bridge name on every line.
+
+
+ifup / ifdown
+-------------
+
+SuSE requires an extra parameter to ifup, which is created by calling getcfg
+appropriately.  See xen-network-common.sh for details.
+
+Gentoo doesn't have ifup/ifdown; appropriate alternatives are defined in
+xen-network-common.sh.
+
+
+sed
+---
+
+\s is not supported in regexps on Debian etch (sed 4.1.2), Ubuntu 4.10.  We
+hand-craft character classes instead.
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/vtpm
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/examples/vtpm       Fri Dec  2 18:52:25 2005
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+dir=$(dirname "$0")
+. "$dir/vtpm-common.sh"
+
+
+case "$command" in
+    online | offline)
+        exit 0
+        ;;
+esac
+
+case "$command" in
+  add)
+    vtpm_create_instance
+  ;;
+  remove)
+    vtpm_remove_instance
+  ;;
+esac
+
+log debug "Successful vTPM operation '$command'."
+success
diff -r eae5812f33f1 -r 28bd01c9b596 tools/examples/vtpm-common.sh
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/examples/vtpm-common.sh     Fri Dec  2 18:52:25 2005
@@ -0,0 +1,281 @@
+#
+# Copyright (c) 2005 IBM Corporation
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+
+findCommand "$@"
+if [ "$command" != "online" ]  &&
+   [ "$command" != "offline" ] &&
+   [ "$command" != "add" ]     &&
+   [ "$command" != "remove" ]
+then
+       log err "Invalid command: $command"
+       exit 1
+fi
+
+
+XENBUS_PATH="${XENBUS_PATH:?}"
+
+
+VTPMDB="/etc/xen/vtpm.db"
+
+#In the vtpm-impl file some commands should be defined:
+#      vtpm_create, vtpm_setup, vtpm_reset, etc. (see below)
+#This should be indicated by setting VTPM_IMPL_DEFINED.
+if [ -r "$dir/vtpm-impl" ]; then
+       . "$dir/vtpm-impl"
+fi
+
+if [ -z "$VTPM_IMPL_DEFINED" ]; then
+       function vtpm_create () {
+               true
+       }
+       function vtpm_setup() {
+               true
+       }
+       function vtpm_reset() {
+               true
+       }
+       function vtpm_suspend() {
+               true
+       }
+       function vtpm_resume() {
+               true
+       }
+fi
+
+#Find the instance number for the vtpm given the name of the domain
+# Parameters
+# - vmname : the name of the vm
+# Return value
+#  Returns '0' if instance number could not be found, otherwise
+#  it returns the instance number in the variable 'instance'
+function find_instance () {
+       local vmname=$1
+       local ret=0
+       instance=`cat $VTPMDB |                    \
+                 awk -vvmname=$vmname             \
+                 '{                               \
+                    if ( 1 != index($1,"#")) {    \
+                      if ( $1 == vmname ) {       \
+                        print $2;                 \
+                        exit;                     \
+                      }                           \
+                    }                             \
+                  }'`
+       if [ "$instance" != "" ]; then
+               ret=1
+       fi
+       return $ret
+}
+
+
+# Check whether a particular instance number is still available
+# returns '1' if it is available
+function is_free_instancenum () {
+       local instance=$1
+       local avail=1
+
+       #Allowed instance number range: 1-255
+       if [ $instance -eq 0 -o $instance -gt 255 ]; then
+               avail=0
+       else
+               instances=`cat $VTPMDB |                 \
+                          gawk                          \
+                          '{                            \
+                              if (1 != index($1,"#")) { \
+                                printf("%s ",$2);       \
+                              }                         \
+                           }'`
+               for i in $instances; do
+                       if [ $i -eq $instance ]; then
+                               avail=0
+                               break
+                       fi
+               done
+       fi
+       return $avail
+}
+
+
+# Get an available instance number given the database
+# Returns an unused instance number
+function get_free_instancenum () {
+       local ctr
+       local instances
+       local don
+       instances=`cat $VTPMDB |                 \
+                  gawk                          \
+                  '{                            \
+                      if (1 != index($1,"#")) { \
+                        printf("%s ",$2);       \
+                      }                         \
+                   }'`
+       ctr=1
+       don=0
+       while [ $don -eq 0 ]; do
+               local found
+               found=0
+               for i in $instances; do
+                       if [ $i -eq $ctr ]; then
+                               found=1;
+                               break;
+                       fi
+               done
+
+               if [ $found -eq 0 ]; then
+                       don=1
+                       break
+               fi
+               let ctr=ctr+1
+       done
+       let instance=$ctr
+}
+
+
+# Add a domain name and instance number to the DB file
+function add_instance () {
+       local vmname=$1
+       local inst=$2
+
+       if [ ! -f $VTPMDB ]; then
+               echo "#Database for VM to vTPM association" > $VTPMDB
+               echo "#1st column: domain name" >> $VTPMDB
+               echo "#2nd column: TPM instance number" >> $VTPMDB
+       fi
+       validate_entry $vmname $inst
+       if [ $? -eq 0 ]; then
+               echo "$vmname $inst" >> $VTPMDB
+       fi
+}
+
+
+#Validate whether an entry is the same as passed to this
+#function
+function validate_entry () {
+       local rc=0
+       local vmname=$1
+       local inst=$2
+       local res
+       res=`cat $VTPMDB |             \
+            gawk -vvmname=$vmname     \
+                 -vinst=$inst         \
+            '{                        \
+                if ( 1 == index($1,"#")) {\
+                } else                \
+                if ( $1 == vmname &&  \
+                     $2 == inst) {    \
+                   printf("1");       \
+                   exit;              \
+                } else                \
+                if ( $1 == vmname ||  \
+                     $2 == inst) {    \
+                   printf("2");       \
+                   exit;              \
+                }                     \
+            }'`
+
+       if [ "$res" == "1" ]; then
+               let rc=1
+       elif [ "$res" == "2" ]; then
+               let rc=2
+       fi
+       return $rc
+}
+
+
+#Remove an entry from the vTPM database given its domain name
+function remove_entry () {
+       local vmname=$1
+       local VTPMDB_TMP="$VTPMDB".tmp
+       `cat $VTPMDB |             \
+        gawk -vvmname=$vmname     \
+        '{                        \
+           if ( $1 != vmname ) {  \
+             print $0;            \
+           }                      \
+        '} > $VTPMDB_TMP`
+       if [ -e $VTPMDB_TMP ]; then
+               mv -f $VTPMDB_TMP $VTPMDB
+       else
+               log err "Error creating temporary file '$VTPMDB_TMP'."
+       fi
+}
+
+
+#Create a vTPM instance
+# If no entry in the TPM database is found, the instance is
+# created and an entry added to the database.
+function vtpm_create_instance () {
+       local domname=$(xenstore_read "$XENBUS_PATH"/domain)
+       local res
+       set +e
+       find_instance $domname
+       res=$?
+       if [ $res -eq 0 ]; then
+               #Try to give the preferred instance to the domain
+               instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
+               if [ "$instance" != "" ]; then
+                       is_free_instancenum $instance
+                       res=$?
+                       if [ $res -eq 0 ]; then
+                               get_free_instancenum
+                       fi
+               else
+                       get_free_instancenum
+               fi
+               add_instance $domname $instance
+               if [ "$REASON" == "create" ]; then
+                       vtpm_create $instance
+               elif [ "$REASON" == "hibernate" ]; then
+                       vtpm_resume $instance $domname
+               else
+                       #default case for 'now'
+                       vtpm_create $instance
+               fi
+       fi
+       if [ "$REASON" == "create" ]; then
+               vtpm_reset $instance
+       elif [ "$REASON" == "hibernate" ]; then
+               vtpm_setup $instance
+       else
+               #default case for 'now'
+               vtpm_reset $instance
+       fi
+       xenstore_write $XENBUS_PATH/instance $instance
+       set -e
+}
+
+
+#Remove an instance
+function vtpm_remove_instance () {
+       local domname=$(xenstore_read "$XENBUS_PATH"/domain)
+       set +e
+       find_instance $domname
+       res=$?
+       if [ $res -eq 0 ]; then
+               #Something is really wrong with the DB
+               log err "vTPM DB file $VTPMDB has no entry for '$domname'"
+       else
+               if [ "$REASON" == "hibernate" ]; then
+                       vtpm_suspend $instance
+               fi
+       fi
+       set -e
+}
diff -r eae5812f33f1 -r 28bd01c9b596 tools/misc/xen-bugtool
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/misc/xen-bugtool    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+#  -*- mode: python; -*-
+
+# Copyright (c) 2005, XenSource Ltd.
+
+import sys
+
+sys.path.append('/usr/lib/python')
+sys.path.append('/usr/lib64/python')
+
+from xen.util import bugtool
+
+
+if __name__ == "__main__":
+    try:
+        sys.exit(bugtool.main())
+    except KeyboardInterrupt:
+        print "\nInterrupted."
+        sys.exit(1)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/util/bugtool.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/util/bugtool.py  Fri Dec  2 18:52:25 2005
@@ -0,0 +1,232 @@
+#!/usr/bin/env python
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+# Copyright (c) 2005, XenSource Ltd.
+
+
+import errno
+import getpass
+import httplib
+import re
+import os
+import os.path
+import StringIO
+import sys
+import tarfile
+import tempfile
+import time
+import urllib
+
+import xen.lowlevel.xc
+
+from xen.xend import encode
+
+
+SERVER = 'bugzilla.xensource.com'
+SHOW_BUG_PATTERN = 'http://%s/bugzilla/show_bug.cgi?id=%%d' % SERVER
+ATTACH_PATTERN = \
+ 'http://%s/bugzilla/attachment.cgi?bugid=%%d&action=enter' % SERVER
+
+TITLE_RE = re.compile(r'<title>(.*)</title>')
+
+FILES_TO_SEND = [ '/var/log/syslog', '/var/log/messages', '/var/log/debug',
+                  '/var/log/xend.log', '/var/log/xend-debug.log',
+                  '/var/log/xenstored-trace.log' ]
+#FILES_TO_SEND = [  ]
+
+
+def main(argv = None):
+    if argv is None:
+        argv = sys.argv
+
+    print '''
+This application will collate the Xen dmesg output, details of the hardware
+configuration of your machine, information about the build of Xen that you are
+using, plus, if you allow it, various logs.
+
+The information collated can either be posted to a Xen Bugzilla bug (this bug
+must already exist in the system, and you must be a registered user there), or
+it can be saved as a .tar.bz2 for sending or archiving.
+
+The collated logs may contain private information, and if you are at all
+worried about that, you should exit now, or you should explicitly exclude
+those logs from the archive.
+
+'''
+    
+    bugball = []
+
+    xc = xen.lowlevel.xc.xc()
+
+    def do(n, f):
+        try:
+            s = f()
+        except Exception, exn:
+            s = str(exn)
+        bugball.append(string_iterator(n, s))
+
+    do('xen-dmesg', lambda: xc.readconsolering())
+    do('physinfo',  lambda: prettyDict(xc.physinfo()))
+    do('xeninfo',   lambda: prettyDict(xc.xeninfo()))
+
+    for filename in FILES_TO_SEND:
+        if not os.path.exists(filename):
+            continue
+
+        if yes('Include %s? [Y/n] ' % filename):
+            bugball.append(file(filename))
+
+    maybeAttach(bugball)
+
+    if (yes('''
+Do you wish to save these details as a tarball (.tar.bz2)? [Y/n] ''')):
+        tar(bugball)
+
+    return 0
+
+
+def maybeAttach(bugball):
+    if not yes('''
+Do you wish to attach these details to a Bugzilla bug? [Y/n] '''):
+        return
+
+    bug = int(raw_input('Bug number? '))
+
+    bug_title = getBugTitle(bug)
+
+    if bug_title == 'Search by bug number' or bug_title == 'Invalid Bug ID':
+        print >>sys.stderr, 'Bug %d does not exist!' % bug
+        maybeAttach(bugball)
+    elif yes('Are you sure that you want to attach to %s? [Y/n] ' %
+             bug_title):
+        attach(bug, bugball)
+    else:
+        maybeAttach(bugball)
+
+
+def attach(bug, bugball):
+    username = raw_input('Bugzilla username: ')
+    password = getpass.getpass('Bugzilla password: ')
+
+    conn = httplib.HTTPConnection(SERVER)
+    try:
+        for f in bugball:
+            send(bug, conn, f, f.name, username, password)
+    finally:
+        conn.close()
+
+
+def getBugTitle(bug):
+    f = urllib.urlopen(SHOW_BUG_PATTERN % bug)
+
+    try:
+        for line in f:
+            m = TITLE_RE.search(line)
+            if m:
+                return m.group(1)
+    finally:
+        f.close()
+
+    raise "Could not find title of bug %d!" % bug
+
+
+def send(bug, conn, fd, filename, username, password):
+
+    print "Attaching %s to bug %d." % (filename, bug)
+    
+    headers, data = encode.encode_data(
+        { 'bugid'                : str(bug),
+          'action'               : 'insert',
+          'data'                 : fd,
+          'description'          : '%s from %s' % (filename, username),
+          'contenttypeselection' : 'text/plain',
+          'contenttypemethod'    : 'list',
+          'ispatch'              : '0',
+          'GoAheadAndLogIn'      : '1',
+          'Bugzilla_login'       : username,
+          'Bugzilla_password'    : password,
+          })
+    
+    conn.request('POST',ATTACH_PATTERN % bug, data, headers)
+    response = conn.getresponse()
+    try:
+        body = response.read()
+        m = TITLE_RE.search(body)
+
+        if response.status != 200:
+            print >>sys.stderr, (
+                'Attach failed: %s %s.' % (response.status, response.reason))
+        elif not m or m.group(1) != 'Changes Submitted':
+            print >>sys.stderr, (
+                'Attach failed: got a page titled %s.' % m.group(1))
+        else:
+            print "Attaching %s to bug %d succeeded." % (filename, bug)
+    finally:
+        response.close()
+
+
+def tar(bugball):
+    filename = raw_input('Tarball destination filename? ')
+
+    now = time.time()
+
+    tf = tarfile.open(filename, 'w:bz2')
+
+    try:
+        for f in bugball:
+            ti = tarfile.TarInfo(f.name.split('/')[-1])
+            if hasattr(f, 'size'):
+                ti.size = f.size()
+            else:
+                ti.size = os.stat(f.name).st_size
+
+            ti.mtime = now
+            ti.type = tarfile.REGTYPE
+            ti.uid = 0
+            ti.gid = 0
+            ti.uname = 'root'
+            ti.gname = 'root'
+
+            f.seek(0) # If we've added this file to a bug, it will have been
+                      # read once already, so reset it.
+            tf.addfile(ti, f)
+    finally:
+        tf.close()
+
+    print 'Writing tarball %s successful.' % filename
+
+
+def prettyDict(d):
+    format = '%%-%ds: %%s' % max(map(len, [k for k, _ in d.items()]))
+    return '\n'.join([format % i for i in d.items()]) + '\n'
+
+
+class string_iterator(StringIO.StringIO):
+    def __init__(self, name, val):
+        StringIO.StringIO.__init__(self, val)
+        self.name = name
+
+    def size(self):
+        return len(self.getvalue())
+
+
+def yes(prompt):
+    yn = raw_input(prompt)
+
+    return len(yn) == 0 or yn.lower()[0] == 'y'
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/balloon.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/balloon.py  Fri Dec  2 18:52:25 2005
@@ -0,0 +1,97 @@
+#===========================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
+#============================================================================
+
+
+import time
+
+import xen.lowlevel.xc
+
+import XendDomain
+import XendRoot
+from XendLogging import log
+from XendError import VmError
+
+
+PROC_XEN_BALLOON = "/proc/xen/balloon"
+BALLOON_OUT_SLACK = 1 # MiB.  We need this because the physinfo details are
+                      # rounded.
+
+
+def free(required):
+    """Balloon out memory from the privileged domain so that there is the
+    specified required amount (in KiB) free.
+    """
+    
+    xc = xen.lowlevel.xc.xc()
+    xroot = XendRoot.instance()
+
+    try:
+        free_mem = xc.physinfo()['free_memory']
+        need_mem = (required + 1023) / 1024 + BALLOON_OUT_SLACK
+
+        log.debug("Balloon: free %d; need %d.", free_mem, need_mem)
+        
+        if free_mem >= need_mem:
+            return
+
+        dom0_min_mem = xroot.get_dom0_min_mem()
+        if dom0_min_mem == 0:
+            raise VmError('Not enough free memory and dom0_min_mem is 0.')
+
+        dom0_alloc = _get_dom0_alloc()
+        dom0_new_alloc = dom0_alloc - (need_mem - free_mem)
+        if dom0_new_alloc < dom0_min_mem:
+            raise VmError(
+                ('I need %d MiB, but dom0_min_mem is %d and shrinking to '
+                 '%d MiB would leave only %d MiB free.') %
+                (need_mem, dom0_min_mem, dom0_min_mem,
+                 free_mem + (dom0_alloc - dom0_min_mem)))
+
+        dom0 = XendDomain.instance().privilegedDomain()
+        dom0.setMemoryTarget(dom0_new_alloc)
+
+        timeout = 20 # 2 sec
+        while timeout > 0:
+            time.sleep(0.1)
+
+            free_mem = xc.physinfo()['free_memory']
+            if free_mem >= need_mem:
+                return
+
+            timeout -= 1
+
+        raise VmError('The privileged domain did not balloon!')
+    finally:
+        del xc
+
+
+def _get_dom0_alloc():
+    """Return current allocation memory of dom0 (in MiB). Return 0 on error"""
+
+    f = file(PROC_XEN_BALLOON, 'r')
+    try:
+        line = f.readline()
+        for x in line.split():
+            for n in x:
+                if not n.isdigit():
+                    break
+            else:
+                return int(x) / 1024
+        return 0
+    finally:
+        f.close()
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/python/xen/xend/server/tests/__init__.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/tests/__init__.py    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,1 @@
+ 
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/python/xen/xend/server/tests/test_controllers.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/python/xen/xend/server/tests/test_controllers.py    Fri Dec  2 
18:52:25 2005
@@ -0,0 +1,81 @@
+import os
+import re
+import unittest
+
+import xen.xend.XendRoot
+
+xen.xend.XendRoot.XendRoot.config_default = '/dev/null'
+
+from xen.xend.server import netif
+
+
+FAKE_DOMID = 42
+FAKE_DEVID = 63
+
+
+xroot = xen.xend.XendRoot.instance()
+
+
+class test_controllers(unittest.TestCase):
+
+    def testNetif(self):
+        controller = self.controllerInstance(netif.NetifController)
+
+        self.assertNetif(controller.getDeviceDetails(['vif']), None)
+        self.assertNetif(
+            controller.getDeviceDetails(
+            ['vif', ['mac', 'aa:bb:cc:dd:ee:ff']]),
+            'aa:bb:cc:dd:ee:ff')
+
+
+    def assertNetif(self, results, expectedMac):
+
+        (devid, backdets, frontdets) = results
+
+        self.assertEqual(devid, FAKE_DEVID)
+
+        self.assertEqual(backdets['handle'], str(FAKE_DEVID))
+        self.assertEqual(backdets['script'],
+                         os.path.join(xroot.network_script_dir,
+                                      xroot.get_vif_script()))
+        self.assertValidMac(backdets['mac'], expectedMac)
+
+        self.assertEqual(frontdets['handle'], str(FAKE_DEVID))
+        self.assertValidMac(frontdets['mac'], expectedMac)
+
+
+    MAC_REGEXP = re.compile('^' +
+                            ':'.join([r'[0-9a-f][0-9a-f]'
+                                      for i in range(0, 6)]) +
+                            '$')
+
+    def assertValidMac(self, mac, expected):
+        if expected:
+            self.assertEqual(mac, expected)
+        else:
+            self.assert_(self.MAC_REGEXP.match(mac))
+            
+
+    def controllerInstance(self, cls):
+        """Allocate an instance of the given controller class, and override
+        methods as appropriate so that we can run tests without needing
+        Xenstored."""
+        
+        result = cls(FakeXendDomainInfo())
+
+        result.allocateDeviceID = fakeID
+
+        return result
+
+
+class FakeXendDomainInfo:
+    def getDomainPath(self):
+        return "/test/fake/domain/%d/" % FAKE_DOMID
+
+
+def fakeID():
+    return FAKE_DEVID
+
+
+def test_suite():
+    return unittest.makeSuite(test_controllers)
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/tests/_sanity/01_domu_proc.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/_sanity/01_domu_proc.py       Fri Dec  2 18:52:25 2005
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Dan Smith <danms@xxxxxxxxxx>
+
+#
+# Test that the library and ramdisk are working to the point
+# that we can start a DomU and read /proc
+#
+
+from XmTestLib import *
+
+import re
+
+domain = XmTestDomain()
+
+try:
+    domain.start()
+except DomainError, e:
+    FAIL(str(e))
+
+try:
+    console = XmConsole(domain.getName())
+    console.sendInput("foo")
+    run = console.runCmd("cat /proc/cpuinfo")
+except ConsoleError, e:
+    FAIL(str(e))
+
+if run["return"] != 0:
+    FAIL("Unable to read /proc/cpuinfo")
+
+if not re.search("processor", run["output"]):
+    print run["output"]
+    FAIL("/proc/cpuinfo looks wrong!")
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/tests/_sanity/Makefile.am
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/_sanity/Makefile.am   Fri Dec  2 18:52:25 2005
@@ -0,0 +1,21 @@
+
+SUBDIRS =
+
+TESTS = 01_domu_proc.test 
+
+XFAIL_TESTS = 
+
+EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
+
+TESTS_ENVIRONMENT=@TENV@
+
+%.test: %.py
+       cp $< $@
+       chmod +x $@
+
+clean-local: am_config_clean-local
+
+am_config_clean-local:
+       rm -f *test
+       rm -f *log
+       rm -f *~
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py   Fri Dec 
 2 18:52:25 2005
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Dan Smith <danms@xxxxxxxxxx>
+
+from XmTestLib import *
+
+# Mount /dev/ram0
+
+s, o = traceCommand("mkfs /dev/ram0")
+if s != 0:
+    FAIL("Unable to mkfs /dev/ram0")
+
+s, o = traceCommand("mkdir -p mnt");
+if s != 0:
+    FAIL("Unable to create ./mnt")
+
+s, o = traceCommand("mount /dev/ram0 mnt -o rw")
+if s != 0:
+    FAIL("Unable to mount /dev/ram0 on ./mnt")
+
+# Now try to start a DomU with write access to /dev/ram0
+
+domain = XmTestDomain();
+domain.configAddDisk("phy:/dev/ram0", "hda1", "w")
+
+try:
+    domain.start()
+    s, o = traceCommand("umount mnt")
+    FAIL("Bug #331: Started a DomU with write access to a rw mounted block 
device")
+except DomainError, e:
+    s, o = traceCommand("umount mnt")
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/block-create/12_block_attach_shared_domU.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/block-create/12_block_attach_shared_domU.py   Fri Dec 
 2 18:52:25 2005
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Dan Smith <danms@xxxxxxxxxx>
+
+from XmTestLib import *
+
+dom1 = XmTestDomain()
+dom2 = XmTestDomain(dom1.getName() + "-2")
+
+dom1.configAddDisk("phy:/dev/ram0", "hda1", "w")
+dom2.configAddDisk("phy:/dev/ram0", "hda1", "w")
+
+try:
+    dom1.start()
+except DomainError, e:
+    FAIL("Unable to start domain")
+
+try:
+    dom2.start()
+    dom1.destroy()
+    FAIL("Bug #331: Started a DomU with write access to an in-use block 
device")
+except DomainError, e:
+    dom1.destroy()
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py      
Fri Dec  2 18:52:25 2005
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Dan Smith <danms@xxxxxxxxxx>
+
+from XmTestLib import *
+
+import time
+import re
+
+def checkBlockList(domain):
+    s, o = traceCommand("xm block-list %s" % domain.getName())
+    if s != 0:
+        FAIL("block-list failed")
+    if re.search("769", o):
+        return True
+    else:
+        return False
+
+def checkXmLongList(domain):
+    s, o = traceCommand("xm list --long %s" % domain.getName())
+    if s != 0:
+        FAIL("xm list --long <dom> failed")
+    if re.search("hda1", o):
+        return True
+    else:
+        return False
+
+domain = XmTestDomain()
+
+try:
+    domain.start()
+except DomainError,e:
+    FAIL(str(e))
+
+s, o = traceCommand("xm block-attach %s phy:/dev/ram0 hda1 w" % 
domain.getName())
+if s != 0:
+    FAIL("block-attach failed")
+
+if not checkBlockList(domain):
+    FAIL("block-list does not show that hda1 was attached")
+
+if not checkXmLongList(domain):
+    FAIL("xm long list does not show that hda1 was attached")
+
+s, o = traceCommand("xm block-detach %s hda1" % domain.getName())
+if s != 0:
+    FAIL("block-detach failed")
+
+time.sleep(2)
+
+if checkBlockList(domain):
+    FAIL("block-list does not show that hda1 was removed")
+
+if checkXmLongList(domain):
+    FAIL("xm long list does not show that hda1 was removed")
+
+
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/network-attach/01_network_attach_pos.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/network-attach/01_network_attach_pos.py       Fri Dec 
 2 18:52:25 2005
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx>
+
+import sys
+
+from XmTestLib import *
+from network_utils import *
+
+# Create a domain (default XmTestDomain, with our ramdisk)
+domain = XmTestDomain()
+
+try:
+    domain.start()
+except DomainError, e:
+    if verbose:
+        print "Failed to create test domain because:"
+        print e.extra
+    FAIL(str(e))
+
+# Attach a console to it
+try:
+    console = XmConsole(domain.getName(), historySaveCmds=True)
+except ConsoleError, e:
+    FAIL(str(e))
+
+try:
+    # Activate the console
+    console.sendInput("input")
+    # Run 'ls'
+    run = console.runCmd("ls")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    FAIL(str(e))
+    
+## Real test
+status, msg = network_attach(domain.getName(), console)
+if status:
+    FAIL(msg)
+
+
+##
+# Close the console
+console.closeConsole()
+
+# Stop the domain (nice shutdown)
+domain.stop()
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py        
Fri Dec  2 18:52:25 2005
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx>
+
+import sys
+import re
+import time
+
+from XmTestLib import *
+from network_utils import *
+
+# Create a domain (default XmTestDomain, with our ramdisk)
+domain = XmTestDomain()
+
+try:
+    domain.start()
+except DomainError, e:
+    if verbose:
+        print "Failed to create test domain because:"
+        print e.extra
+    FAIL(str(e))
+
+# Attach a console to it
+try:
+    console = XmConsole(domain.getName(), historySaveCmds=True)
+except ConsoleError, e:
+    FAIL(str(e))
+
+try:
+    # Activate the console
+    console.sendInput("input")
+    # Run 'ls'
+    run = console.runCmd("ls")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    FAIL(str(e))
+
+## Real test - attach and detach
+status, msg = network_attach(domain.getName(), console)
+if status:
+    FAIL(msg)
+
+status, msg = network_detach(domain.getName(), console)
+if status:
+    FAIL(msg)
+
+
+
+# Close the console
+console.closeConsole()
+
+# Stop the domain (nice shutdown)
+domain.stop()
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ 
b/tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py   
    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx>
+
+import sys
+import re
+import time
+
+from XmTestLib import *
+from network_utils import *
+
+# Create a domain (default XmTestDomain, with our ramdisk)
+domain = XmTestDomain()
+
+try:
+    domain.start()
+except DomainError, e:
+    if verbose:
+        print "Failed to create test domain because:"
+        print e.extra
+    FAIL(str(e))
+
+# Attach a console to it
+try:
+    console = XmConsole(domain.getName(), historySaveCmds=True)
+    # network-detach is crashing, so we enable console debugging
+    # for now, so that reports include the oops
+    console.debugMe = True
+except ConsoleError, e:
+    FAIL(str(e))
+
+try:
+    # Activate the console
+    console.sendInput("input")
+    # Run 'ls'
+    run = console.runCmd("ls")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    FAIL(str(e))
+    
+for i in range(10):
+    print "Attaching %d device" % i 
+    status, msg = network_attach(domain.getName(), console)
+    if status:
+        FAIL(msg)
+    
+    print "Detaching %d device" % i 
+    status, msg = network_detach(domain.getName(), console, i)
+    if status:
+        FAIL(msg)
+
+# Close the console
+console.closeConsole()
+
+# Stop the domain (nice shutdown)
+domain.stop()
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py     
Fri Dec  2 18:52:25 2005
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx>
+
+from XmTestLib import *
+
+status, output = traceCommand("xm network-attach NOT-EXIST")
+
+eyecatcher = "Error"
+where = output.find(eyecatcher)
+if status == 0:
+       FAIL("xm block-attach returned bad status, expected non 0, status is: 
%i" % status )
+elif where == -1:
+       FAIL("xm block-attach returned bad output, expected Error, output is: 
%s" % output )
+       
+
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/network-attach/Makefile.am
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/network-attach/Makefile.am    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,24 @@
+
+SUBDIRS =
+
+TESTS = 01_network_attach_pos.test \
+       02_network_attach_detach_pos.test \
+       03_network_attach_detach_multiple_pos.test  \
+       04_network_attach_baddomain_neg.test
+
+XFAIL_TESTS = 03_network_attach_detach_multiple_pos.test
+
+EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) network_utils.py
+
+TESTS_ENVIRONMENT=@TENV@
+
+%.test: %.py
+       cp $< $@
+       chmod +x $@
+
+clean-local: am_config_clean-local
+
+am_config_clean-local:
+       rm -f *test
+       rm -f *log
+       rm -f *~
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/network-attach/network_utils.py
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/tools/xm-test/tests/network-attach/network_utils.py       Fri Dec  2 
18:52:25 2005
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Murillo F. Bernardes <mfb@xxxxxxxxxx>
+
+from XmTestLib import *
+
+def count_eth(console):
+    try:
+        run = console.runCmd("ifconfig -a | grep eth")
+    except ConsoleError, e:
+        FAIL(str(e))
+    return len(run['output'].splitlines())
+
+def network_attach(domain_name, console):
+    eths_before = count_eth(console)
+    status, output = traceCommand("xm network-attach %s" % domain_name)
+    if status != 0:
+        return -1, "xm network-attach returned invalid %i != 0" % status
+
+    eths_after = count_eth(console)
+    if (eths_after != (eths_before+1)):
+        return -2, "Network device is not actually connected to domU"
+
+    return 0, None 
+
+def network_detach(domain_name, console, num=0):
+    eths_before = count_eth(console)
+    status, output = traceCommand("xm network-detach %s %d" % (domain_name, 
num))
+    if status != 0:
+        return -1, "xm network-attach returned invalid %i != 0" % status
+
+    eths_after = count_eth(console)
+    if eths_after != (eths_before-1):
+       return -2, "Network device was not actually disconnected from domU"
+
+    return 0, None
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-ia64/grant_table.h
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-ia64/grant_table.h        Fri Dec  2 18:52:25 2005
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * include/asm-ia64/grant_table.h
+ */
+
+#ifndef __ASM_GRANT_TABLE_H__
+#define __ASM_GRANT_TABLE_H__
+
+#define ORDER_GRANT_FRAMES 0
+
+#define create_grant_host_mapping(a, f, fl)  0
+#define destroy_grant_host_mapping(a, f, fl) 0
+
+#define steal_page_for_grant_transfer(d, p)  0
+
+#define gnttab_create_shared_mfn(d, t, i) ((void)0)
+
+#define gnttab_shared_mfn(d, t, i)                                      \
+    ( ((d) == dom0) ?                                                   \
+      ((virt_to_phys((t)->shared) >> PAGE_SHIFT) + (i)) :               \
+      (map_domain_page((d), 1UL<<40, virt_to_phys((t)->shared)),        \
+       1UL << (40 - PAGE_SHIFT))                                        \
+    )
+
+#define gnttab_log_dirty(d, f) ((void)0)
+
+#endif /* __ASM_GRANT_TABLE_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/grant_table.h
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/grant_table.h Fri Dec  2 18:52:25 2005
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * include/asm-x86/grant_table.h
+ * 
+ * Copyright (c) 2004-2005 K A Fraser
+ */
+
+#ifndef __ASM_GRANT_TABLE_H__
+#define __ASM_GRANT_TABLE_H__
+
+#define ORDER_GRANT_FRAMES 2
+
+/*
+ * Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and
+ * must hold a reference to the page.
+ */
+int create_grant_host_mapping(
+    unsigned long addr, unsigned long frame, unsigned int flags);
+int destroy_grant_host_mapping(
+    unsigned long addr, unsigned long frame, unsigned int flags);
+
+int steal_page_for_grant_transfer(
+    struct domain *d, struct pfn_info *page);
+
+#define gnttab_create_shared_mfn(d, t, i)                                \
+    do {                                                                 \
+        SHARE_PFN_WITH_DOMAIN(                                           \
+            virt_to_page((char *)(t)->shared + ((i) * PAGE_SIZE)), (d)); \
+        set_pfn_from_mfn(                                                \
+            (virt_to_phys((t)->shared) >> PAGE_SHIFT) + (i),             \
+            INVALID_M2P_ENTRY);                                          \
+    } while ( 0 )
+
+#define gnttab_shared_mfn(d, t, i)                      \
+    ((virt_to_phys((t)->shared) >> PAGE_SHIFT) + (i))
+
+#define gnttab_log_dirty(d, f) mark_dirty((d), (f))
+
+#endif /* __ASM_GRANT_TABLE_H__ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/vmx_vpic.h
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/vmx_vpic.h    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,85 @@
+/*
+ * QEMU System Emulator header
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2005 Intel Corp
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef _VMX_VPIC_H
+#define _VMX_VPIC_H
+
+#define hw_error(x)  do {} while (0);
+
+
+/* i8259.c */
+typedef struct IOAPICState IOAPICState;
+typedef struct PicState {
+    uint8_t last_irr; /* edge detection */
+    uint8_t irr; /* interrupt request register */
+    uint8_t imr; /* interrupt mask register */
+    uint8_t isr; /* interrupt service register */
+    uint8_t priority_add; /* highest irq priority */
+    uint8_t irq_base;
+    uint8_t read_reg_select;
+    uint8_t poll;
+    uint8_t special_mask;
+    uint8_t init_state;
+    uint8_t auto_eoi;
+    uint8_t rotate_on_auto_eoi;
+    uint8_t special_fully_nested_mode;
+    uint8_t init4; /* true if 4 byte init */
+    uint8_t elcr; /* PIIX edge/trigger selection*/
+    uint8_t elcr_mask;
+    struct vmx_virpic *pics_state;
+} PicState;
+
+struct vmx_virpic {
+    /* 0 is master pic, 1 is slave pic */
+    /* XXX: better separation between the two pics */
+    PicState pics[2];
+    void (*irq_request)(int *opaque, int level);
+    void *irq_request_opaque;
+    /* IOAPIC callback support */
+    void (*alt_irq_func)(void *opaque, int irq_num, int level);
+    void *alt_irq_opaque;
+};
+
+
+void pic_set_irq(struct vmx_virpic *s, int irq, int level);
+void pic_set_irq_new(void *opaque, int irq, int level);
+void pic_init(struct vmx_virpic *s, 
+              void (*irq_request)(),
+              void *irq_request_opaque);
+void pic_set_alt_irq_func(struct vmx_virpic *s, 
+                          void(*alt_irq_func)(),
+                          void *alt_irq_opaque);
+int pic_read_irq(struct vmx_virpic *s);
+void pic_update_irq(struct vmx_virpic *s);
+uint32_t pic_intack_read(struct vmx_virpic *s);
+void register_pic_io_hook (void);
+int cpu_get_pic_interrupt(struct vcpu *v, int *type);
+int is_pit_irq(struct vcpu *v, int irq, int type);
+int is_irq_enabled(struct vcpu *v, int irq);
+void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs);
+void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs);
+
+/* APIC */
+#endif  /* _VMX_VPIC_H */  
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/vmx_vpit.h
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/xen/include/asm-x86/vmx_vpit.h    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,55 @@
+#ifndef _VMX_VIRPIT_H
+#define _VMX_VIRPIT_H
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/time.h>
+#include <xen/errno.h>
+#include <xen/ac_timer.h>
+#include <asm/vmx_vmcs.h>
+#include <asm/vmx_vpic.h>
+
+#define PIT_FREQ 1193181
+
+#define LSByte 0
+#define MSByte 1
+#define LSByte_multiple 2
+#define MSByte_multiple 3
+
+struct vmx_virpit {
+    /* for simulation of counter 0 in mode 2*/
+    u64 period_cycles;                 /* pit frequency in cpu cycles */
+    u64 inject_point; /* the time inject virt intr */
+    s_time_t scheduled;                 /* scheduled timer interrupt */
+    struct ac_timer pit_timer;  /* periodic timer for mode 2*/
+    unsigned int channel;  /* the pit channel, counter 0~2 */
+    unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
+    u32 period;                /* pit frequency in ns */
+    int first_injected;                 /* flag to prevent shadow window */
+    int ticking;    /* indicating it is ticking */
+
+    /* virtual PIT state for handle related I/O */
+    int read_state;
+    int count_LSB_latched;
+    int count_MSB_latched;
+
+    unsigned int count;  /* the 16 bit channel count */
+    unsigned int init_val; /* the init value for the counter */
+};
+
+/* to hook the ioreq packet to get the PIT initializaiton info */
+extern void vmx_hooks_assist(struct vcpu *v);
+
+static __inline__ s_time_t get_pit_scheduled(
+    struct vcpu *v, 
+    struct vmx_virpit *vpit)
+{
+    if ( is_irq_enabled(v, 0) ) {
+        return vpit->scheduled;
+    }
+    else
+        return -1;
+}
+
+#endif /* _VMX_VIRPIT_H_ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/io/xenbus.h
--- /dev/null   Fri Dec  2 18:12:11 2005
+++ b/xen/include/public/io/xenbus.h    Fri Dec  2 18:52:25 2005
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * xenbus.h
+ *
+ * Xenbus protocol details.
+ *
+ * Copyright (C) 2005 XenSource Ltd.
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following
+ * license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _XEN_XENBUS_H
+#define _XEN_XENBUS_H
+
+
+/* The state of either end of the Xenbus, i.e. the current communication
+   status of initialisation across the bus.  States here imply nothing about
+   the state of the connection between the driver and the kernel's device
+   layers.  */
+typedef enum
+{
+  XenbusStateUnknown      = 0,
+  XenbusStateInitialising = 1,
+  XenbusStateInitWait     = 2,  /* Finished early initialisation, but waiting
+                                   for information from the peer or hotplug
+                                  scripts. */
+  XenbusStateInitialised  = 3,  /* Initialised and waiting for a connection
+                                  from the peer. */
+  XenbusStateConnected    = 4,
+  XenbusStateClosing      = 5,  /* The device is being closed due to an error
+                                  or an unplug event. */
+  XenbusStateClosed       = 6
+
+} XenbusState;
+
+
+#endif /* _XEN_XENBUS_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 eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/kernel/devmem.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c     Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,157 +0,0 @@
-/*
- *  Originally from 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>
- */
-
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/miscdevice.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/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/ptrace.h>
-#include <linux/device.h>
-#include <asm/pgalloc.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/hypervisor.h>
-
-static inline int uncached_access(struct file *file)
-{
-        if (file->f_flags & O_SYNC)
-                return 1;
-        /* Xen sets correct MTRR type on non-RAM for us. */
-        return 0;
-}
-
-/*
- * This funcion reads the *physical* memory. The f_pos points directly to the 
- * memory location. 
- */
-static ssize_t read_mem(struct file * file, char __user * buf,
-                       size_t count, loff_t *ppos)
-{
-       unsigned long i, p = *ppos;
-       ssize_t read = -EFAULT;
-       void *v;
-
-       if ((v = ioremap(p, count)) == NULL) {
-               /*
-                * Some programs (e.g., dmidecode) groove off into weird RAM
-                * areas where no table scan possibly exist (because Xen will
-                * have stomped on them!). These programs get rather upset if
-                 * we let them know that Xen failed their access, so we fake
-                 * out a read of all zeroes. :-)
-                */
-               for (i = 0; i < count; i++)
-                       if (put_user(0, buf+i))
-                               return -EFAULT;
-               return count;
-       }
-       if (copy_to_user(buf, v, count))
-               goto out;
-
-       read = count;
-       *ppos += read;
-out:
-       iounmap(v);
-       return read;
-}
-
-static ssize_t write_mem(struct file * file, const char __user * buf, 
-                        size_t count, loff_t *ppos)
-{
-       unsigned long p = *ppos;
-       ssize_t written = -EFAULT;
-       void *v;
-
-       if ((v = ioremap(p, count)) == NULL)
-               return -EFAULT;
-       if (copy_from_user(v, buf, count))
-               goto out;
-
-       written = count;
-       *ppos += written;
-out:
-       iounmap(v);
-       return written;
-}
-
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
-{
-       if (uncached_access(file))
-               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-       if (direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-                                  vma->vm_end - vma->vm_start,
-                                  vma->vm_page_prot, DOMID_IO))
-               return -EAGAIN;
-
-       return 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;
-
-       down(&file->f_dentry->d_inode->i_sem);
-       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;
-       }
-       up(&file->f_dentry->d_inode->i_sem);
-       return ret;
-}
-
-static int open_mem(struct inode * inode, struct file * filp)
-{
-       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
-}
-
-struct file_operations mem_fops = {
-       .llseek         = memory_lseek,
-       .read           = read_mem,
-       .write          = write_mem,
-       .mmap           = mmap_mem,
-       .open           = open_mem,
-};
-
-/*
- * Local variables:
- *  c-file-style: "linux"
- *  indent-tabs-mode: t
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/arch/xen/kernel/fixup.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/fixup.c      Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,93 +0,0 @@
-/******************************************************************************
- * fixup.c
- * 
- * Binary-rewriting of certain IA32 instructions, on notification by Xen.
- * Used to avoid repeated slow emulation of common instructions used by the
- * user-space TLS (Thread-Local Storage) libraries.
- * 
- * **** NOTE ****
- *  Issues with the binary rewriting have caused it to be removed. Instead
- *  we rely on Xen's emulator to boot the kernel, and then print a banner
- *  message recommending that the user disables /lib/tls.
- * 
- * Copyright (c) 2004, K A Fraser
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/version.h>
-
-#define DP(_f, _args...) printk(KERN_ALERT "  " _f "\n" , ## _args )
-
-fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
-{
-       static unsigned long printed = 0;
-       char info[100];
-       int i;
-
-       if (test_and_set_bit(0, &printed))
-               return;
-
-       HYPERVISOR_vm_assist(
-               VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
-
-       sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
-
-
-       DP("");
-       DP("***************************************************************");
-       DP("***************************************************************");
-       DP("** WARNING: Currently emulating unsupported memory accesses  **");
-       DP("**          in /lib/tls libraries. The emulation is very     **");
-       DP("**          slow. To ensure full performance you should      **");
-       DP("**          execute the following as root:                   **");
-       DP("**          mv /lib/tls /lib/tls.disabled                    **");
-       DP("** Offending process: %-38.38s **", info);
-       DP("***************************************************************");
-       DP("***************************************************************");
-       DP("");
-
-       for (i = 5; i > 0; i--) {
-               printk("Pausing... %d", i);
-               mdelay(1000);
-               printk("\b\b\b\b\b\b\b\b\b\b\b\b");
-       }
-
-       printk("Continuing...\n\n");
-}
-
-static int __init fixup_init(void)
-{
-       HYPERVISOR_vm_assist(
-               VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
-       return 0;
-}
-__initcall(fixup_init);
-
-/*
- * Local variables:
- *  c-file-style: "linux"
- *  indent-tabs-mode: t
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff -r eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/arch/xen/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/smp.c        Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,25 +0,0 @@
-/* Copyright (C) 2004, Christian Limpach */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/threads.h>
-
-/*
- * the frequency of the profiling timer can be changed
- * by writing a multiplier value into /proc/profile.
- */
-int setup_profiling_timer(unsigned int multiplier)
-{
-       printk("setup_profiling_timer\n");
-       return 0;
-}
-
-/*
- * Local variables:
- *  c-file-style: "linux"
- *  indent-tabs-mode: t
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff -r eae5812f33f1 -r 28bd01c9b596 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h   Fri Dec  2 
18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,23 +0,0 @@
-#ifndef _XENCONS_RING_H
-#define _XENCONS_RING_H
-
-asmlinkage int xprintk(const char *fmt, ...);
-
-int xencons_ring_init(void);
-int xencons_ring_send(const char *data, unsigned len);
-
-typedef void (xencons_receiver_func)(
-       char *buf, unsigned len, struct pt_regs *regs);
-void xencons_ring_register_receiver(xencons_receiver_func *f);
-
-#endif /* _XENCONS_RING_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 eae5812f33f1 -r 28bd01c9b596 linux-2.6-xen-sparse/include/linux/tpmfe.h
--- a/linux-2.6-xen-sparse/include/linux/tpmfe.h        Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,33 +0,0 @@
-#ifndef TPM_FE_H
-#define TPM_FE_H
-
-struct tpmfe_device {
-       /*
-        * Let upper layer receive data from front-end
-        */
-       int (*receive)(const u8 *buffer, size_t count, const void *ptr);
-       /*
-        * Indicate the status of the front-end to the upper
-        * layer.
-        */
-       void (*status)(unsigned int flags);
-
-       /*
-        * This field indicates the maximum size the driver can
-        * transfer in one chunk. It is filled out by the front-end
-        * driver and should be propagated to the generic tpm driver
-        * for allocation of buffers.
-        */
-       unsigned int max_tx_size;
-};
-
-enum {
-       TPMFE_STATUS_DISCONNECTED = 0x0,
-       TPMFE_STATUS_CONNECTED = 0x1
-};
-
-int tpm_fe_send(const u8 * buf, size_t count, void *ptr);
-int tpm_fe_register_receiver(struct tpmfe_device *);
-void tpm_fe_unregister_receiver(void);
-
-#endif
diff -r eae5812f33f1 -r 28bd01c9b596 tools/python/xen/xend/scheduler.py
--- a/tools/python/xen/xend/scheduler.py        Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,42 +0,0 @@
-#============================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
-# Copyright (C) 2005 XenSource Ltd
-#============================================================================
-
-import threading
-
-def later(delay, fn, *args, **kwargs):
-    """Schedule a function to be called later.
-
-    @param delay:  delay in seconds
-    @param fn:     function
-    @param args:   arguments (list)
-    @param kwargs  keyword arguments (map)
-    """
-    timer = threading.Timer(delay, fn, args=args, kwargs=kwargs)
-    timer.start()
-    return timer
-
-def now(fn, *args, **kwargs):
-    """Schedule a function to be called now.
-
-    @param fn:     function
-    @param args:   arguments (list)
-    @param kwargs  keyword arguments (map)
-    """
-    thread = threading.Thread(target=fn, args=args, kwargs=kwargs)
-    thread.start()
-    return thread
diff -r eae5812f33f1 -r 28bd01c9b596 tools/vtpm_manager/util/depend
--- a/tools/vtpm_manager/util/depend    Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,7 +0,0 @@
-hashtable.o: hashtable.c hashtable.h hashtable_private.h
-hashtable_itr.o: hashtable_itr.c hashtable.h hashtable_private.h \
-  hashtable_itr.h
-bsg.o: bsg.c tcg.h ../crypto/crypto.h ../crypto/sym_crypto.h buffer.h \
-  bsg.h log.h
-log.o: log.c buffer.h tcg.h
-buffer.o: buffer.c tcg.h bsg.h buffer.h
diff -r eae5812f33f1 -r 28bd01c9b596 tools/xm-test/lib/XmTestLib/config.py
--- a/tools/xm-test/lib/XmTestLib/config.py     Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,4 +0,0 @@
-#!/usr/bin/python
-
-USE_BLKDEV_FOR_ROOT = False
-
diff -r eae5812f33f1 -r 28bd01c9b596 
tools/xm-test/tests/create/05_create_noroot_noram_neg.py
--- a/tools/xm-test/tests/create/05_create_noroot_noram_neg.py  Fri Dec  2 
18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,26 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (C) International Business Machines Corp., 2005
-# Author: Li Ge <lge@xxxxxxxxxx>
-
-# Test description: 
-# Negative Test:
-# Test for creating domain with no ramdisk and no root. Verify fail.
-
-import sys
-import re
-import time
-
-from XmTestLib import *
-
-status, output = traceCommand("xm create /dev/null name=NOROOT memory=64 
kernel=%s" % getDefaultKernel())
-
-# sleep a while to wait for the kernel fails to mount root and NOROOT
-# goes away from the xm list
-time.sleep(15)
-
-eyecatcher = "NOROOT"
-status, output = traceCommand("xm list")
-where = output.find(eyecatcher)
-if where != -1:
-       FAIL("xm create test05 passed with no root and no ramdisk. Expected 
result: Fail.")
diff -r eae5812f33f1 -r 28bd01c9b596 xen/arch/ia64/xen/grant_table.c
--- a/xen/arch/ia64/xen/grant_table.c   Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,1462 +0,0 @@
-// temporarily in arch/ia64 until can merge into common/grant_table.c
-/******************************************************************************
- * common/grant_table.c
- * 
- * Mechanism for granting foreign access to page frames, and receiving
- * page-ownership transfers.
- * 
- * Copyright (c) 2005 Christopher Clark
- * Copyright (c) 2004 K A Fraser
- * Copyright (c) 2005 Andrew Warfield
- * Modifications by Geoffrey Lefebvre are (c) Intel Research Cambridge
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#define GRANT_DEBUG 0
-#define GRANT_DEBUG_VERBOSE 0
-
-#include <xen/config.h>
-#include <xen/lib.h>
-#include <xen/sched.h>
-#include <xen/shadow.h>
-#include <xen/mm.h>
-#ifdef __ia64__
-#define __addr_ok(a) 1 // FIXME-ia64: a variant of access_ok??
-// FIXME-ia64: these belong in an asm/grant_table.h... PAGE_SIZE different
-#undef ORDER_GRANT_FRAMES
-//#undef NUM_GRANT_FRAMES
-#define ORDER_GRANT_FRAMES 0
-//#define NUM_GRANT_FRAMES  (1U << ORDER_GRANT_FRAMES)
-#endif
-#include <acm/acm_hooks.h>
-
-#if defined(CONFIG_X86_64)
-#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#else
-#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY)
-#endif
-
-#define PIN_FAIL(_lbl, _rc, _f, _a...)   \
-    do {                           \
-        DPRINTK( _f, ## _a );      \
-        rc = (_rc);                \
-        goto _lbl;                 \
-    } while ( 0 )
-
-static inline int
-get_maptrack_handle(
-    grant_table_t *t)
-{
-    unsigned int h;
-    if ( unlikely((h = t->maptrack_head) == (t->maptrack_limit - 1)) )
-        return -1;
-    t->maptrack_head = t->maptrack[h].ref_and_flags >> MAPTRACK_REF_SHIFT;
-    t->map_count++;
-    return h;
-}
-
-static inline void
-put_maptrack_handle(
-    grant_table_t *t, int handle)
-{
-    t->maptrack[handle].ref_and_flags = t->maptrack_head << MAPTRACK_REF_SHIFT;
-    t->maptrack_head = handle;
-    t->map_count--;
-}
-
-static int
-__gnttab_activate_grant_ref(
-    struct domain   *mapping_d,          /* IN */
-    struct vcpu     *mapping_ed,
-    struct domain   *granting_d,
-    grant_ref_t      ref,
-    u16              dev_hst_ro_flags,
-    u64              addr,
-    unsigned long   *pframe )            /* OUT */
-{
-    domid_t               sdom;
-    u16                   sflags;
-    active_grant_entry_t *act;
-    grant_entry_t        *sha;
-    s16                   rc = 1;
-    unsigned long         frame = 0;
-    int                   retries = 0;
-
-    /*
-     * Objectives of this function:
-     * . Make the record ( granting_d, ref ) active, if not already.
-     * . Update shared grant entry of owner, indicating frame is mapped.
-     * . Increment the owner act->pin reference counts.
-     * . get_page on shared frame if new mapping.
-     * . get_page_type if this is first RW mapping of frame.
-     * . Add PTE to virtual address space of mapping_d, if necessary.
-     * Returns:
-     * .  -ve: error
-     * .    1: ok
-     * .    0: ok and TLB invalidate of host_addr needed.
-     *
-     * On success, *pframe contains mfn.
-     */
-
-    /*
-     * We bound the number of times we retry CMPXCHG on memory locations that
-     * we share with a guest OS. The reason is that the guest can modify that
-     * location at a higher rate than we can read-modify-CMPXCHG, so the guest
-     * could cause us to livelock. There are a few cases where it is valid for
-     * the guest to race our updates (e.g., to change the GTF_readonly flag),
-     * so we allow a few retries before failing.
-     */
-
-    act = &granting_d->grant_table->active[ref];
-    sha = &granting_d->grant_table->shared[ref];
-
-    spin_lock(&granting_d->grant_table->lock);
-
-    if ( act->pin == 0 )
-    {
-        /* CASE 1: Activating a previously inactive entry. */
-
-        sflags = sha->flags;
-        sdom   = sha->domid;
-
-        /* This loop attempts to set the access (reading/writing) flags
-         * in the grant table entry.  It tries a cmpxchg on the field
-         * up to five times, and then fails under the assumption that 
-         * the guest is misbehaving. */
-        for ( ; ; )
-        {
-            u32 scombo, prev_scombo, new_scombo;
-
-            if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) ||
-                 unlikely(sdom != mapping_d->domain_id) )
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
-                        sflags, sdom, mapping_d->domain_id);
-
-            /* Merge two 16-bit values into a 32-bit combined update. */
-            /* NB. Endianness! */
-            prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
-
-            new_scombo = scombo | GTF_reading;
-            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
-            {
-                new_scombo |= GTF_writing;
-                if ( unlikely(sflags & GTF_readonly) )
-                    PIN_FAIL(unlock_out, GNTST_general_error,
-                             "Attempt to write-pin a r/o grant entry.\n");
-            }
-
-            /* NB. prev_scombo is updated in place to seen value. */
-            if ( unlikely(cmpxchg_user((u32 *)&sha->flags,
-                                       prev_scombo,
-                                       new_scombo)) )
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Fault while modifying shared flags and domid.\n");
-
-            /* Did the combined update work (did we see what we expected?). */
-            if ( likely(prev_scombo == scombo) )
-                break;
-
-            if ( retries++ == 4 )
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Shared grant entry is unstable.\n");
-
-            /* Didn't see what we expected. Split out the seen flags & dom. */
-            /* NB. Endianness! */
-            sflags = (u16)prev_scombo;
-            sdom   = (u16)(prev_scombo >> 16);
-        }
-
-        /* rmb(); */ /* not on x86 */
-
-        frame = __gpfn_to_mfn_foreign(granting_d, sha->frame);
-
-#ifdef __ia64__
-// FIXME-ia64: any error checking need to be done here?
-#else
-        if ( unlikely(!pfn_valid(frame)) ||
-             unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
-                        get_page(&frame_table[frame], granting_d) :
-                        get_page_and_type(&frame_table[frame], granting_d,
-                                          PGT_writable_page))) )
-        {
-            clear_bit(_GTF_writing, &sha->flags);
-            clear_bit(_GTF_reading, &sha->flags);
-            PIN_FAIL(unlock_out, GNTST_general_error,
-                     "Could not pin the granted frame (%lx)!\n", frame);
-        }
-#endif 
-
-        if ( dev_hst_ro_flags & GNTMAP_device_map )
-            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
-                GNTPIN_devr_inc : GNTPIN_devw_inc;
-        if ( dev_hst_ro_flags & GNTMAP_host_map )
-            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
-                GNTPIN_hstr_inc : GNTPIN_hstw_inc;
-        act->domid = sdom;
-        act->frame = frame;
-    }
-    else 
-    {
-        /* CASE 2: Active modications to an already active entry. */
-
-        /*
-         * A cheesy check for possible pin-count overflow.
-         * A more accurate check cannot be done with a single comparison.
-         */
-        if ( (act->pin & 0x80808080U) != 0 )
-            PIN_FAIL(unlock_out, ENOSPC,
-                     "Risk of counter overflow %08x\n", act->pin);
-
-        frame = act->frame;
-
-        if ( !(dev_hst_ro_flags & GNTMAP_readonly) && 
-             !((sflags = sha->flags) & GTF_writing) )
-        {
-            for ( ; ; )
-            {
-                u16 prev_sflags;
-                
-                if ( unlikely(sflags & GTF_readonly) )
-                    PIN_FAIL(unlock_out, GNTST_general_error,
-                             "Attempt to write-pin a r/o grant entry.\n");
-
-                prev_sflags = sflags;
-
-                /* NB. prev_sflags is updated in place to seen value. */
-                if ( unlikely(cmpxchg_user(&sha->flags, prev_sflags, 
-                                           prev_sflags | GTF_writing)) )
-                    PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Fault while modifying shared flags.\n");
-
-                if ( likely(prev_sflags == sflags) )
-                    break;
-
-                if ( retries++ == 4 )
-                    PIN_FAIL(unlock_out, GNTST_general_error,
-                             "Shared grant entry is unstable.\n");
-
-                sflags = prev_sflags;
-            }
-
-#ifdef __ia64__
-// FIXME-ia64: any error checking need to be done here?
-#else
-            if ( unlikely(!get_page_type(&frame_table[frame],
-                                         PGT_writable_page)) )
-            {
-                clear_bit(_GTF_writing, &sha->flags);
-                PIN_FAIL(unlock_out, GNTST_general_error,
-                         "Attempt to write-pin a unwritable page.\n");
-            }
-#endif
-        }
-
-        if ( dev_hst_ro_flags & GNTMAP_device_map )
-            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ? 
-                GNTPIN_devr_inc : GNTPIN_devw_inc;
-
-        if ( dev_hst_ro_flags & GNTMAP_host_map )
-            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
-                GNTPIN_hstr_inc : GNTPIN_hstw_inc;
-    }
-
-    /*
-     * At this point:
-     * act->pin updated to reference count mappings.
-     * sha->flags updated to indicate to granting domain mapping done.
-     * frame contains the mfn.
-     */
-
-    spin_unlock(&granting_d->grant_table->lock);
-
-#ifdef __ia64__
-// FIXME-ia64: any error checking need to be done here?
-#else
-    if ( (addr != 0) && (dev_hst_ro_flags & GNTMAP_host_map) )
-    {
-        /* Write update into the pagetable. */
-        l1_pgentry_t pte;
-        pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS);
-        
-        if ( (dev_hst_ro_flags & GNTMAP_application_map) )
-            l1e_add_flags(pte,_PAGE_USER);
-        if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
-            l1e_add_flags(pte,_PAGE_RW);
-
-        if ( dev_hst_ro_flags & GNTMAP_contains_pte )
-            rc = update_grant_pte_mapping(addr, pte, mapping_d, mapping_ed);
-        else
-            rc = update_grant_va_mapping(addr, pte, mapping_d, mapping_ed);
-
-        /* IMPORTANT: rc indicates the degree of TLB flush that is required.
-         * GNTST_flush_one (1) or GNTST_flush_all (2). This is done in the 
-         * outer gnttab_map_grant_ref. */
-        if ( rc < 0 )
-        {
-            /* Failure: undo and abort. */
-
-            spin_lock(&granting_d->grant_table->lock);
-
-            if ( dev_hst_ro_flags & GNTMAP_readonly )
-            {
-                act->pin -= GNTPIN_hstr_inc;
-            }
-            else
-            {
-                act->pin -= GNTPIN_hstw_inc;
-                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
-                {
-                    clear_bit(_GTF_writing, &sha->flags);
-                    put_page_type(&frame_table[frame]);
-                }
-            }
-
-            if ( act->pin == 0 )
-            {
-                clear_bit(_GTF_reading, &sha->flags);
-                put_page(&frame_table[frame]);
-            }
-
-            spin_unlock(&granting_d->grant_table->lock);
-        }
-
-    }
-#endif
-
-    *pframe = frame;
-    return rc;
-
- unlock_out:
-    spin_unlock(&granting_d->grant_table->lock);
-    return rc;
-}
-
-/*
- * Returns 0 if TLB flush / invalidate required by caller.
- * va will indicate the address to be invalidated.
- * 
- * addr is _either_ a host virtual address, or the address of the pte to
- * update, as indicated by the GNTMAP_contains_pte flag.
- */
-static int
-__gnttab_map_grant_ref(
-    gnttab_map_grant_ref_t *uop,
-    unsigned long *va)
-{
-    domid_t        dom;
-    grant_ref_t    ref;
-    struct domain *ld, *rd;
-    struct vcpu   *led;
-    u16            dev_hst_ro_flags;
-    int            handle;
-    u64            addr;
-    unsigned long  frame = 0;
-    int            rc;
-
-    led = current;
-    ld = led->domain;
-
-    /* Bitwise-OR avoids short-circuiting which screws control flow. */
-    if ( unlikely(__get_user(dom, &uop->dom) |
-                  __get_user(ref, &uop->ref) |
-                  __get_user(addr, &uop->host_addr) |
-                  __get_user(dev_hst_ro_flags, &uop->flags)) )
-    {
-        DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
-        return -EFAULT; /* don't set status */
-    }
-
-    if ( (dev_hst_ro_flags & GNTMAP_host_map) &&
-         ( (addr == 0) ||
-           (!(dev_hst_ro_flags & GNTMAP_contains_pte) && 
-            unlikely(!__addr_ok(addr))) ) )
-    {
-        DPRINTK("Bad virtual address (%"PRIx64") or flags (%"PRIx16").\n",
-                addr, dev_hst_ro_flags);
-        (void)__put_user(GNTST_bad_virt_addr, &uop->handle);
-        return GNTST_bad_gntref;
-    }
-
-    if ( unlikely(ref >= NR_GRANT_ENTRIES) ||
-         unlikely((dev_hst_ro_flags &
-                   (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
-    {
-        DPRINTK("Bad ref (%d) or flags (%x).\n", ref, dev_hst_ro_flags);
-        (void)__put_user(GNTST_bad_gntref, &uop->handle);
-        return GNTST_bad_gntref;
-    }
-
-    if (acm_pre_grant_map_ref(dom)) {
-        (void)__put_user(GNTST_permission_denied, &uop->handle);
-        return GNTST_permission_denied;
-    }
-
-    if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
-         unlikely(ld == rd) )
-    {
-        if ( rd != NULL )
-            put_domain(rd);
-        DPRINTK("Could not find domain %d\n", dom);
-        (void)__put_user(GNTST_bad_domain, &uop->handle);
-        return GNTST_bad_domain;
-    }
-
-    /* Get a maptrack handle. */
-    if ( unlikely((handle = get_maptrack_handle(ld->grant_table)) == -1) )
-    {
-        int              i;
-        grant_mapping_t *new_mt;
-        grant_table_t   *lgt      = ld->grant_table;
-
-        if ( (lgt->maptrack_limit << 1) > MAPTRACK_MAX_ENTRIES )
-        {
-            put_domain(rd);
-            DPRINTK("Maptrack table is at maximum size.\n");
-            (void)__put_user(GNTST_no_device_space, &uop->handle);
-            return GNTST_no_device_space;
-        }
-
-        /* Grow the maptrack table. */
-        new_mt = alloc_xenheap_pages(lgt->maptrack_order + 1);
-        if ( new_mt == NULL )
-        {
-            put_domain(rd);
-            DPRINTK("No more map handles available.\n");
-            (void)__put_user(GNTST_no_device_space, &uop->handle);
-            return GNTST_no_device_space;
-        }
-
-        memcpy(new_mt, lgt->maptrack, PAGE_SIZE << lgt->maptrack_order);
-        for ( i = lgt->maptrack_limit; i < (lgt->maptrack_limit << 1); i++ )
-            new_mt[i].ref_and_flags = (i+1) << MAPTRACK_REF_SHIFT;
-
-        free_xenheap_pages(lgt->maptrack, lgt->maptrack_order);
-        lgt->maptrack          = new_mt;
-        lgt->maptrack_order   += 1;
-        lgt->maptrack_limit  <<= 1;
-
-        DPRINTK("Doubled maptrack size\n");
-        handle = get_maptrack_handle(ld->grant_table);
-    }
-
-#if GRANT_DEBUG_VERBOSE
-    DPRINTK("Mapping grant ref (%hu) for domain (%hu) with flags (%x)\n",
-            ref, dom, dev_hst_ro_flags);
-#endif
-
-    if ( 0 <= ( rc = __gnttab_activate_grant_ref( ld, led, rd, ref,
-                                                  dev_hst_ro_flags,
-                                                  addr, &frame)))
-    {
-        /*
-         * Only make the maptrack live _after_ writing the pte, in case we 
-         * overwrite the same frame number, causing a maptrack walk to find it
-         */
-        ld->grant_table->maptrack[handle].domid = dom;
-
-        ld->grant_table->maptrack[handle].ref_and_flags
-            = (ref << MAPTRACK_REF_SHIFT) |
-              (dev_hst_ro_flags & MAPTRACK_GNTMAP_MASK);
-
-        (void)__put_user((u64)frame << PAGE_SHIFT, &uop->dev_bus_addr);
-
-        if ( ( dev_hst_ro_flags & GNTMAP_host_map ) &&
-             !( dev_hst_ro_flags & GNTMAP_contains_pte) )
-            *va = addr;
-
-        (void)__put_user(handle, &uop->handle);
-    }
-    else
-    {
-        (void)__put_user(rc, &uop->handle);
-        put_maptrack_handle(ld->grant_table, handle);
-    }
-
-    put_domain(rd);
-    return rc;
-}
-
-static long
-gnttab_map_grant_ref(
-    gnttab_map_grant_ref_t *uop, unsigned int count)
-{
-    int i, rc, flush = 0;
-    unsigned long va = 0;
-
-    for ( i = 0; i < count; i++ )
-        if ( (rc =__gnttab_map_grant_ref(&uop[i], &va)) >= 0 )
-            flush += rc;
-
-#ifdef __ia64__
-// FIXME-ia64: probably need to do something here to avoid stale mappings?
-#else
-    if ( flush == 1 )
-        flush_tlb_one_mask(current->domain->cpumask, va);
-    else if ( flush != 0 ) 
-        flush_tlb_mask(current->domain->cpumask);
-#endif
-
-    return 0;
-}
-
-static int
-__gnttab_unmap_grant_ref(
-    gnttab_unmap_grant_ref_t *uop,
-    unsigned long *va)
-{
-    domid_t          dom;
-    grant_ref_t      ref;
-    u16              handle;
-    struct domain   *ld, *rd;
-    active_grant_entry_t *act;
-    grant_entry_t   *sha;
-    grant_mapping_t *map;
-    u16              flags;
-    s16              rc = 1;
-    u64              addr, dev_bus_addr;
-    unsigned long    frame;
-
-    ld = current->domain;
-
-    /* Bitwise-OR avoids short-circuiting which screws control flow. */
-    if ( unlikely(__get_user(addr, &uop->host_addr) |
-                  __get_user(dev_bus_addr, &uop->dev_bus_addr) |
-                  __get_user(handle, &uop->handle)) )
-    {
-        DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n");
-        return -EFAULT; /* don't set status */
-    }
-
-    frame = (unsigned long)(dev_bus_addr >> PAGE_SHIFT);
-
-    map = &ld->grant_table->maptrack[handle];
-
-    if ( unlikely(handle >= ld->grant_table->maptrack_limit) ||
-         unlikely(!(map->ref_and_flags & MAPTRACK_GNTMAP_MASK)) )
-    {
-        DPRINTK("Bad handle (%d).\n", handle);
-        (void)__put_user(GNTST_bad_handle, &uop->status);
-        return GNTST_bad_handle;
-    }
-
-    dom   = map->domid;
-    ref   = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
-    flags = map->ref_and_flags & MAPTRACK_GNTMAP_MASK;
-
-    if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
-         unlikely(ld == rd) )
-    {
-        if ( rd != NULL )
-            put_domain(rd);
-        DPRINTK("Could not find domain %d\n", dom);
-        (void)__put_user(GNTST_bad_domain, &uop->status);
-        return GNTST_bad_domain;
-    }
-
-#if GRANT_DEBUG_VERBOSE
-    DPRINTK("Unmapping grant ref (%hu) for domain (%hu) with handle (%hu)\n",
-            ref, dom, handle);
-#endif
-
-    act = &rd->grant_table->active[ref];
-    sha = &rd->grant_table->shared[ref];
-
-    spin_lock(&rd->grant_table->lock);
-
-    if ( frame == 0 )
-    {
-        frame = act->frame;
-    }
-    else
-    {
-        if ( unlikely(frame != act->frame) )
-            PIN_FAIL(unmap_out, GNTST_general_error,
-                     "Bad frame number doesn't match gntref.\n");
-        if ( flags & GNTMAP_device_map )
-            act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_devr_inc
-                                                  : GNTPIN_devw_inc;
-
-        map->ref_and_flags &= ~GNTMAP_device_map;
-        (void)__put_user(0, &uop->dev_bus_addr);
-
-        /* Frame is now unmapped for device access. */
-    }
-
-    if ( (addr != 0) &&
-         (flags & GNTMAP_host_map) &&
-         ((act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) > 0))
-    {
-#ifdef __ia64__
-// FIXME-ia64: any error checking need to be done here?
-#else
-        if ( flags & GNTMAP_contains_pte )
-        {
-            if ( (rc = clear_grant_pte_mapping(addr, frame, ld)) < 0 )
-                goto unmap_out;
-        }
-        else
-        {
-            if ( (rc = clear_grant_va_mapping(addr, frame)) < 0 )
-                goto unmap_out;
-        }
-#endif
-
-        map->ref_and_flags &= ~GNTMAP_host_map;
-
-        act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_hstr_inc
-                                              : GNTPIN_hstw_inc;
-
-        rc = 0;
-        if ( !( flags & GNTMAP_contains_pte) )
-            *va = addr;
-    }
-
-    if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0)
-    {
-        map->ref_and_flags = 0;
-        put_maptrack_handle(ld->grant_table, handle);
-    }
-
-#ifdef __ia64__
-// FIXME-ia64: any error checking need to be done here?  I think not and then
-//  this can probably be macro-ized into nothingness
-#else
-    /* If just unmapped a writable mapping, mark as dirtied */
-    if ( unlikely(shadow_mode_log_dirty(rd)) &&
-        !( flags & GNTMAP_readonly ) )
-         mark_dirty(rd, frame);
-#endif
-
-    /* If the last writable mapping has been removed, put_page_type */
-    if ( ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask) ) == 0) &&
-         ( !( flags & GNTMAP_readonly ) ) )
-    {
-        clear_bit(_GTF_writing, &sha->flags);
-        put_page_type(&frame_table[frame]);
-    }
-
-    if ( act->pin == 0 )
-    {
-        act->frame = 0xdeadbeef;
-        clear_bit(_GTF_reading, &sha->flags);
-        put_page(&frame_table[frame]);
-    }
-
- unmap_out:
-    (void)__put_user(rc, &uop->status);
-    spin_unlock(&rd->grant_table->lock);
-    put_domain(rd);
-    return rc;
-}
-
-static long
-gnttab_unmap_grant_ref(
-    gnttab_unmap_grant_ref_t *uop, unsigned int count)
-{
-    int i, flush = 0;
-    unsigned long va = 0;
-
-    for ( i = 0; i < count; i++ )
-        if ( __gnttab_unmap_grant_ref(&uop[i], &va) == 0 )
-            flush++;
-
-#ifdef __ia64__
-// FIXME-ia64: probably need to do something here to avoid stale mappings?
-#else
-    if ( flush == 1 )
-        flush_tlb_one_mask(current->domain->cpumask, va);
-    else if ( flush != 0 ) 
-        flush_tlb_mask(current->domain->cpumask);
-#endif
-
-    return 0;
-}
-
-static long 
-gnttab_setup_table(
-    gnttab_setup_table_t *uop, unsigned int count)
-{
-    gnttab_setup_table_t  op;
-    struct domain        *d;
-    int                   i;
-
-    if ( count != 1 )
-        return -EINVAL;
-
-    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
-    {
-        DPRINTK("Fault while reading gnttab_setup_table_t.\n");
-        return -EFAULT;
-    }
-
-    if ( unlikely(op.nr_frames > NR_GRANT_FRAMES) )
-    {
-        DPRINTK("Xen only supports up to %d grant-table frames per domain.\n",
-                NR_GRANT_FRAMES);
-        (void)put_user(GNTST_general_error, &uop->status);
-        return 0;
-    }
-
-    if ( op.dom == DOMID_SELF )
-    {
-        op.dom = current->domain->domain_id;
-    }
-    else if ( unlikely(!IS_PRIV(current->domain)) )
-    {
-        (void)put_user(GNTST_permission_denied, &uop->status);
-        return 0;
-    }
-
-    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
-    {
-        DPRINTK("Bad domid %d.\n", op.dom);
-        (void)put_user(GNTST_bad_domain, &uop->status);
-        return 0;
-    }
-
-    if ( op.nr_frames <= NR_GRANT_FRAMES )
-    {
-        ASSERT(d->grant_table != NULL);
-        (void)put_user(GNTST_okay, &uop->status);
-#ifdef __ia64__
-       if (d == dom0) {
-            for ( i = 0; i < op.nr_frames; i++ )
-                (void)put_user(
-                    (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
-                    &uop->frame_list[i]);
-       } else {
-            /* IA64 hack - need to map it somewhere */
-            unsigned long addr = (1UL << 40);
-            map_domain_page(d, addr, virt_to_phys(d->grant_table->shared));
-            (void)put_user(addr >> PAGE_SHIFT, &uop->frame_list[0]);
-        }
-#else
-        for ( i = 0; i < op.nr_frames; i++ )
-            (void)put_user(
-                (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
-                &uop->frame_list[i]);
-#endif
-    }
-
-    put_domain(d);
-    return 0;
-}
-
-#if GRANT_DEBUG
-static int
-gnttab_dump_table(gnttab_dump_table_t *uop)
-{
-    grant_table_t        *gt;
-    gnttab_dump_table_t   op;
-    struct domain        *d;
-    u32                   shared_mfn;
-    active_grant_entry_t *act;
-    grant_entry_t         sha_copy;
-    grant_mapping_t      *maptrack;
-    int                   i;
-
-
-    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
-    {
-        DPRINTK("Fault while reading gnttab_dump_table_t.\n");
-        return -EFAULT;
-    }
-
-    if ( op.dom == DOMID_SELF )
-    {
-        op.dom = current->domain->domain_id;
-    }
-
-    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
-    {
-        DPRINTK("Bad domid %d.\n", op.dom);
-        (void)put_user(GNTST_bad_domain, &uop->status);
-        return 0;
-    }
-
-    ASSERT(d->grant_table != NULL);
-    gt = d->grant_table;
-    (void)put_user(GNTST_okay, &uop->status);
-
-    shared_mfn = virt_to_phys(d->grant_table->shared);
-
-    DPRINTK("Grant table for dom (%hu) MFN (%x)\n",
-            op.dom, shared_mfn);
-
-    ASSERT(d->grant_table->active != NULL);
-    ASSERT(d->grant_table->shared != NULL);
-    ASSERT(d->grant_table->maptrack != NULL);
-
-    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
-    {
-        sha_copy =  gt->shared[i];
-
-        if ( sha_copy.flags )
-        {
-            DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) "
-                    "dom:(%hu) frame:(%x)\n",
-                    op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
-        }
-    }
-
-    spin_lock(&gt->lock);
-
-    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
-    {
-        act = &gt->active[i];
-
-        if ( act->pin )
-        {
-            DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) "
-                    "dom:(%hu) frame:(%lx)\n",
-                    op.dom, i, act->pin, act->domid, act->frame);
-        }
-    }
-
-    for ( i = 0; i < gt->maptrack_limit; i++ )
-    {
-        maptrack = &gt->maptrack[i];
-
-        if ( maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK )
-        {
-            DPRINTK("Grant: dom (%hu) MAP (%d) ref:(%hu) flags:(%x) "
-                    "dom:(%hu)\n",
-                    op.dom, i,
-                    maptrack->ref_and_flags >> MAPTRACK_REF_SHIFT,
-                    maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK,
-                    maptrack->domid);
-        }
-    }
-
-    spin_unlock(&gt->lock);
-
-    put_domain(d);
-    return 0;
-}
-#endif
-
-static long
-gnttab_transfer(gnttab_transfer_t *uop, unsigned int count)
-{
-    struct domain *d = current->domain;
-    struct domain *e;
-    struct pfn_info *page;
-    u32 _d, _nd, x, y;
-    int i;
-    int result = GNTST_okay;
-
-#ifdef __ia64__
-//FIXME-IA64: not support for now?
-    return GNTST_general_error;
-#else
-    for (i = 0; i < count; i++) {
-        gnttab_transfer_t *gop = &uop[i];
-#if GRANT_DEBUG
-        printk("gnttab_transfer: i=%d mfn=%lx domid=%d gref=%08x\n",
-               i, gop->mfn, gop->domid, gop->handle);
-#endif
-        page = &frame_table[gop->mfn];
-        
-        if (unlikely(IS_XEN_HEAP_FRAME(page))) { 
-            printk("gnttab_transfer: xen heap frame mfn=%lx\n", 
-                   (unsigned long) gop->mfn);
-            gop->status = GNTST_bad_virt_addr;
-            continue;
-        }
-        if (unlikely(!pfn_valid(page_to_pfn(page)))) {
-            printk("gnttab_transfer: invalid pfn for mfn=%lx\n", 
-                   (unsigned long) gop->mfn);
-            gop->status = GNTST_bad_virt_addr;
-            continue;
-        }
-        if (unlikely((e = find_domain_by_id(gop->domid)) == NULL)) {
-            printk("gnttab_transfer: can't find domain %d\n", gop->domid);
-            gop->status = GNTST_bad_domain;
-            continue;
-        }
-
-        spin_lock(&d->page_alloc_lock);
-
-        /*
-         * The tricky bit: atomically release ownership while
-         * there is just one benign reference to the page
-         * (PGC_allocated). If that reference disappears then the
-         * deallocation routine will safely spin.
-         */
-        _d  = pickle_domptr(d);
-        _nd = page->u.inuse._domain;
-        y   = page->count_info;
-        do {
-            x = y;
-            if (unlikely((x & (PGC_count_mask|PGC_allocated)) !=
-                         (1 | PGC_allocated)) || unlikely(_nd != _d)) {
-                printk("gnttab_transfer: Bad page values %p: ed=%p(%u), sd=%p,"
-                       " caf=%08x, taf=%" PRtype_info "\n", 
-                       (void *) page_to_pfn(page),
-                        d, d->domain_id, unpickle_domptr(_nd), x, 
-                        page->u.inuse.type_info);
-                spin_unlock(&d->page_alloc_lock);
-                put_domain(e);
-                return 0;
-            }
-            __asm__ __volatile__(
-                LOCK_PREFIX "cmpxchg8b %2"
-                : "=d" (_nd), "=a" (y),
-                "=m" (*(volatile u64 *)(&page->count_info))
-                : "0" (_d), "1" (x), "c" (NULL), "b" (x) );
-        } while (unlikely(_nd != _d) || unlikely(y != x));
-
-        /*
-         * Unlink from 'd'. At least one reference remains (now
-         * anonymous), so noone else is spinning to try to delete
-         * this page from 'd'.
-         */
-        d->tot_pages--;
-        list_del(&page->list);
-
-        spin_unlock(&d->page_alloc_lock);
-
-        spin_lock(&e->page_alloc_lock);
-
-        /*
-         * Check that 'e' will accept the page and has reservation
-         * headroom.  Also, a domain mustn't have PGC_allocated
-         * pages when it is dying.
-         */
-#ifdef GRANT_DEBUG
-        if (unlikely(e->tot_pages >= e->max_pages)) {
-            printk("gnttab_dontate: no headroom tot_pages=%d max_pages=%d\n",
-                   e->tot_pages, e->max_pages);
-            spin_unlock(&e->page_alloc_lock);
-            put_domain(e);
-            result = GNTST_general_error;
-            break;
-        }
-        if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags))) {
-            printk("gnttab_transfer: target domain is dying\n");
-            spin_unlock(&e->page_alloc_lock);
-            put_domain(e);
-            result = GNTST_general_error;
-            break;
-        }
-        if (unlikely(!gnttab_prepare_for_transfer(e, d, gop->ref))) {
-            printk("gnttab_transfer: gnttab_prepare_for_transfer fails\n");
-            spin_unlock(&e->page_alloc_lock);
-            put_domain(e);
-            result = GNTST_general_error;
-            break;
-        }
-#else
-        ASSERT(e->tot_pages <= e->max_pages);
-        if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags)) ||
-            unlikely(e->tot_pages == e->max_pages) ||
-            unlikely(!gnttab_prepare_for_transfer(e, d, gop->ref))) {
-            printk("gnttab_transfer: Transferee has no reservation headroom 
(%d,"
-                   "%d) or provided a bad grant ref (%08x) or is dying (%p)\n",
-                   e->tot_pages, e->max_pages, gop->ref, e->d_flags);
-            spin_unlock(&e->page_alloc_lock);
-            put_domain(e);
-            result = GNTST_general_error;
-            break;
-        }
-#endif
-        /* Okay, add the page to 'e'. */
-        if (unlikely(e->tot_pages++ == 0)) {
-            get_knownalive_domain(e);
-        }
-        list_add_tail(&page->list, &e->page_list);
-        page_set_owner(page, e);
-        
-        spin_unlock(&e->page_alloc_lock);
-        
-        /*
-         * Transfer is all done: tell the guest about its new page
-         * frame.
-         */
-        gnttab_notify_transfer(e, d, gop->ref, gop->mfn);
-        
-        put_domain(e);
-        
-        gop->status = GNTST_okay;
-    }
-    return result;
-#endif
-}
-
-long 
-do_grant_table_op(
-    unsigned int cmd, void *uop, unsigned int count)
-{
-    long rc;
-    struct domain *d = current->domain;
-    
-    if ( count > 512 )
-        return -EINVAL;
-    
-    LOCK_BIGLOCK(d);
-    
-#ifndef __ia64__
-    sync_pagetable_state(d);
-#endif
-    
-    rc = -EFAULT;
-    switch ( cmd )
-        {
-        case GNTTABOP_map_grant_ref:
-            if ( unlikely(!array_access_ok(
-                              uop, count, sizeof(gnttab_map_grant_ref_t))) )
-                goto out;
-            rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count);
-            break;
-        case GNTTABOP_unmap_grant_ref:
-            if ( unlikely(!array_access_ok(
-                              uop, count, sizeof(gnttab_unmap_grant_ref_t))) )
-                goto out;
-            rc = gnttab_unmap_grant_ref((gnttab_unmap_grant_ref_t *)uop, 
-                                        count);
-            break;
-        case GNTTABOP_setup_table:
-            rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count);
-            break;
-#if GRANT_DEBUG
-        case GNTTABOP_dump_table:
-            rc = gnttab_dump_table((gnttab_dump_table_t *)uop);
-            break;
-#endif
-        case GNTTABOP_transfer:
-            if (unlikely(!array_access_ok(uop, count, 
-                                          sizeof(gnttab_transfer_t))))
-                goto out;
-            rc = gnttab_transfer(uop, count);
-            break;
-        default:
-            rc = -ENOSYS;
-            break;
-        }
-    
-  out:
-    UNLOCK_BIGLOCK(d);
-    
-    return rc;
-}
-
-int
-gnttab_check_unmap(
-    struct domain *rd, struct domain *ld, unsigned long frame, int readonly)
-{
-    /* Called when put_page is invoked on a page belonging to a foreign domain.
-     * Instead of decrementing the frame table ref count, locate the grant
-     * table entry, if any, and if found, decrement that count.
-     * Called a _lot_ at domain creation because pages mapped by priv domains
-     * also traverse this.
-     */
-    
-    /* Note: If the same frame is mapped multiple times, and then one of
-     *       the ptes is overwritten, which maptrack handle gets invalidated?
-     * Advice: Don't do it. Explicitly unmap.
-     */
-    
-    unsigned int handle, ref, refcount;
-    grant_table_t        *lgt, *rgt;
-    active_grant_entry_t *act;
-    grant_mapping_t      *map;
-    int found = 0;
-    
-    lgt = ld->grant_table;
-    
-#if GRANT_DEBUG_VERBOSE
-    if ( ld->domain_ id != 0 ) {
-            DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
-                    rd->domain_id, ld->domain_id, frame, readonly);
-      }
-#endif
-    
-    /* Fast exit if we're not mapping anything using grant tables */
-    if ( lgt->map_count == 0 )
-        return 0;
-    
-    if ( get_domain(rd) == 0 ) {
-        DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n",
-                rd->domain_id);
-        return 0;
-    }
-    
-    rgt = rd->grant_table;
-    
-    for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) {
-
-        map = &lgt->maptrack[handle];
-            
-        if ( map->domid != rd->domain_id )
-            continue;
-        
-        if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
-             ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) {
-
-            ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT);
-            act = &rgt->active[ref];
-                    
-            spin_lock(&rgt->lock);
-                    
-            if ( act->frame != frame ) {
-                spin_unlock(&rgt->lock);
-                continue;
-            }
-                    
-            refcount = act->pin & ( readonly ? GNTPIN_hstr_mask
-                                    : GNTPIN_hstw_mask );
-
-            if ( refcount == 0 ) {
-                spin_unlock(&rgt->lock);
-                continue;
-            }
-                    
-            /* gotcha */
-            DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
-                    rd->domain_id, ld->domain_id, frame, readonly);
-                    
-            if ( readonly )
-                act->pin -= GNTPIN_hstr_inc;
-            else {
-                act->pin -= GNTPIN_hstw_inc;
-                            
-                /* any more granted writable mappings? */
-                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) {
-                    clear_bit(_GTF_writing, &rgt->shared[ref].flags);
-                    put_page_type(&frame_table[frame]);
-                }
-            }
-                
-            if ( act->pin == 0 ) {
-                clear_bit(_GTF_reading, &rgt->shared[ref].flags);
-                put_page(&frame_table[frame]);
-            }
-
-            spin_unlock(&rgt->lock);
-                    
-            clear_bit(GNTMAP_host_map, &map->ref_and_flags);
-                    
-            if ( !(map->ref_and_flags & GNTMAP_device_map) )
-                put_maptrack_handle(lgt, handle);
-                    
-            found = 1;
-            break;
-        }
-    }
-    put_domain(rd);
-    
-    return found;
-}
-
-int 
-gnttab_prepare_for_transfer(
-    struct domain *rd, struct domain *ld, grant_ref_t ref)
-{
-    grant_table_t *rgt;
-    grant_entry_t *sha;
-    domid_t        sdom;
-    u16            sflags;
-    u32            scombo, prev_scombo;
-    int            retries = 0;
-    unsigned long  target_pfn;
-
-#if GRANT_DEBUG_VERBOSE
-    DPRINTK("gnttab_prepare_for_transfer rd(%hu) ld(%hu) ref(%hu).\n",
-            rd->domain_id, ld->domain_id, ref);
-#endif
-
-    if ( unlikely((rgt = rd->grant_table) == NULL) ||
-         unlikely(ref >= NR_GRANT_ENTRIES) )
-    {
-        DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
-                rd->domain_id, ref);
-        return 0;
-    }
-
-    spin_lock(&rgt->lock);
-
-    sha = &rgt->shared[ref];
-    
-    sflags = sha->flags;
-    sdom   = sha->domid;
-
-    for ( ; ; )
-    {
-        target_pfn = sha->frame;
-
-        if ( unlikely(target_pfn >= max_page ) )
-        {
-            DPRINTK("Bad pfn (%lx)\n", target_pfn);
-            goto fail;
-        }
-
-        if ( unlikely(sflags != GTF_accept_transfer) ||
-             unlikely(sdom != ld->domain_id) )
-        {
-            DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
-                    sflags, sdom, ld->domain_id);
-            goto fail;
-        }
-
-        /* Merge two 16-bit values into a 32-bit combined update. */
-        /* NB. Endianness! */
-        prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
-
-        /* NB. prev_scombo is updated in place to seen value. */
-        if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, 
-                                   prev_scombo | GTF_transfer_committed)) )
-        {
-            DPRINTK("Fault while modifying shared flags and domid.\n");
-            goto fail;
-        }
-
-        /* Did the combined update work (did we see what we expected?). */
-        if ( likely(prev_scombo == scombo) )
-            break;
-
-        if ( retries++ == 4 )
-        {
-            DPRINTK("Shared grant entry is unstable.\n");
-            goto fail;
-        }
-
-        /* Didn't see what we expected. Split out the seen flags & dom. */
-        /* NB. Endianness! */
-        sflags = (u16)prev_scombo;
-        sdom   = (u16)(prev_scombo >> 16);
-    }
-
-    spin_unlock(&rgt->lock);
-    return 1;
-
- fail:
-    spin_unlock(&rgt->lock);
-    return 0;
-}
-
-void 
-gnttab_notify_transfer(
-    struct domain *rd, struct domain *ld, grant_ref_t ref, unsigned long frame)
-{
-    grant_entry_t  *sha;
-    unsigned long   pfn;
-
-#if GRANT_DEBUG_VERBOSE
-    DPRINTK("gnttab_notify_transfer rd(%hu) ld(%hu) ref(%hu).\n",
-            rd->domain_id, ld->domain_id, ref);
-#endif
-
-    sha = &rd->grant_table->shared[ref];
-
-    spin_lock(&rd->grant_table->lock);
-
-#ifdef __ia64__
-// FIXME-ia64: any error checking need to be done here?
-#else
-    pfn = sha->frame;
-
-    if ( unlikely(pfn >= max_page ) )
-        DPRINTK("Bad pfn (%lx)\n", pfn);
-    else
-    {
-        machine_to_phys_mapping[frame] = pfn;
-
-        if ( unlikely(shadow_mode_log_dirty(ld)))
-             mark_dirty(ld, frame);
-
-        if (shadow_mode_translate(ld))
-            __phys_to_machine_mapping[pfn] = frame;
-    }
-#endif
-    sha->frame = __mfn_to_gpfn(rd, frame);
-    sha->domid = rd->domain_id;
-    wmb();
-    sha->flags = ( GTF_accept_transfer | GTF_transfer_completed );
-
-    spin_unlock(&rd->grant_table->lock);
-
-    return;
-}
-
-int 
-grant_table_create(
-    struct domain *d)
-{
-    grant_table_t *t;
-    int            i;
-
-    if ( (t = xmalloc(grant_table_t)) == NULL )
-        goto no_mem;
-
-    /* Simple stuff. */
-    memset(t, 0, sizeof(*t));
-    spin_lock_init(&t->lock);
-
-    /* Active grant table. */
-    if ( (t->active = xmalloc_array(active_grant_entry_t, NR_GRANT_ENTRIES))
-         == NULL )
-        goto no_mem;
-    memset(t->active, 0, sizeof(active_grant_entry_t) * NR_GRANT_ENTRIES);
-
-    /* Tracking of mapped foreign frames table */
-    if ( (t->maptrack = alloc_xenheap_page()) == NULL )
-        goto no_mem;
-    t->maptrack_order = 0;
-    t->maptrack_limit = PAGE_SIZE / sizeof(grant_mapping_t);
-    memset(t->maptrack, 0, PAGE_SIZE);
-    for ( i = 0; i < t->maptrack_limit; i++ )
-        t->maptrack[i].ref_and_flags = (i+1) << MAPTRACK_REF_SHIFT;
-
-    /* Shared grant table. */
-    t->shared = alloc_xenheap_pages(ORDER_GRANT_FRAMES);
-    if ( t->shared == NULL )
-        goto no_mem;
-    memset(t->shared, 0, NR_GRANT_FRAMES * PAGE_SIZE);
-
-#ifdef __ia64__
-// I don't think there's anything to do here on ia64?...
-#else
-    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
-    {
-        SHARE_PFN_WITH_DOMAIN(
-            virt_to_page((char *)(t->shared)+(i*PAGE_SIZE)), d);
-        machine_to_phys_mapping[(virt_to_phys(t->shared) >> PAGE_SHIFT) + i] =
-            INVALID_M2P_ENTRY;
-    }
-#endif
-
-    /* Okay, install the structure. */
-    wmb(); /* avoid races with lock-free access to d->grant_table */
-    d->grant_table = t;
-    return 0;
-
- no_mem:
-    if ( t != NULL )
-    {
-        xfree(t->active);
-        free_xenheap_page(t->maptrack);
-        xfree(t);
-    }
-    return -ENOMEM;
-}
-
-void
-gnttab_release_dev_mappings(grant_table_t *gt)
-{
-    grant_mapping_t        *map;
-    domid_t                 dom;
-    grant_ref_t             ref;
-    u16                     handle;
-    struct domain          *ld, *rd;
-    unsigned long           frame;
-    active_grant_entry_t   *act;
-    grant_entry_t          *sha;
-
-    ld = current->domain;
-
-    for ( handle = 0; handle < gt->maptrack_limit; handle++ )
-    {
-        map = &gt->maptrack[handle];
-
-        if ( map->ref_and_flags & GNTMAP_device_map )
-        {
-            dom = map->domid;
-            ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
-
-            DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
-                    handle, ref,
-                    map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
-
-            if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
-                 unlikely(ld == rd) )
-            {
-                if ( rd != NULL )
-                    put_domain(rd);
-
-                printk(KERN_WARNING "Grant release: No dom%d\n", dom);
-                continue;
-            }
-
-            act = &rd->grant_table->active[ref];
-            sha = &rd->grant_table->shared[ref];
-
-            spin_lock(&rd->grant_table->lock);
-
-            if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) )
-            {
-                frame = act->frame;
-
-                if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) &&
-                     ( (act->pin & GNTPIN_devw_mask) >  0 ) )
-                {
-                    clear_bit(_GTF_writing, &sha->flags);
-                    put_page_type(&frame_table[frame]);
-                }
-
-                act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask);
-
-                if ( act->pin == 0 )
-                {
-                    clear_bit(_GTF_reading, &sha->flags);
-                    map->ref_and_flags = 0;
-                    put_page(&frame_table[frame]);
-                }
-                else
-                    map->ref_and_flags &= ~GNTMAP_device_map;
-            }
-
-            spin_unlock(&rd->grant_table->lock);
-
-            put_domain(rd);
-        }
-    }
-}
-
-
-void
-grant_table_destroy(
-    struct domain *d)
-{
-    grant_table_t *t;
-
-    if ( (t = d->grant_table) != NULL )
-    {
-        /* Free memory relating to this grant table. */
-        d->grant_table = NULL;
-        free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
-        free_xenheap_page(t->maptrack);
-        xfree(t->active);
-        xfree(t);
-    }
-}
-
-void
-grant_table_init(
-    void)
-{
-    /* Nothing. */
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/asm-x86/vmx_virpit.h
--- a/xen/include/asm-x86/vmx_virpit.h  Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,55 +0,0 @@
-#ifndef _VMX_VIRPIT_H
-#define _VMX_VIRPIT_H
-
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/lib.h>
-#include <xen/time.h>
-#include <xen/errno.h>
-#include <xen/ac_timer.h>
-#include <asm/vmx_vmcs.h>
-#include <public/io/vmx_vpic.h>
-
-#define PIT_FREQ 1193181
-
-#define LSByte 0
-#define MSByte 1
-#define LSByte_multiple 2
-#define MSByte_multiple 3
-
-struct vmx_virpit {
-    /* for simulation of counter 0 in mode 2*/
-    u64 period_cycles;                 /* pit frequency in cpu cycles */
-    u64 inject_point; /* the time inject virt intr */
-    s_time_t scheduled;                 /* scheduled timer interrupt */
-    struct ac_timer pit_timer;  /* periodic timer for mode 2*/
-    unsigned int channel;  /* the pit channel, counter 0~2 */
-    unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
-    u32 period;                /* pit frequency in ns */
-    int first_injected;                 /* flag to prevent shadow window */
-    int ticking;    /* indicating it is ticking */
-
-    /* virtual PIT state for handle related I/O */
-    int read_state;
-    int count_LSB_latched;
-    int count_MSB_latched;
-
-    unsigned int count;  /* the 16 bit channel count */
-    unsigned int init_val; /* the init value for the counter */
-};
-
-/* to hook the ioreq packet to get the PIT initializaiton info */
-extern void vmx_hooks_assist(struct vcpu *v);
-
-static __inline__ s_time_t get_pit_scheduled(
-    struct vcpu *v, 
-    struct vmx_virpit *vpit)
-{
-    if ( is_irq_enabled(v, 0) ) {
-        return vpit->scheduled;
-    }
-    else
-        return -1;
-}
-
-#endif /* _VMX_VIRPIT_H_ */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/io/vmx_vlapic.h
--- a/xen/include/public/io/vmx_vlapic.h        Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,58 +0,0 @@
-#ifndef _VMX_VLAPIC_H
-#define _VMX_VLAPIC_H
-
-/*
-   We extended one bit for PIC type
- */
-#define VLAPIC_DELIV_MODE_FIXED          0x0
-#define VLAPIC_DELIV_MODE_LPRI           0x1
-#define VLAPIC_DELIV_MODE_SMI            0x2
-#define VLAPIC_DELIV_MODE_NMI            0x4
-#define VLAPIC_DELIV_MODE_INIT           0x5
-#define VLAPIC_DELIV_MODE_STARTUP        0x6
-#define VLAPIC_DELIV_MODE_EXT            0x7
-#define VLAPIC_DELIV_MODE_MASK            0x8
-
-#define VLAPIC_MSG_LEVEL                4
-
-#define INTR_EXT   0
-#define INTR_APIC   1
-#define INTR_LAPIC  2
-
-#define VL_STATE_EOI    1
-#define VL_STATE_EXT_LOCK   2
-#define VL_STATE_MSG_LOCK   3
-#define VL_STATE_EOI_LOCK   3
-
-#define VLOCAL_APIC_MAX_INTS             256
-#define VLAPIC_INT_COUNT                (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * 
sizeof(uint64_t)))
-#define VLAPIC_INT_COUNT_32             (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * 
sizeof(uint32_t)))
-
-typedef struct {
-    /* interrupt for PIC and ext type IOAPIC interrupt */
-    uint64_t   vl_ext_intr[VLAPIC_INT_COUNT];
-    uint64_t   vl_ext_intr_mask[VLAPIC_INT_COUNT];
-    uint64_t   vl_apic_intr[VLAPIC_INT_COUNT];
-    uint64_t   vl_apic_tmr[VLAPIC_INT_COUNT];
-    uint64_t   vl_eoi[VLAPIC_INT_COUNT];
-    uint32_t   vl_lapic_id;
-    uint32_t   direct_intr;
-    uint32_t   vl_apr;
-    uint32_t   vl_logical_dest;
-    uint32_t   vl_dest_format;
-    uint32_t   vl_arb_id;
-    uint32_t   vl_state;
-    uint32_t   apic_msg_count;
-} vlapic_info;
-
-#endif /* _VMX_VLAPIC_H_ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r eae5812f33f1 -r 28bd01c9b596 xen/include/public/io/vmx_vpic.h
--- a/xen/include/public/io/vmx_vpic.h  Fri Dec  2 18:12:11 2005
+++ /dev/null   Fri Dec  2 18:52:25 2005
@@ -1,85 +0,0 @@
-/*
- * QEMU System Emulator header
- * 
- * Copyright (c) 2003 Fabrice Bellard
- * Copyright (c) 2005 Intel Corp
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef _VMX_VPIC_H
-#define _VMX_VPIC_H
-
-#define hw_error(x)  do {} while (0);
-
-
-/* i8259.c */
-typedef struct IOAPICState IOAPICState;
-typedef struct PicState {
-    uint8_t last_irr; /* edge detection */
-    uint8_t irr; /* interrupt request register */
-    uint8_t imr; /* interrupt mask register */
-    uint8_t isr; /* interrupt service register */
-    uint8_t priority_add; /* highest irq priority */
-    uint8_t irq_base;
-    uint8_t read_reg_select;
-    uint8_t poll;
-    uint8_t special_mask;
-    uint8_t init_state;
-    uint8_t auto_eoi;
-    uint8_t rotate_on_auto_eoi;
-    uint8_t special_fully_nested_mode;
-    uint8_t init4; /* true if 4 byte init */
-    uint8_t elcr; /* PIIX edge/trigger selection*/
-    uint8_t elcr_mask;
-    struct vmx_virpic *pics_state;
-} PicState;
-
-struct vmx_virpic {
-    /* 0 is master pic, 1 is slave pic */
-    /* XXX: better separation between the two pics */
-    PicState pics[2];
-    void (*irq_request)(int *opaque, int level);
-    void *irq_request_opaque;
-    /* IOAPIC callback support */
-    void (*alt_irq_func)(void *opaque, int irq_num, int level);
-    void *alt_irq_opaque;
-};
-
-
-void pic_set_irq(struct vmx_virpic *s, int irq, int level);
-void pic_set_irq_new(void *opaque, int irq, int level);
-void pic_init(struct vmx_virpic *s, 
-              void (*irq_request)(),
-              void *irq_request_opaque);
-void pic_set_alt_irq_func(struct vmx_virpic *s, 
-                          void(*alt_irq_func)(),
-                          void *alt_irq_opaque);
-int pic_read_irq(struct vmx_virpic *s);
-void pic_update_irq(struct vmx_virpic *s);
-uint32_t pic_intack_read(struct vmx_virpic *s);
-void register_pic_io_hook (void);
-int cpu_get_pic_interrupt(struct vcpu *v, int *type);
-int is_pit_irq(struct vcpu *v, int irq, int type);
-int is_irq_enabled(struct vcpu *v, int irq);
-void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs);
-void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs);
-
-/* APIC */
-#endif  /* _VMX_VPIC_H */  

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

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