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

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg (staging)



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1193780084 21600
# Node ID a07288a8478521002c2302ad18fac52eb6600055
# Parent  c17bfb09179095567c0cdae0aef3177afd6fad53
# Parent  7eb68d995aa7b3527721376b6112b995ef539168
merge with xen-unstable.hg (staging)
---
 buildconfigs/mk.linux-2.6-paravirt                                |   15 
 tools/check/check_libvncserver                                    |   38 
 tools/check/check_sdl                                             |   27 
 tools/xenfb/Makefile                                              |   32 
 tools/xenfb/sdlfb.c                                               |  342 --
 tools/xenfb/vncfb.c                                               |  522 ----
 tools/xenfb/xenfb.c                                               |  779 ------
 tools/xenfb/xenfb.h                                               |   35 
 Config.mk                                                         |    1 
 Makefile                                                          |   42 
 README                                                            |   54 
 buildconfigs/mk.linux-2.6                                         |    6 
 buildconfigs/mk.linux-2.6-common                                  |  158 +
 buildconfigs/mk.linux-2.6-native                                  |    4 
 buildconfigs/mk.linux-2.6-xen                                     |  161 -
 buildconfigs/mk.linux-2.6.5-SLES-xen                              |    2 
 buildconfigs/mk.linux-2.6.9-RHEL-xen                              |    2 
 buildconfigs/src.tarball                                          |   14 
 docs/misc/vtd.txt                                                 |   50 
 tools/Makefile                                                    |    1 
 tools/check/Makefile                                              |    4 
 tools/console/daemon/io.c                                         |  142 +
 tools/examples/xend-config.sxp                                    |   33 
 tools/firmware/hvmloader/acpi/build.c                             |    2 
 tools/firmware/rombios/32bit/tcgbios/tcgbios.c                    |    2 
 tools/firmware/vgabios/clext.c                                    |   26 
 tools/firmware/vmxassist/machine.h                                |    5 
 tools/firmware/vmxassist/vm86.c                                   |  267 ++
 tools/ioemu/Makefile.target                                       |   17 
 tools/ioemu/configure                                             |   28 
 tools/ioemu/hw/cirrus_vga.c                                       |   12 
 tools/ioemu/hw/xen_console.c                                      |  432 +++
 tools/ioemu/hw/xen_console.h                                      |   25 
 tools/ioemu/hw/xen_machine_fv.c                                   |  296 ++
 tools/ioemu/hw/xen_machine_pv.c                                   |   73 
 tools/ioemu/hw/xen_platform.c                                     |   14 
 tools/ioemu/hw/xenfb.c                                            | 1157 
++++++++++
 tools/ioemu/hw/xenfb.h                                            |   13 
 tools/ioemu/monitor.c                                             |   26 
 tools/ioemu/target-i386-dm/helper2.c                              |   35 
 tools/ioemu/vl.c                                                  |  273 --
 tools/ioemu/vl.h                                                  |   14 
 tools/ioemu/vnc.c                                                 | 1153 
++++++++-
 tools/ioemu/xenstore.c                                            |   42 
 tools/libxc/xc_domain.c                                           |    6 
 tools/libxc/xc_domain_restore.c                                   |   88 
 tools/libxc/xc_domain_save.c                                      |   40 
 tools/libxc/xc_misc.c                                             |   16 
 tools/libxc/xenctrl.h                                             |    8 
 tools/python/xen/lowlevel/xc/xc.c                                 |   16 
 tools/python/xen/util/acmpolicy.py                                |   30 
 tools/python/xen/util/xsm/acm/acm.py                              |   38 
 tools/python/xen/xend/XendCheckpoint.py                           |    5 
 tools/python/xen/xend/XendConfig.py                               |  101 
 tools/python/xen/xend/XendConstants.py                            |    1 
 tools/python/xen/xend/XendDomain.py                               |   11 
 tools/python/xen/xend/XendDomainInfo.py                           |  101 
 tools/python/xen/xend/XendOptions.py                              |   29 
 tools/python/xen/xend/XendXSPolicyAdmin.py                        |   41 
 tools/python/xen/xend/image.py                                    |  398 +--
 tools/python/xen/xend/server/ConsoleController.py                 |    9 
 tools/python/xen/xend/server/DevController.py                     |   33 
 tools/python/xen/xend/server/blkif.py                             |   17 
 tools/python/xen/xend/server/netif.py                             |    9 
 tools/python/xen/xend/server/pciif.py                             |    4 
 tools/python/xen/xend/server/tpmif.py                             |    4 
 tools/python/xen/xend/server/vfbif.py                             |  117 -
 tools/python/xen/xm/addlabel.py                                   |   17 
 tools/python/xen/xm/create.py                                     |    9 
 tools/python/xen/xm/rmlabel.py                                    |   24 
 tools/python/xen/xm/setpolicy.py                                  |   12 
 tools/python/xen/xm/xenapi_create.py                              |    2 
 tools/xenstore/xenstored_watch.c                                  |   11 
 tools/xentrace/xentrace.c                                         |    2 
 tools/xm-test/lib/XmTestLib/XenAPIDomain.py                       |   11 
 tools/xm-test/tests/security-acm/08_security-acm_xapi.py          |    5 
 tools/xm-test/tests/vtpm/09_vtpm-xapi.py                          |    2 
 unmodified_drivers/linux-2.6/README                               |   10 
 unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h |    8 
 unmodified_drivers/linux-2.6/overrides.mk                         |    2 
 unmodified_drivers/linux-2.6/platform-pci/evtchn.c                |   22 
 unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        |    1 
 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c          |    4 
 xen/arch/ia64/vmx/mmio.c                                          |  121 -
 xen/arch/x86/Makefile                                             |    1 
 xen/arch/x86/acpi/boot.c                                          |    1 
 xen/arch/x86/acpi/power.c                                         |   55 
 xen/arch/x86/boot/cmdline.S                                       |    8 
 xen/arch/x86/boot/trampoline.S                                    |    4 
 xen/arch/x86/domain.c                                             |   31 
 xen/arch/x86/domain_build.c                                       |   14 
 xen/arch/x86/domctl.c                                             |   97 
 xen/arch/x86/flushtlb.c                                           |   33 
 xen/arch/x86/hvm/Makefile                                         |    2 
 xen/arch/x86/hvm/hvm.c                                            |   17 
 xen/arch/x86/hvm/intercept.c                                      |   96 
 xen/arch/x86/hvm/irq.c                                            |   16 
 xen/arch/x86/hvm/mtrr.c                                           |  258 +-
 xen/arch/x86/hvm/platform.c                                       |    3 
 xen/arch/x86/hvm/stdvga.c                                         |  697 ++++++
 xen/arch/x86/hvm/svm/amd_iommu/amd-iommu-detect.c                 |    2 
 xen/arch/x86/hvm/svm/amd_iommu/amd-iommu-init.c                   |    2 
 xen/arch/x86/hvm/svm/svm.c                                        |    2 
 xen/arch/x86/hvm/vioapic.c                                        |    4 
 xen/arch/x86/hvm/vlapic.c                                         |   13 
 xen/arch/x86/hvm/vmx/vmcs.c                                       |   10 
 xen/arch/x86/hvm/vmx/vmx.c                                        |    6 
 xen/arch/x86/hvm/vmx/vtd/io.c                                     |   31 
 xen/arch/x86/hvm/vpic.c                                           |   14 
 xen/arch/x86/hvm/vpt.c                                            |   99 
 xen/arch/x86/mm.c                                                 |   11 
 xen/arch/x86/mm/shadow/common.c                                   |   12 
 xen/arch/x86/mm/shadow/multi.c                                    |   15 
 xen/arch/x86/setup.c                                              |    5 
 xen/arch/x86/shutdown.c                                           |   14 
 xen/arch/x86/smp.c                                                |    6 
 xen/arch/x86/smpboot.c                                            |    2 
 xen/arch/x86/tboot.c                                              |   70 
 xen/arch/x86/traps.c                                              |  469 +++-
 xen/arch/x86/x86_32/asm-offsets.c                                 |    5 
 xen/arch/x86/x86_32/entry.S                                       |   11 
 xen/arch/x86/x86_64/asm-offsets.c                                 |    5 
 xen/arch/x86/x86_64/compat/entry.S                                |   11 
 xen/arch/x86/x86_64/compat/traps.c                                |    6 
 xen/arch/x86/x86_64/entry.S                                       |   10 
 xen/arch/x86/x86_64/mm.c                                          |   27 
 xen/common/sysctl.c                                               |    5 
 xen/drivers/char/console.c                                        |   52 
 xen/drivers/char/ns16550.c                                        |    4 
 xen/drivers/char/serial.c                                         |   61 
 xen/include/asm-x86/amd-iommu.h                                   |    2 
 xen/include/asm-x86/apic.h                                        |    8 
 xen/include/asm-x86/domain.h                                      |    2 
 xen/include/asm-x86/fixmap.h                                      |    1 
 xen/include/asm-x86/flushtlb.h                                    |   20 
 xen/include/asm-x86/hvm/cacheattr.h                               |   16 
 xen/include/asm-x86/hvm/domain.h                                  |    1 
 xen/include/asm-x86/hvm/hvm.h                                     |    6 
 xen/include/asm-x86/hvm/io.h                                      |   42 
 xen/include/asm-x86/hvm/irq.h                                     |    5 
 xen/include/asm-x86/hvm/vpt.h                                     |    4 
 xen/include/asm-x86/io_apic.h                                     |    3 
 xen/include/asm-x86/iommu.h                                       |    5 
 xen/include/asm-x86/msr.h                                         |    8 
 xen/include/asm-x86/page.h                                        |    3 
 xen/include/asm-x86/processor.h                                   |   21 
 xen/include/asm-x86/smp.h                                         |    1 
 xen/include/asm-x86/tboot.h                                       |   90 
 xen/include/asm-x86/x86_32/elf.h                                  |    4 
 xen/include/asm-x86/x86_64/elf.h                                  |    4 
 xen/include/public/domctl.h                                       |   40 
 xen/include/public/hvm/ioreq.h                                    |   17 
 xen/include/public/hvm/params.h                                   |   24 
 xen/include/public/sysctl.h                                       |   25 
 xen/include/xen/console.h                                         |    3 
 xen/xsm/xsm_policy.c                                              |    2 
 156 files changed, 6885 insertions(+), 3550 deletions(-)

diff -r c17bfb091790 -r a07288a84785 Config.mk
--- a/Config.mk Tue Oct 30 11:33:55 2007 -0600
+++ b/Config.mk Tue Oct 30 15:34:44 2007 -0600
@@ -89,7 +89,6 @@ XENSTAT_XENTOP     ?= y
 XENSTAT_XENTOP     ?= y
 VTPM_TOOLS         ?= n
 LIBXENAPI_BINDINGS ?= n
-XENFB_TOOLS        ?= n
 PYTHON_TOOLS       ?= y
 
 -include $(XEN_ROOT)/.config
diff -r c17bfb091790 -r a07288a84785 Makefile
--- a/Makefile  Tue Oct 30 11:33:55 2007 -0600
+++ b/Makefile  Tue Oct 30 15:34:44 2007 -0600
@@ -103,7 +103,7 @@ world:
 
 # clean doesn't do a kclean
 .PHONY: clean
-clean:: 
+clean::
        $(MAKE) -C xen clean
        $(MAKE) -C tools clean
        $(MAKE) -C docs clean
@@ -153,6 +153,11 @@ help:
        @echo '  prep-kernels     - prepares kernel directories, does not build'
        @echo '  uninstall        - attempt to remove installed Xen tools'
        @echo '                     (use with extreme care!)'
+       @echo
+       @echo 'Trusted Boot (tboot) targets:'
+       @echo '  build-tboot      - download and build the tboot module'
+       @echo '  install-tboot    - download, build, and install the tboot 
module'
+       @echo '  clean-tboot      - clean the tboot module if it exists'
        @echo
        @echo 'Environment:'
        @echo '  XEN_PYTHON_NATIVE_INSTALL=y'
@@ -194,8 +199,43 @@ uninstall:
        rm -rf $(D)/usr/share/xen
        rm -rf $(D)/usr/share/man/man1/xen*
        rm -rf $(D)/usr/share/man/man8/xen*
+       rm -rf $(D)/boot/tboot*
 
 # Legacy targets for compatibility
 .PHONY: linux26
 linux26:
        $(MAKE) 'KERNELS=linux-2.6*' kernels
+
+
+#
+# tboot targets
+#
+
+TBOOT_TARFILE = tboot-20071029.tar.gz
+TBOOT_BASE_URL = http://downloads.sourceforge.net/tboot
+
+.PHONY: build-tboot
+build-tboot: download_tboot
+       $(MAKE) -C tboot build
+
+.PHONY: install-tboot
+install-tboot: download_tboot
+       $(MAKE) -C tboot install
+
+.PHONY: clean-tboot
+clean-tboot:
+       [ ! -d tboot ] || $(MAKE) -C tboot clean
+
+.PHONY: distclean-tboot
+distclean-tboot:
+       [ ! -d tboot ] || $(MAKE) -C tboot distclean
+
+.PHONY: download_tboot
+download_tboot: tboot/Makefile
+
+tboot/Makefile: tboot/$(TBOOT_TARFILE)
+       [ -e tboot/Makefile ] || tar -xzf tboot/$(TBOOT_TARFILE) -C tboot/ 
--strip-components 1
+
+tboot/$(TBOOT_TARFILE):
+       mkdir -p tboot
+       wget -O tboot/$(TBOOT_TARFILE) $(TBOOT_BASE_URL)/$(TBOOT_TARFILE)
diff -r c17bfb091790 -r a07288a84785 README
--- a/README    Tue Oct 30 11:33:55 2007 -0600
+++ b/README    Tue Oct 30 15:34:44 2007 -0600
@@ -1,13 +1,13 @@
-#############################
- __  __            _____  _ 
- \ \/ /___ _ __   |___ / / |
-  \  // _ \ '_ \    |_ \ | |
-  /  \  __/ | | |  ___) || |
- /_/\_\___|_| |_| |____(_)_|
-
-#############################
-
-http://www.xensource.com/xen/about.html
+#################################
+ __  __            _____  ____  
+ \ \/ /___ _ __   |___ / |___ \ 
+  \  // _ \ '_ \    |_ \   __) |
+  /  \  __/ | | |  ___) | / __/ 
+ /_/\_\___|_| |_| |____(_)_____|
+                                
+#################################
+
+http://www.xen.org/
 
 What is Xen?
 ============
@@ -21,7 +21,7 @@ by the original Xen development team to 
 by the original Xen development team to build enterprise products
 around Xen.
 
-The 3.1 release offers excellent performance, hardware support and
+The 3.2 release offers excellent performance, hardware support and
 enterprise-grade features such as x86_32-PAE, x86_64, SMP guests and
 live relocation of VMs. This install tree contains source for a Linux
 2.6 guest; ports to Linux 2.4, NetBSD, FreeBSD and Solaris are
@@ -55,8 +55,8 @@ 2. Configure your bootloader to boot Xen
    /boot/grub/menu.lst: edit this file to include an entry like the
    following:
 
-    title Xen 3.1 / XenLinux 2.6
-       kernel /boot/xen-3.1.gz console=vga
+    title Xen 3.2 / XenLinux 2.6
+       kernel /boot/xen-3.2.gz console=vga
        module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
        module /boot/initrd-2.6-xen.img
 
@@ -75,7 +75,7 @@ 2. Configure your bootloader to boot Xen
    32MB memory for internal use, which is not available for allocation
    to virtual machines.
 
-3. Reboot your system and select the "Xen 3.1 / XenLinux 2.6" menu
+3. Reboot your system and select the "Xen 3.2 / XenLinux 2.6" menu
    option. After booting Xen, Linux will start and your initialisation
    scripts should execute in the usual way.
 
@@ -202,3 +202,29 @@ Xend (the Xen daemon) has the following 
     * For optional XenAPI support in XM, PyXML:
           URL:    http://pyxml.sourceforge.net
           YUM:    PyXML
+
+
+Intel(R) Trusted Execution Technology Support
+=============================================
+
+Intel's technology for safer computing, Intel(R) Trusted Execution Technology
+(Intel(R) TXT), defines platform-level enhancements that provide the building
+blocks for creating trusted platforms.  For more information, see
+http://www.intel.com/technology/security/.
+
+Intel(R) TXT support is provided by the Trusted Boot (tboot) module in
+conjunction with minimal logic in the Xen hypervisor.
+
+Tboot is an open source, pre- kernel/VMM module that uses Intel(R) TXT to
+perform a measured and verified launch of an OS kernel/VMM.
+
+The Trusted Boot module is available from
+http://sourceforge.net/projects/tboot.  This project hosts the code in a
+mercurial repo at http://tboot.sourceforge.net/hg/tboot.hg and contains
+tarballs of the source.  Instructions in the tboot README describe how
+to modify grub.conf to use tboot to launch Xen.
+
+There are optional targets as part of Xen's top-level makefile that will
+downlaod and build tboot: install-tboot, build-tboot, dist-tboot, clean-tboot.
+These will download the latest tar file from the SourceForge site using wget,
+then build/install/dist according to Xen's settings.
diff -r c17bfb091790 -r a07288a84785 buildconfigs/mk.linux-2.6
--- a/buildconfigs/mk.linux-2.6 Tue Oct 30 11:33:55 2007 -0600
+++ b/buildconfigs/mk.linux-2.6 Tue Oct 30 15:34:44 2007 -0600
@@ -1,14 +1,10 @@ XEN_LINUX_SOURCE ?= tarball
 XEN_LINUX_SOURCE ?= tarball
 LINUX_VER ?= 2.6
 
-XEN_LINUX_TARBALL_KETCHUP := y
-
 IMAGE_TARGET ?= vmlinux bzImage
-
-XEN_LINUX_ALLOW_INTERFACE_MISMATCH := y
 
 XEN_LINUX_CONFIG_UPDATE := buildconfigs/enable-xen-config
 
 EXTRAVERSION ?=
 
-include buildconfigs/mk.linux-2.6-xen
+include buildconfigs/mk.linux-2.6-common
diff -r c17bfb091790 -r a07288a84785 buildconfigs/mk.linux-2.6-common
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/buildconfigs/mk.linux-2.6-common  Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,158 @@
+LINUX_SERIES = 2.6
+
+# Linux search path, will be searched for tarballs and mercurial
+# repositories.
+LINUX_SRC_PATH ?= .:..
+
+# The source directory is not automatically updated to avoid blowing
+# away developer's changes. If you want to automatically pull a new
+# version of the Linux tree then add `XEN_LINUX_UPDATE=y' to your make
+# command line.
+ifeq ($(XEN_LINUX_UPDATE),y)
+__XEN_LINUX_UPDATE = $(LINUX_SRCDIR)/.force-update
+else
+__XEN_LINUX_UPDATE =
+endif
+
+# Let XEN_TARGET_ARCH override ARCH.
+ifeq ($(XEN_TARGET_ARCH),x86_32)
+LINUX_ARCH     ?= i386
+else
+LINUX_ARCH     ?= $(XEN_TARGET_ARCH)
+endif
+
+LINUX_DIR     = build-linux-$(LINUX_VER)$(EXTRAVERSION)_$(XEN_TARGET_ARCH)
+
+IMAGE_TARGET ?= vmlinuz
+ifneq ($(XEN_TARGET_ARCH),ia64)
+IMAGE_PATH ?= arch/$(LINUX_ARCH)/boot/$(firstword $(IMAGE_TARGET))
+else
+IMAGE_PATH ?= arch/ia64/hp/sim/boot/vmlinux.gz
+endif
+INSTALL_BOOT_PATH := $(DESTDIR)/boot
+
+LINUX_VER3  := $(LINUX_SERIES).$(word 3, $(subst ., ,$(LINUX_VER)))
+
+.PHONY: _build
+_build: build
+
+include buildconfigs/src.$(XEN_LINUX_SOURCE)
+
+# Default to allowing interface mismatch
+ifndef XEN_LINUX_ALLOW_INTERFACE_MISMATCH
+XEN_LINUX_ALLOW_INTERFACE_MISMATCH := y
+endif
+
+KERNELRELEASE = $(shell $(MAKE) -s --no-print-directory -C $(LINUX_DIR) 
kernelrelease)
+
+# The real action starts here!
+.PHONY: build
+build: $(LINUX_DIR)/include/linux/autoconf.h
+ifneq ($(XEN_LINUX_ALLOW_INTERFACE_MISMATCH),y)
+       @if ! diff -urN -X buildconfigs/interface.exclude \
+              $(LINUX_SRCDIR)/include/xen/interface xen/include/public ; then \
+               echo "" 1>&2 ; \
+               echo " *** $(LINUX_SRCDIR)/include/xen/interface is out of date 
" 1>&2 ; \
+               echo " *** relative to $(XEN_ROOT)/xen/include/public." 1>&2 ; \
+               echo "" 1>&2 ; \
+               exit 1 ; \
+       fi
+endif
+       if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \
+           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
+           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) 
INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \
+       fi
+       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) 
$(IMAGE_TARGET)
+       mkdir -p $(INSTALL_BOOT_PATH)
+       cp $(LINUX_DIR)/$(IMAGE_PATH) 
$(INSTALL_BOOT_PATH)/vmlinuz-$(KERNELRELEASE)
+       cp $(LINUX_DIR)/.config $(INSTALL_BOOT_PATH)/config-$(KERNELRELEASE)
+       cp $(LINUX_DIR)/System.map 
$(INSTALL_BOOT_PATH)/System.map-$(KERNELRELEASE)
+
+$(LINUX_DIR)/include/linux/autoconf.h: 
CONFIG_FILE=$(CURDIR)/$(LINUX_DIR)/.config
+$(LINUX_DIR)/include/linux/autoconf.h: $(LINUX_SRCDIR)/.valid-src
+       rm -rf $(LINUX_DIR)
+       mkdir -p $(LINUX_DIR)
+       # Re-use config from install dir if one exists. Next try to use
+       # buildconfigs/create_config.sh is one is provided by the source
+       # tree. Finally attempt to use make defconfig.
+       set -e ; \
+       CONFIG_VERSION=$$(sed -ne 's/$$(XENGUEST)//; s/^EXTRAVERSION = //p' 
$(LINUX_SRCDIR)/Makefile); \
+       if [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION$(EXTRAVERSION) ] ; then \
+         cp 
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION$(EXTRAVERSION) 
$(CONFIG_FILE) ; \
+        elif [ -e $(LINUX_SRCDIR)/buildconfigs/create_config.sh ] ; then \
+         cd $(LINUX_SRCDIR) && sh buildconfigs/create_config.sh \
+               $(CONFIG_FILE) $(EXTRAVERSION) $(XEN_TARGET_ARCH) 
$(XEN_SYSTYPE) ; \
+          echo "Configured $(LINUX_DIR) using create_config.sh" ; \
+       elif $(MAKE) -C $(LINUX_SRCDIR) ARCH=$(LINUX_ARCH) defconfig 
O=$$(/bin/pwd)/$(LINUX_DIR) ; then \
+         echo "Configured $(LINUX_DIR) using defconfig" ; \
+       else \
+          echo "No configuration method found for this kernel" ; \
+       fi
+ifneq ($(XEN_LINUX_CONFIG_UPDATE),)
+       echo "Updating $(CONFIG_FILE) using $(XEN_LINUX_CONFIG_UPDATE)"
+       sh $(XEN_LINUX_CONFIG_UPDATE) $(CONFIG_FILE)
+endif
+ifeq ($(XEN_TARGET_ARCH),x86_32)
+ifeq ($(pae),y)
+       sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# 
CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > 
$(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE)
+else
+       grep '^CONFIG_HIGHMEM64G=y' $(CONFIG_FILE) >/dev/null && ( sed -e 
's!^CONFIG_HIGHMEM64G=y$$!\# CONFIG_HIGHMEM64G is not set!;s!^\# 
CONFIG_HIGHMEM4G is not set$$!CONFIG_HIGHMEM4G=y!' $(CONFIG_FILE) > 
$(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE) ) || true
+endif
+endif
+ifneq ($(EXTRAVERSION),)
+       echo "$(EXTRAVERSION)" >$(LINUX_DIR)/localversion-xen
+endif
+       $(MAKE) -C $(LINUX_SRCDIR) ARCH=$(LINUX_ARCH) oldconfig 
O=$$(/bin/pwd)/$(LINUX_DIR)
+       @if [ ! -f $(LINUX_DIR)/Makefile ] ; then \
+           echo "***********************************"; \
+           echo "oldconfig did not create a Makefile"; \
+           echo "Generating $(LINUX_DIR)/Makefile   "; \
+           echo "***********************************"; \
+           ( echo "# Automatically generated: don't edit"; \
+             echo ""; \
+             echo "VERSION = 2"; \
+             echo "PATCHLEVEL = 6"; \
+             echo ""; \
+             echo "KERNELSRC    := $(CURDIR)/$(LINUX_SRCDIR)"; \
+             echo "KERNELOUTPUT := $(CURDIR)/$(LINUX_DIR)"; \
+             echo ""; \
+             echo "MAKEFLAGS += --no-print-directory"; \
+             echo ""; \
+             echo ".PHONY: all \$$(MAKECMDGOALS)"; \
+             echo ""; \
+             echo "all:"; \
+             echo "    \$$(MAKE) -C \$$(KERNELSRC) O=\$$(KERNELOUTPUT)"; \
+             echo ""; \
+             echo "Makefile:;"; \
+             echo ""; \
+             echo "\$$(filter-out all Makefile,\$$(MAKECMDGOALS)) %/:"; \
+             echo "    \$$(MAKE) -C \$$(KERNELSRC) O=\$$(KERNELOUTPUT) \$$@"; \
+           ) > $(LINUX_DIR)/Makefile ; \
+       fi
+       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) prepare
+
+.PHONY: prep
+prep: $(LINUX_DIR)/include/linux/autoconf.h
+
+.PHONY: config
+config: CONFIGMODE = menuconfig
+config: $(LINUX_DIR)/include/linux/autoconf.h
+       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) $(CONFIGMODE)
+
+.PHONY: clean
+clean::
+       [ ! -d $(LINUX_DIR) ] || \
+               $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
+
+.PHONY: delete
+delete: 
+       rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR) $(LINUX_SRCDIR)
+
+.PHONY: mrproper
+mrproper:
+       rm -rf $(LINUX_SRCDIR)
+       rm -f linux-$(LINUX_VER).tar.bz2
+
+.PHONY: $(LINUX_SRCDIR)/.force-update
+$(LINUX_SRCDIR)/.force-update:
+       @ :
diff -r c17bfb091790 -r a07288a84785 buildconfigs/mk.linux-2.6-native
--- a/buildconfigs/mk.linux-2.6-native  Tue Oct 30 11:33:55 2007 -0600
+++ b/buildconfigs/mk.linux-2.6-native  Tue Oct 30 15:34:44 2007 -0600
@@ -2,6 +2,4 @@ IMAGE_TARGET = bzImage
 IMAGE_TARGET = bzImage
 INSTALL_BOOT_PATH = $(DESTDIR)/boot
 
-XEN_LINUX_ALLOW_INTERFACE_MISMATCH := y
-
-include buildconfigs/mk.linux-2.6-xen
+include buildconfigs/mk.linux-2.6-common
diff -r c17bfb091790 -r a07288a84785 buildconfigs/mk.linux-2.6-paravirt
--- a/buildconfigs/mk.linux-2.6-paravirt        Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-XEN_LINUX_SOURCE ?= tarball
-XEN_LINUX_MIRROR ?= http://xenbits.xensource.com/ext/paravirt_ops/
-LINUX_VER ?= 2.6-paravirt
-
-# This target currently only supports x86_32.
-XEN_TARGET_ARCH = x86_32
-IMAGE_TARGET ?= vmlinux bzImage
-
-XEN_LINUX_ALLOW_INTERFACE_MISMATCH := y
-
-XEN_LINUX_CONFIG_UPDATE := buildconfigs/enable-xen-config
-
-EXTRAVERSION ?= -paravirt
-
-include buildconfigs/mk.linux-2.6-xen
diff -r c17bfb091790 -r a07288a84785 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Tue Oct 30 11:33:55 2007 -0600
+++ b/buildconfigs/mk.linux-2.6-xen     Tue Oct 30 15:34:44 2007 -0600
@@ -1,163 +1,6 @@ LINUX_SERIES = 2.6
-LINUX_SERIES = 2.6
+EXTRAVERSION ?= -xen
 LINUX_VER    ?= 2.6.18
-
-EXTRAVERSION ?= -xen
-
-# Linux search path, will be searched for tarballs and mercurial
-# repositories.
-LINUX_SRC_PATH ?= .:..
-
-# The source directory is not automatically updated to avoid blowing
-# away developer's changes. If you want to automatically pull a new
-# version of the Linux tree then add `XEN_LINUX_UPDATE=y' to your make
-# command line.
-ifeq ($(XEN_LINUX_UPDATE),y)
-__XEN_LINUX_UPDATE = $(LINUX_SRCDIR)/.force-update
-else
-__XEN_LINUX_UPDATE =
-endif
 
 XEN_LINUX_SOURCE ?= hg-clone
 
-# Let XEN_TARGET_ARCH override ARCH.
-ifeq ($(XEN_TARGET_ARCH),x86_32)
-LINUX_ARCH     ?= i386
-else
-LINUX_ARCH     ?= $(XEN_TARGET_ARCH)
-endif
-
-LINUX_DIR     = build-linux-$(LINUX_VER)$(EXTRAVERSION)_$(XEN_TARGET_ARCH)
-
-IMAGE_TARGET ?= vmlinuz
-ifneq ($(XEN_TARGET_ARCH),ia64)
-IMAGE_PATH ?= arch/$(LINUX_ARCH)/boot/$(firstword $(IMAGE_TARGET))
-else
-IMAGE_PATH ?= arch/ia64/hp/sim/boot/vmlinux.gz
-endif
-INSTALL_BOOT_PATH := $(DESTDIR)/boot
-
-LINUX_VER3  := $(LINUX_SERIES).$(word 3, $(subst ., ,$(LINUX_VER)))
-
-.PHONY: _build
-_build: build
-
-include buildconfigs/src.$(XEN_LINUX_SOURCE)
-
-# Default to allowing interface mismatch
-ifndef XEN_LINUX_ALLOW_INTERFACE_MISMATCH
-XEN_LINUX_ALLOW_INTERFACE_MISMATCH := y
-endif
-
-KERNELRELEASE = $(shell $(MAKE) -s --no-print-directory -C $(LINUX_DIR) 
kernelrelease)
-
-# The real action starts here!
-.PHONY: build
-build: $(LINUX_DIR)/include/linux/autoconf.h
-ifneq ($(XEN_LINUX_ALLOW_INTERFACE_MISMATCH),y)
-       @if ! diff -urN -X buildconfigs/interface.exclude \
-              $(LINUX_SRCDIR)/include/xen/interface xen/include/public ; then \
-               echo "" 1>&2 ; \
-               echo " *** $(LINUX_SRCDIR)/include/xen/interface is out of date 
" 1>&2 ; \
-               echo " *** relative to $(XEN_ROOT)/xen/include/public." 1>&2 ; \
-               echo "" 1>&2 ; \
-               exit 1 ; \
-       fi
-endif
-       if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
-           $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) 
INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \
-       fi
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) 
$(IMAGE_TARGET)
-       mkdir -p $(INSTALL_BOOT_PATH)
-       cp $(LINUX_DIR)/$(IMAGE_PATH) 
$(INSTALL_BOOT_PATH)/vmlinuz-$(KERNELRELEASE)
-       cp $(LINUX_DIR)/.config $(INSTALL_BOOT_PATH)/config-$(KERNELRELEASE)
-       cp $(LINUX_DIR)/System.map 
$(INSTALL_BOOT_PATH)/System.map-$(KERNELRELEASE)
-
-$(LINUX_DIR)/include/linux/autoconf.h: 
CONFIG_FILE=$(CURDIR)/$(LINUX_DIR)/.config
-$(LINUX_DIR)/include/linux/autoconf.h: $(LINUX_SRCDIR)/.valid-src
-       rm -rf $(LINUX_DIR)
-       mkdir -p $(LINUX_DIR)
-       # Re-use config from install dir if one exists. Next try to use
-       # buildconfigs/create_config.sh is one is provided by the source
-       # tree. Finally attempt to use make defconfig.
-       set -e ; \
-       CONFIG_VERSION=$$(sed -ne 's/$$(XENGUEST)//; s/^EXTRAVERSION = //p' 
$(LINUX_SRCDIR)/Makefile); \
-       if [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION$(EXTRAVERSION) ] ; then \
-         cp 
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION$(EXTRAVERSION) 
$(CONFIG_FILE) ; \
-        elif [ -e $(LINUX_SRCDIR)/buildconfigs/create_config.sh ] ; then \
-         cd $(LINUX_SRCDIR) && sh buildconfigs/create_config.sh \
-               $(CONFIG_FILE) $(EXTRAVERSION) $(XEN_TARGET_ARCH) 
$(XEN_SYSTYPE) ; \
-          echo "Configured $(LINUX_DIR) using create_config.sh" ; \
-       elif $(MAKE) -C $(LINUX_SRCDIR) ARCH=$(LINUX_ARCH) defconfig 
O=$$(/bin/pwd)/$(LINUX_DIR) ; then \
-         echo "Configured $(LINUX_DIR) using defconfig" ; \
-       else \
-          echo "No configuration method found for this kernel" ; \
-       fi
-ifneq ($(XEN_LINUX_CONFIG_UPDATE),)
-       echo "Updating $(CONFIG_FILE) using $(XEN_LINUX_CONFIG_UPDATE)"
-       sh $(XEN_LINUX_CONFIG_UPDATE) $(CONFIG_FILE)
-endif
-ifeq ($(XEN_TARGET_ARCH),x86_32)
-ifeq ($(pae),y)
-       sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# 
CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > 
$(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE)
-else
-       grep '^CONFIG_HIGHMEM64G=y' $(CONFIG_FILE) >/dev/null && ( sed -e 
's!^CONFIG_HIGHMEM64G=y$$!\# CONFIG_HIGHMEM64G is not set!;s!^\# 
CONFIG_HIGHMEM4G is not set$$!CONFIG_HIGHMEM4G=y!' $(CONFIG_FILE) > 
$(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE) ) || true
-endif
-endif
-ifneq ($(EXTRAVERSION),)
-       echo "$(EXTRAVERSION)" >$(LINUX_DIR)/localversion-xen
-endif
-       $(MAKE) -C $(LINUX_SRCDIR) ARCH=$(LINUX_ARCH) oldconfig 
O=$$(/bin/pwd)/$(LINUX_DIR)
-       @if [ ! -f $(LINUX_DIR)/Makefile ] ; then \
-           echo "***********************************"; \
-           echo "oldconfig did not create a Makefile"; \
-           echo "Generating $(LINUX_DIR)/Makefile   "; \
-           echo "***********************************"; \
-           ( echo "# Automatically generated: don't edit"; \
-             echo ""; \
-             echo "VERSION = 2"; \
-             echo "PATCHLEVEL = 6"; \
-             echo ""; \
-             echo "KERNELSRC    := $(CURDIR)/$(LINUX_SRCDIR)"; \
-             echo "KERNELOUTPUT := $(CURDIR)/$(LINUX_DIR)"; \
-             echo ""; \
-             echo "MAKEFLAGS += --no-print-directory"; \
-             echo ""; \
-             echo ".PHONY: all \$$(MAKECMDGOALS)"; \
-             echo ""; \
-             echo "all:"; \
-             echo "    \$$(MAKE) -C \$$(KERNELSRC) O=\$$(KERNELOUTPUT)"; \
-             echo ""; \
-             echo "Makefile:;"; \
-             echo ""; \
-             echo "\$$(filter-out all Makefile,\$$(MAKECMDGOALS)) %/:"; \
-             echo "    \$$(MAKE) -C \$$(KERNELSRC) O=\$$(KERNELOUTPUT) \$$@"; \
-           ) > $(LINUX_DIR)/Makefile ; \
-       fi
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) prepare
-
-.PHONY: prep
-prep: $(LINUX_DIR)/include/linux/autoconf.h
-
-.PHONY: config
-config: CONFIGMODE = menuconfig
-config: $(LINUX_DIR)/include/linux/autoconf.h
-       $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) $(CONFIGMODE)
-
-.PHONY: clean
-clean::
-       [ ! -d $(LINUX_DIR) ] || \
-               $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
-
-.PHONY: delete
-delete: 
-       rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR) $(LINUX_SRCDIR)
-
-.PHONY: mrproper
-mrproper:
-       rm -rf $(LINUX_SRCDIR)
-       rm -f linux-$(LINUX_VER).tar.bz2
-
-.PHONY: $(LINUX_SRCDIR)/.force-update
-$(LINUX_SRCDIR)/.force-update:
-       @ :
+include buildconfigs/mk.linux-2.6-common
diff -r c17bfb091790 -r a07288a84785 buildconfigs/mk.linux-2.6.5-SLES-xen
--- a/buildconfigs/mk.linux-2.6.5-SLES-xen      Tue Oct 30 11:33:55 2007 -0600
+++ b/buildconfigs/mk.linux-2.6.5-SLES-xen      Tue Oct 30 15:34:44 2007 -0600
@@ -1,8 +1,6 @@
 # This tree only supports PAE
 XEN_TARGET_ARCH = x86_32
 XEN_TARGET_X86_PAE = y
-
-XEN_LINUX_ALLOW_INTERFACE_MISMATCH := y
 
 EXTRAVERSION = -xen
 LINUX_VER = 2.6.5-SLES
diff -r c17bfb091790 -r a07288a84785 buildconfigs/mk.linux-2.6.9-RHEL-xen
--- a/buildconfigs/mk.linux-2.6.9-RHEL-xen      Tue Oct 30 11:33:55 2007 -0600
+++ b/buildconfigs/mk.linux-2.6.9-RHEL-xen      Tue Oct 30 15:34:44 2007 -0600
@@ -1,8 +1,6 @@
 # This tree only supports PAE
 XEN_TARGET_ARCH = x86_32
 XEN_TARGET_X86_PAE = y
-
-XEN_LINUX_ALLOW_INTERFACE_MISMATCH := y
 
 EXTRAVERSION = -xen
 LINUX_VER = 2.6.9-RHEL
diff -r c17bfb091790 -r a07288a84785 buildconfigs/src.tarball
--- a/buildconfigs/src.tarball  Tue Oct 30 11:33:55 2007 -0600
+++ b/buildconfigs/src.tarball  Tue Oct 30 15:34:44 2007 -0600
@@ -1,8 +1,5 @@ XEN_LINUX_MIRROR ?= http://www.kernel.or
 XEN_LINUX_MIRROR ?= http://www.kernel.org/pub/linux/kernel/v2.6/
 XEN_LINUX_TARBALL ?= linux-$(LINUX_VER)-xen.tar.bz2
-
-# Update using ketchup instead of manipulating tarball manually.
-XEN_LINUX_TARBALL_KETCHUP ?= n
 
 LINUX_SRCDIR ?= linux-$(LINUX_VER)
 
@@ -17,17 +14,6 @@ linux-%.tar.bz2:
 
 # XXX create a pristine tree for diff -Nurp convenience
 
-ifeq ($(XEN_LINUX_TARBALL_KETCHUP),y)
 %/.valid-src: $(__XEN_LINUX_UPDATE)
        $(KETCHUP) -d $(@D) $(LINUX_VER)
        touch $@ # update timestamp to avoid rebuild
-else
-%/.valid-src: $(__XEN_LINUX_UPDATE) %.tar.bz2
-       rm -rf tmp-linux-$* $(@D)
-       mkdir -p tmp-linux-$*
-       tar -C tmp-linux-$* -jxf $<
-       -@rm -f tmp-linux-$*/pax_global_header
-       mv tmp-linux-$*/* $(@D)
-       @rm -rf tmp-linux-$*
-       touch $@ # update timestamp to avoid rebuild
-endif
diff -r c17bfb091790 -r a07288a84785 docs/misc/vtd.txt
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/misc/vtd.txt Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,50 @@
+Title   : How to do PCI Passthrough with VT-d
+Authors : Allen Kay    <allen.m.kay@xxxxxxxxx>
+          Weidong Han  <weidong.han@xxxxxxxxx>
+Created : October-24-2007
+Updated : October-24-2007
+
+How to turn on VT-d in Xen
+--------------------------
+
+1 ) cd xen-unstable.hg
+2 ) make install
+3 ) make linux-2.6-xen-config CONFIGMODE=menuconfig
+4 ) change XEN->"PCI-device backend driver" from "M" to "*".
+5 ) make linux-2.6-xen-build
+6 ) make linux-2.6-xen-install
+7 ) depmod 2.6.18.8-xen
+8 ) mkinitrd -v -f --with=ahci --with=aacraid --with=sd_mod --with=scsi_mod 
initrd-2.6.18-xen.img 2.6.18.8-xen
+9 ) cp initrd-2.6.18-xen.img /boot
+10) lspci - select the PCI BDF you want to assign to guest OS
+11) "hide" pci device from dom0 as following sample grub entry:
+
+title Xen-Fedora Core (2.6.18-xen)
+        root (hd0,0)
+        kernel /boot/xen.gz com1=115200,8n1 console=com1 vtd=1
+        module /boot/vmlinuz-2.6.18.8-xen root=LABEL=/ ro console=tty0 
console=ttyS0,115200,8n1 pciback.hide=(01:00.0)(03:00.0) 
pciback.verbose_request=1 apic=debug maxcpus=1
+        module /boot/initrd-2.6.18-xen.img
+
+12) reboot system
+13) add "pci" line in /etc/xen/hvm.conf for to assigned devices
+        pci = [ '01:00.0', '03:00.0' ]
+15) start hvm guest and use "lspci" to see the passthru device and
+    "ifconfig" to see if IP address has been assigned to NIC devices.
+
+
+VT-d Enabled Systems
+--------------------
+
+1) For VT-d enabling work on Xen, we have been using development
+systems using following Intel motherboards:
+    - DQ35MP
+    - DQ35JO
+
+2) As far as we know, following OEM systems also has vt-d enabled.
+Feel free to add others as they become available.
+
+- Dell: Optiplex 755
+http://www.dell.com/content/products/category.aspx/optix?c=us&cs=555&l=en&s=biz
+
+- HP Compaq:  DC7800
+http://h10010.www1.hp.com/wwpc/us/en/en/WF04a/12454-12454-64287-321860-3328898.html
diff -r c17bfb091790 -r a07288a84785 tools/Makefile
--- a/tools/Makefile    Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/Makefile    Tue Oct 30 15:34:44 2007 -0600
@@ -20,7 +20,6 @@ SUBDIRS-y += libaio
 SUBDIRS-y += libaio
 SUBDIRS-y += blktap
 SUBDIRS-y += libfsimage
-SUBDIRS-$(XENFB_TOOLS) += xenfb
 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
 
 # These don't cross-compile
diff -r c17bfb091790 -r a07288a84785 tools/check/Makefile
--- a/tools/check/Makefile      Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/check/Makefile      Tue Oct 30 15:34:44 2007 -0600
@@ -7,7 +7,7 @@ all: build
 # Check this machine is OK for building on.
 .PHONY: build
 build:
-       XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) 
ACM_SECURITY=$(ACM_SECURITY) ./chk build
+       LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) 
./chk build
 
 # Check this machine is OK for installing on.
 # DO NOT use this check from 'make install' in the parent
@@ -15,7 +15,7 @@ build:
 # copy rather than actually installing.
 .PHONY: install
 install:
-       XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) 
ACM_SECURITY=$(ACM_SECURITY) ./chk install
+       LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ACM_SECURITY=$(ACM_SECURITY) 
./chk install
 
 .PHONY: clean
 clean:
diff -r c17bfb091790 -r a07288a84785 tools/check/check_libvncserver
--- a/tools/check/check_libvncserver    Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#!/bin/sh
-# CHECK-BUILD CHECK-INSTALL
-
-if [ ! "$XENFB_TOOLS" = "y" ]
-then
-    echo -n "unused, "
-    exit 0
-fi
-
-RC=0
-
-LIBVNCSERVER_CONFIG="$(which libvncserver-config)"
-tmpfile=$(mktemp)
-
-if test -z ${LIBVNCSERVER_CONFIG}; then 
-    RC=1
-else
-    ${LIBVNCSERVER_CONFIG} --libs 2>&1 > /dev/null
-    RC=$?
-fi
-
-if test $RC -ne 0; then
-    echo "FAILED"
-       echo " *** libvncserver-config is missing. "
-    echo " *** Please install libvncserver."
-elif ! ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile >/dev/null 2>&1; then
-    echo "FAILED"
-    echo " *** dependency libraries for libvncserver are missing: "
-    RC=1
-    for i in $(ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile 2>&1 >/dev/null); 
do
-        case $i in
-        -l*) echo lib${i#-l}
-        esac
-    done
-fi
-rm -f $tmpfile
-
-exit $RC
diff -r c17bfb091790 -r a07288a84785 tools/check/check_sdl
--- a/tools/check/check_sdl     Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/bin/sh
-# CHECK-BUILD CHECK-INSTALL
-
-if [ ! "$XENFB_TOOLS" = "y" ]
-then
-    echo -n "unused, "
-    exit 0
-fi
-
-RC=0
-
-SDL_CONFIG="$(which sdl-config)"
-
-if test -z ${SDL_CONFIG}; then 
-    RC=1
-else
-    ${SDL_CONFIG} --libs 2>&1 > /dev/null
-    RC=$?
-fi
-
-if test $RC -ne 0; then
-    echo "FAILED"
-       echo " *** sdl-config is missing. "
-    echo " *** Please install libsdl-dev or sdl."
-fi
-
-exit $RC
diff -r c17bfb091790 -r a07288a84785 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/console/daemon/io.c Tue Oct 30 15:34:44 2007 -0600
@@ -35,6 +35,7 @@
 #include <termios.h>
 #include <stdarg.h>
 #include <sys/mman.h>
+#include <sys/time.h>
 #if defined(__NetBSD__) || defined(__OpenBSD__)
 #include <util.h>
 #elif defined(__linux__) || defined(__Linux__)
@@ -47,13 +48,20 @@
 /* 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)
 
+/* How many events are allowed in each time period */
+#define RATE_LIMIT_ALLOWANCE 30
+/* Duration of each time period in ms */
+#define RATE_LIMIT_PERIOD 200
+
 extern int log_reload;
 extern int log_guest;
 extern int log_hv;
 extern char *log_dir;
 
 static int log_hv_fd = -1;
+static evtchn_port_or_error_t log_hv_evtchn = -1;
 static int xc_handle = -1;
+static int xce_handle = -1;
 
 struct buffer
 {
@@ -76,10 +84,12 @@ struct domain
        char *serialpath;
        int use_consolepath;
        int ring_ref;
-       evtchn_port_t local_port;
-       evtchn_port_t remote_port;
+       evtchn_port_or_error_t local_port;
+       evtchn_port_or_error_t remote_port;
        int xce_handle;
        struct xencons_interface *interface;
+       int event_count;
+       long long next_period;
 };
 
 static struct domain *dom_head;
@@ -377,6 +387,7 @@ static int domain_create_ring(struct dom
 static int domain_create_ring(struct domain *dom)
 {
        int err, remote_port, ring_ref, rc;
+       char *type, path[PATH_MAX];
 
        err = xs_gather(xs, dom->serialpath,
                        "ring-ref", "%u", &ring_ref,
@@ -393,6 +404,14 @@ static int domain_create_ring(struct dom
        } else
                dom->use_consolepath = 0;
 
+       sprintf(path, "%s/type", dom->use_consolepath ? dom->conspath: 
dom->serialpath);
+       type = xs_read(xs, XBT_NULL, path, NULL);
+       if (type && strcmp(type, "xenconsoled") != 0) {
+               free(type);
+               return 0;
+       }
+       free(type);
+
        if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
                goto out;
 
@@ -483,6 +502,13 @@ static struct domain *create_domain(int 
 {
        struct domain *dom;
        char *s;
+       struct timeval tv;
+
+       if (gettimeofday(&tv, NULL) < 0) {
+               dolog(LOG_ERR, "Cannot get time of day %s:%s:L%d",
+                     __FILE__, __FUNCTION__, __LINE__);
+               return NULL;
+       }
 
        dom = (struct domain *)malloc(sizeof(struct domain));
        if (dom == NULL) {
@@ -518,6 +544,8 @@ static struct domain *create_domain(int 
        dom->buffer.size = 0;
        dom->buffer.capacity = 0;
        dom->buffer.max_capacity = 0;
+       dom->event_count = 0;
+       dom->next_period = (tv.tv_sec * 1000) + (tv.tv_usec / 1000) + 
RATE_LIMIT_PERIOD;
        dom->next = NULL;
 
        dom->ring_ref = -1;
@@ -704,14 +732,17 @@ static void handle_tty_write(struct doma
 
 static void handle_ring_read(struct domain *dom)
 {
-       evtchn_port_t port;
+       evtchn_port_or_error_t port;
 
        if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
                return;
 
+       dom->event_count++;
+
        buffer_append(dom);
 
-       (void)xc_evtchn_unmask(dom->xce_handle, port);
+       if (dom->event_count < RATE_LIMIT_ALLOWANCE)
+               (void)xc_evtchn_unmask(dom->xce_handle, port);
 }
 
 static void handle_xs(void)
@@ -743,12 +774,20 @@ static void handle_hv_logs(void)
        char buffer[1024*16];
        char *bufptr = buffer;
        unsigned int size = sizeof(buffer);
-       if (xc_readconsolering(xc_handle, &bufptr, &size, 1) == 0) {
+       static uint32_t index = 0;
+       evtchn_port_or_error_t port;
+
+       if ((port = xc_evtchn_pending(xce_handle)) == -1)
+               return;
+
+       if (xc_readconsolering(xc_handle, &bufptr, &size, 0, 1, &index) == 0) {
                int len = write(log_hv_fd, buffer, size);
                if (len < 0)
                        dolog(LOG_ERR, "Failed to write hypervisor log: %d 
(%s)",
                              errno, strerror(errno));
        }
+
+       (void)xc_evtchn_unmask(xce_handle, port);
 }
 
 static void handle_log_reload(void)
@@ -776,17 +815,34 @@ void handle_io(void)
 
        if (log_hv) {
                xc_handle = xc_interface_open();
-               if (xc_handle == -1)
+               if (xc_handle == -1) {
                        dolog(LOG_ERR, "Failed to open xc handle: %d (%s)",
                              errno, strerror(errno));
-               else
-                       log_hv_fd = create_hv_log();
+                       goto out;
+               }
+               xce_handle = xc_evtchn_open();
+               if (xce_handle == -1) {
+                       dolog(LOG_ERR, "Failed to open xce handle: %d (%s)",
+                             errno, strerror(errno));
+                       goto out;
+               }
+               log_hv_fd = create_hv_log();
+               if (log_hv_fd == -1)
+                       goto out;
+               log_hv_evtchn = xc_evtchn_bind_virq(xce_handle, VIRQ_CON_RING);
+               if (log_hv_evtchn == -1) {
+                       dolog(LOG_ERR, "Failed to bind to VIRQ_CON_RING: "
+                             "%d (%s)", errno, strerror(errno));
+                       goto out;
+               }
        }
 
        for (;;) {
                struct domain *d, *n;
-               struct timeval timeout = { 1, 0 }; /* Read HV logs every 1 
second */
                int max_fd = -1;
+               struct timeval timeout;
+               struct timeval tv;
+               long long now, next_timeout = 0;
 
                FD_ZERO(&readfds);
                FD_ZERO(&writefds);
@@ -794,8 +850,38 @@ void handle_io(void)
                FD_SET(xs_fileno(xs), &readfds);
                max_fd = MAX(xs_fileno(xs), max_fd);
 
+               if (log_hv) {
+                       FD_SET(xc_evtchn_fd(xce_handle), &readfds);
+                       max_fd = MAX(xc_evtchn_fd(xce_handle), max_fd);
+               }
+
+               if (gettimeofday(&tv, NULL) < 0)
+                       return;
+               now = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+
+               /* Re-calculate any event counter allowances & unblock
+                  domains with new allowance */
                for (d = dom_head; d; d = d->next) {
-                       if (d->xce_handle != -1) {
+                       /* Add 5ms of fuzz since select() often returns
+                          a couple of ms sooner than requested. Without
+                          the fuzz we typically do an extra spin in select()
+                          with a 1/2 ms timeout every other iteration */
+                       if ((now+5) > d->next_period) {
+                               d->next_period = now + RATE_LIMIT_PERIOD;
+                               if (d->event_count >= RATE_LIMIT_ALLOWANCE) {
+                                       (void)xc_evtchn_unmask(d->xce_handle, 
d->local_port);
+                               }
+                               d->event_count = 0;
+                       }
+               }
+
+               for (d = dom_head; d; d = d->next) {
+                       if (d->event_count >= RATE_LIMIT_ALLOWANCE) {
+                               /* Determine if we're going to be the next time 
slice to expire */
+                               if (!next_timeout ||
+                                   d->next_period < next_timeout)
+                                       next_timeout = d->next_period;
+                       } else if (d->xce_handle != -1) {
                                int evtchn_fd = xc_evtchn_fd(d->xce_handle);
                                FD_SET(evtchn_fd, &readfds);
                                max_fd = MAX(evtchn_fd, max_fd);
@@ -811,11 +897,19 @@ void handle_io(void)
                        }
                }
 
-               /* XXX I wish we didn't have to busy wait for hypervisor logs
-                * but there's no obvious way to get event channel notifications
-                * for new HV log data as we can with guest */
+               /* If any domain has been rate limited, we need to work
+                  out what timeout to supply to select */
+               if (next_timeout) {
+                       long long duration = (next_timeout - now);
+                       if (duration <= 0) /* sanity check */
+                               duration = 1;
+                       timeout.tv_sec = duration / 1000;
+                       timeout.tv_usec = ((duration - (timeout.tv_sec * 1000))
+                                          * 1000);
+               }
+
                ret = select(max_fd + 1, &readfds, &writefds, 0,
-                            log_hv_fd != -1 ? &timeout : NULL);
+                            next_timeout ? &timeout : NULL);
 
                if (log_reload) {
                        handle_log_reload();
@@ -832,12 +926,10 @@ void handle_io(void)
                        break;
                }
 
-               /* Always process HV logs even if not a timeout */
-               if (log_hv_fd != -1)
+               if (log_hv && FD_ISSET(xc_evtchn_fd(xce_handle), &readfds))
                        handle_hv_logs();
 
-               /* Must not check returned FDSET if it was a timeout */
-               if (ret == 0)
+               if (ret <= 0)
                        continue;
 
                if (FD_ISSET(xs_fileno(xs), &readfds))
@@ -845,9 +937,11 @@ void handle_io(void)
 
                for (d = dom_head; d; d = n) {
                        n = d->next;
-                       if (d->xce_handle != -1 &&
-                           FD_ISSET(xc_evtchn_fd(d->xce_handle), &readfds))
-                               handle_ring_read(d);
+                       if (d->event_count < RATE_LIMIT_ALLOWANCE) {
+                               if (d->xce_handle != -1 &&
+                                   FD_ISSET(xc_evtchn_fd(d->xce_handle), 
&readfds))
+                                       handle_ring_read(d);
+                       }
 
                        if (d->tty_fd != -1 && FD_ISSET(d->tty_fd, &readfds))
                                handle_tty_read(d);
@@ -860,6 +954,7 @@ void handle_io(void)
                }
        }
 
+ out:
        if (log_hv_fd != -1) {
                close(log_hv_fd);
                log_hv_fd = -1;
@@ -868,6 +963,11 @@ void handle_io(void)
                xc_interface_close(xc_handle);
                xc_handle = -1;
        }
+       if (xce_handle != -1) {
+               xc_evtchn_close(xce_handle);
+               xce_handle = -1;
+       }
+       log_hv_evtchn = -1;
 }
 
 /*
diff -r c17bfb091790 -r a07288a84785 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/examples/xend-config.sxp    Tue Oct 30 15:34:44 2007 -0600
@@ -192,8 +192,39 @@
 # Empty string is no authentication.
 (vncpasswd '')
 
+# The VNC server can be told to negotiate a TLS session
+# to encryption all traffic, and provide x509 cert to
+# clients enalbing them to verify server identity. The
+# GTK-VNC widget, virt-viewer, virt-manager and VeNCrypt
+# all support the VNC extension for TLS used in QEMU. The
+# TightVNC/RealVNC/UltraVNC clients do not.
+#
+# To enable this create x509 certificates / keys in the
+# directory /etc/xen/vnc
+#
+#  ca-cert.pem       - The CA certificate
+#  server-cert.pem   - The Server certificate signed by the CA
+#  server-key.pem    - The server private key
+#
+# and then uncomment this next line
+# (vnc-tls 1)
+
+# The certificate dir can be pointed elsewhere..
+#
+# (vnc-x509-cert-dir /etc/xen/vnc)
+
+# The server can be told to request & validate an x509
+# certificate from the client. Only clients with a cert
+# signed by the trusted CA will be able to connect. This
+# is more secure the password auth alone. Passwd auth can
+# used at the same time if desired. To enable client cert
+# checking uncomment this:
+#
+# (vnc-x509-verify 1)
+
 # The default keymap to use for the VM's virtual keyboard
 # when not specififed in VM's configuration
 #(keymap 'en-us')
 
-
+# Script to run when the label of a resource has changed.
+#(resource-label-change-script '')
diff -r c17bfb091790 -r a07288a84785 tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/firmware/hvmloader/acpi/build.c     Tue Oct 30 15:34:44 2007 -0600
@@ -226,7 +226,7 @@ static int construct_processor_objects(u
     }
 
     /* NameString */
-    strncpy(p, pr_scope, strlen(pr_scope));
+    strncpy((char *)p, pr_scope, strlen(pr_scope));
     p += strlen(pr_scope);
 
     /*
diff -r c17bfb091790 -r a07288a84785 
tools/firmware/rombios/32bit/tcgbios/tcgbios.c
--- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c    Tue Oct 30 11:33:55 
2007 -0600
+++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c    Tue Oct 30 15:34:44 
2007 -0600
@@ -591,7 +591,7 @@ void tcpa_add_measurement(uint32_t pcrIn
        case EV_SEPARATOR:
                tcpa_add_measurement_to_log_simple(pcrIndex,
                                            event_type,
-                                           evt_separator,
+                                           (uint8_t *)evt_separator,
                                            4);
        break;
        case EV_ACTION:
diff -r c17bfb091790 -r a07288a84785 tools/firmware/vgabios/clext.c
--- a/tools/firmware/vgabios/clext.c    Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/firmware/vgabios/clext.c    Tue Oct 30 15:34:44 2007 -0600
@@ -1489,14 +1489,26 @@ cirrus_clear_vram_1:
   mov dx, #0x3ce
   out dx, ax
   push ax
-  mov cx, #0xa000
-  mov es, cx
-  xor di, di
+
+;; Windows Vista appears to be emulating this sequence as part of changing 
+;; screen resolution, but it generates 4096 writes per iteration.
+;; Instead, use a magic register sequence to write the whole bank.
+;;mov cx, #0xa000
+;;mov es, cx
+;;xor di, di
+;;mov ax, si
+;;mov cx, #8192
+;;cld
+;;rep
+;;    stosw
   mov ax, si
-  mov cx, #8192
-  cld
-  rep
-      stosw
+  shl ax, #8
+  mov al, #0xfe
+  out dx, ax   ;; Low byte of value to be written to the bank
+  mov ax, si
+  mov al, #0xff  
+  out dx, ax    ;; High byte and trigger the write
+
   pop ax
   inc ah
   cmp ah, bl
diff -r c17bfb091790 -r a07288a84785 tools/firmware/vmxassist/machine.h
--- a/tools/firmware/vmxassist/machine.h        Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/firmware/vmxassist/machine.h        Tue Oct 30 15:34:44 2007 -0600
@@ -38,10 +38,15 @@
 #define CR4_PSE                (1 << 4)
 #define CR4_PAE                (1 << 5)
 
+#define EFLAGS_CF      (1 << 0)
+#define EFLAGS_PF      (1 << 2)
+#define EFLAGS_AF      (1 << 4)
 #define EFLAGS_ZF      (1 << 6)
+#define EFLAGS_SF      (1 << 7)
 #define EFLAGS_TF      (1 << 8)
 #define EFLAGS_IF      (1 << 9)
 #define EFLAGS_DF      (1 << 10)
+#define EFLAGS_OF      (1 << 11)
 #define EFLAGS_IOPL    (3 << 12)
 #define EFLAGS_VM      ((1 << 17) | EFLAGS_IOPL)
 #define EFLAGS_VIF     (1 << 19)
diff -r c17bfb091790 -r a07288a84785 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/firmware/vmxassist/vm86.c   Tue Oct 30 15:34:44 2007 -0600
@@ -33,6 +33,7 @@
 #define        SEG_SS          0x0020
 #define        SEG_FS          0x0040
 #define        SEG_GS          0x0080
+#define REP            0x0100
 
 static unsigned prev_eip = 0;
 enum vm86_mode mode = 0;
@@ -656,6 +657,108 @@ movr(struct regs *regs, unsigned prefix,
 }
 
 /*
+ * We need to handle string moves that address memory beyond the 64KB segment
+ * limit that VM8086 mode enforces.
+ */
+static inline int
+movs(struct regs *regs, unsigned prefix, unsigned opc)
+{
+       unsigned eip = regs->eip - 1;
+       unsigned sseg = segment(prefix, regs, regs->vds);
+       unsigned dseg = regs->ves;
+       unsigned saddr, daddr;
+       unsigned count = 1;
+       int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
+
+       saddr = address(regs, sseg, regs->esi);
+       daddr = address(regs, dseg, regs->edi);
+
+       if ((prefix & REP) != 0) {
+               count = regs->ecx;
+               regs->ecx = 0;
+       }
+
+       switch (opc) {
+       case 0xA4: /* movsb */
+               regs->esi += (incr * count);
+               regs->edi += (incr * count);
+
+               while (count-- != 0) {
+                       write8(daddr, read8(saddr));
+                       daddr += incr;
+                       saddr += incr;
+               }
+               TRACE((regs, regs->eip - eip, "movsb (%%esi),%%es:(%%edi)"));
+               break;
+
+       case 0xA5: /* movsw */
+               if ((prefix & DATA32) == 0) {
+                       incr = 2 * incr;
+                       regs->esi += (incr * count);
+                       regs->edi += (incr * count);
+
+                       while (count-- != 0) {
+                               write16(daddr, read16(saddr));
+                               daddr += incr;
+                               saddr += incr;
+                       }
+               } else {
+                       incr = 4 * incr;
+                       regs->esi += (incr * count);
+                       regs->edi += (incr * count);
+
+                       while (count-- != 0) {
+                               write32(daddr, read32(saddr));
+                               daddr += incr;
+                               saddr += incr;
+                       }
+               }                       
+               TRACE((regs, regs->eip - eip, "movsw %s(%%esi),%%es:(%%edi)"));
+               break;
+       }
+
+       return 1;
+}
+
+static inline int
+lods(struct regs *regs, unsigned prefix, unsigned opc)
+{
+       unsigned eip = regs->eip - 1;
+       unsigned seg = segment(prefix, regs, regs->vds);
+       unsigned addr = address(regs, seg, regs->esi);
+       unsigned count = 1;
+       int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
+
+       if ((prefix & REP) != 0) {
+               count = regs->ecx;
+               regs->ecx = 0;
+       }
+
+       switch (opc) {
+       case 0xAD: /* lodsw */
+               if ((prefix & DATA32) == 0) {
+                       incr = 2 * incr;
+                       regs->esi += (incr * count);
+                       while (count-- != 0) {
+                               setreg16(regs, 0, read16(addr));
+                               addr += incr;
+                       }
+
+                       TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%ax"));
+               } else {
+                       incr = 4 * incr;
+                       regs->esi += (incr * count);
+                       while (count-- != 0) {
+                               setreg32(regs, 0, read32(addr));
+                               addr += incr;
+                       }
+                       TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%eax"));
+               }
+               break;
+       }
+       return 1;
+}
+/*
  * Move to and from a control register.
  */
 static int
@@ -718,6 +821,55 @@ static inline void set_eflags_ZF(unsigne
                regs->eflags &= ~EFLAGS_ZF;
 }
 
+static void set_eflags_add(unsigned hi_bit_mask, unsigned v1, unsigned v2,
+                               unsigned result, struct regs *regs)
+{
+       int bit_count;
+       unsigned tmp;
+       unsigned full_mask;
+       unsigned nonsign_mask;
+
+       /* Carry out of high order bit? */
+       if ( v1 & v2 & hi_bit_mask )
+               regs->eflags |= EFLAGS_CF;
+       else
+               regs->eflags &= ~EFLAGS_CF;
+
+       /* Even parity in least significant byte? */
+       tmp = result & 0xff;
+       for (bit_count = 0; tmp != 0; bit_count++)
+               tmp &= (tmp - 1);
+
+       if (bit_count & 1)
+               regs->eflags &= ~EFLAGS_PF;
+       else
+               regs->eflags |= EFLAGS_PF;
+
+       /* Carry out of least significant BCD digit? */
+       if ( v1 & v2 & (1<<3) )
+               regs->eflags |= EFLAGS_AF;
+       else
+               regs->eflags &= ~EFLAGS_AF;
+
+       /* Result is zero? */
+       full_mask = (hi_bit_mask - 1) | hi_bit_mask;
+       set_eflags_ZF(full_mask, result, regs);
+
+       /* Sign of result? */
+       if ( result & hi_bit_mask )
+               regs->eflags |= EFLAGS_SF;
+       else
+               regs->eflags &= ~EFLAGS_SF;
+
+       /* Carry out of highest non-sign bit? */
+       nonsign_mask = (hi_bit_mask >> 1) & ~hi_bit_mask;
+       if ( v1 & v2 & hi_bit_mask )
+               regs->eflags |= EFLAGS_OF;
+       else
+               regs->eflags &= ~EFLAGS_OF;
+
+}
+
 /*
  * We need to handle cmp opcodes that address memory beyond the 64KB
  * segment limit that VM8086 mode enforces.
@@ -787,6 +939,82 @@ test(struct regs *regs, unsigned prefix,
 
        /* other test opcodes ... */
        }
+
+       return 1;
+}
+
+/*
+ * We need to handle add opcodes that address memory beyond the 64KB
+ * segment limit that VM8086 mode enforces.
+ */
+static int
+add(struct regs *regs, unsigned prefix, unsigned opc)
+{
+       unsigned eip = regs->eip - 1;
+       unsigned modrm = fetch8(regs);
+       unsigned addr = operand(prefix, regs, modrm);
+       unsigned r = (modrm >> 3) & 7;
+
+       unsigned val1 = 0;
+       unsigned val2 = 0;
+       unsigned result = 0;
+       unsigned hi_bit;
+
+       if ((modrm & 0xC0) == 0xC0) /* no registers */
+               return 0;
+
+       switch (opc) {
+       case 0x00: /* addr32 add r8, r/m8 */
+               val1 = getreg8(regs, r);
+               val2 = read8(addr);
+               result = val1 + val2;
+               write8(addr, result);
+               TRACE((regs, regs->eip - eip,
+                       "addb %%e%s, *0x%x", rnames[r], addr));
+               break;
+               
+       case 0x01: /* addr32 add r16, r/m16 */
+               if (prefix & DATA32) {
+                       val1 = getreg32(regs, r);
+                       val2 = read32(addr);
+                       result = val1 + val2;
+                       write32(addr, result);
+                       TRACE((regs, regs->eip - eip,
+                               "addl %%e%s, *0x%x", rnames[r], addr));
+               } else {
+                       val1 = getreg16(regs, r);
+                       val2 = read16(addr);
+                       result = val1 + val2;
+                       write16(addr, result);
+                       TRACE((regs, regs->eip - eip,
+                               "addw %%e%s, *0x%x", rnames[r], addr));
+               }
+               break;
+               
+       case 0x03: /* addr32 add r/m16, r16 */
+               if (prefix & DATA32) {
+                       val1 = getreg32(regs, r);
+                       val2 = read32(addr);
+                       result = val1 + val2;
+                       setreg32(regs, r, result);
+                       TRACE((regs, regs->eip - eip,
+                               "addl *0x%x, %%e%s", addr, rnames[r]));
+               } else {
+                       val1 = getreg16(regs, r);
+                       val2 = read16(addr);
+                       result = val1 + val2;
+                       setreg16(regs, r, result);
+                       TRACE((regs, regs->eip - eip,
+                               "addw *0x%x, %%%s", addr, rnames[r]));
+               }
+               break;
+       }
+
+       if (opc == 0x00)
+               hi_bit = (1<<7);
+       else
+               hi_bit = (prefix & DATA32) ? (1<<31) : (1<<15);
+       set_eflags_add(hi_bit, val1, val2, result, regs);
 
        return 1;
 }
@@ -1314,6 +1542,18 @@ opcode(struct regs *regs)
 
        for (;;) {
                switch ((opc = fetch8(regs))) {
+
+               case 0x00: /* addr32 add r8, r/m8 */
+               case 0x01: /* addr32 add r16, r/m16 */
+               case 0x03: /* addr32 add r/m16, r16 */
+                       if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
+                               goto invalid;
+                       if ((prefix & ADDR32) == 0)
+                               goto invalid;
+                       if (!add(regs, prefix, opc))
+                               goto invalid;
+                       return OPC_EMULATED;
+                       
                case 0x07: /* pop %es */
                        regs->ves = (prefix & DATA32) ?
                                pop32(regs) : pop16(regs);
@@ -1510,6 +1750,21 @@ opcode(struct regs *regs)
                        return OPC_EMULATED;
                }
 
+               case 0xA4: /* movsb */
+               case 0xA5: /* movsw */
+                       if ((prefix & ADDR32) == 0)
+                               goto invalid;
+                       if (!movs(regs, prefix, opc))
+                               goto invalid;
+                       return OPC_EMULATED;
+
+               case 0xAD: /* lodsw */
+                       if ((prefix & ADDR32) == 0)
+                               goto invalid;
+                       if (!lods(regs, prefix, opc))
+                               goto invalid;
+                       return OPC_EMULATED;
+                       
                case 0xBB: /* mov bx, imm16 */
                {
                        int data;
@@ -1627,6 +1882,11 @@ opcode(struct regs *regs)
                        /* Do something power-saving here! */
                        return OPC_EMULATED;
 
+               case 0xF3: /* rep/repe/repz */
+                       TRACE((regs, regs->eip - eip, "rep"));
+                       prefix |= REP;
+                       continue;
+
                case 0xF6: /* addr32 testb $imm, r/m8 */
                        if (!(prefix & ADDR32))
                                goto invalid;
@@ -1660,6 +1920,7 @@ emulate(struct regs *regs)
 {
        unsigned flteip;
        int nemul = 0;
+       unsigned ip;
 
        /* emulate as many instructions as possible */
        while (opcode(regs) != OPC_INVALID)
@@ -1668,6 +1929,12 @@ emulate(struct regs *regs)
        /* detect the case where we are not making progress */
        if (nemul == 0 && prev_eip == regs->eip) {
                flteip = address(regs, MASK16(regs->cs), regs->eip);
+
+               printf("Undecoded sequence: \n");
+               for (ip=flteip; ip < flteip+16; ip++)
+                       printf("0x%02x ", read8(ip));
+               printf("\n");
+
                panic("Unknown opcode at %04x:%04x=0x%x",
                        MASK16(regs->cs), regs->eip, flteip);
        } else
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target       Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/Makefile.target       Tue Oct 30 15:34:44 2007 -0600
@@ -387,6 +387,11 @@ endif
 endif
 AUDIODRV+= wavcapture.o
 
+ifdef CONFIG_VNC_TLS
+CPPFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
+LIBS += $(CONFIG_VNC_TLS_LIBS)
+endif
+
 # SCSI layer
 VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
 
@@ -409,6 +414,10 @@ VL_OBJS+= piix4acpi.o
 VL_OBJS+= piix4acpi.o
 VL_OBJS+= xenstore.o
 VL_OBJS+= xen_platform.o
+VL_OBJS+= xen_machine_fv.o
+VL_OBJS+= xen_machine_pv.o
+VL_OBJS+= xenfb.o
+VL_OBJS+= xen_console.o
 VL_OBJS+= tpm_tis.o
 CPPFLAGS += -DHAS_AUDIO
 endif
@@ -452,8 +461,7 @@ ifdef CONFIG_SDL
 ifdef CONFIG_SDL
 VL_OBJS+=sdl.o x_keymap.o
 endif
-VL_OBJS+=vnc.o
-VL_OBJS+=d3des.o
+VL_OBJS+=vnc.o d3des.o
 ifdef CONFIG_COCOA
 VL_OBJS+=cocoa.o
 COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
@@ -511,11 +519,8 @@ sdl.o: sdl.c keymaps.c sdl_keysym.h
 sdl.o: sdl.c keymaps.c sdl_keysym.h
        $(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
 
-vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h
+vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
        $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-
-d3des.o: d3des.c d3des.h
-       $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
 
 sdlaudio.o: sdlaudio.c
        $(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) $(BASE_CFLAGS) -c -o $@ $<
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/configure
--- a/tools/ioemu/configure     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/configure     Tue Oct 30 15:34:44 2007 -0600
@@ -87,6 +87,7 @@ fmod="no"
 fmod="no"
 fmod_lib=""
 fmod_inc=""
+vnc_tls="yes"
 bsd="no"
 linux="no"
 kqemu="no"
@@ -225,6 +226,8 @@ for opt do
   ;;
   --fmod-inc=*) fmod_inc="$optarg"
   ;;
+  --disable-vnc-tls) vnc_tls="no"
+  ;;
   --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" ; user="no"
   ;;
   --disable-slirp) slirp="no"
@@ -292,6 +295,7 @@ echo "  --enable-alsa            enable 
 echo "  --enable-alsa            enable ALSA audio driver"
 echo "  --enable-fmod            enable FMOD audio driver"
 echo "  --enabled-dsound         enable DirectSound audio driver"
+echo "  --disable-vnc-tls        disable TLS encryption for VNC server"
 echo "  --enable-system          enable all system emulation targets"
 echo "  --disable-system         disable all system emulation targets"
 echo "  --enable-linux-user      enable all linux usermode emulation targets"
@@ -410,6 +414,18 @@ if test "$solaris" = "yes" ; then
   fi
 fi 
 
+##########################################
+
+# VNC TLS detection
+if test "$vnc_tls" = "yes" ; then
+  `pkg-config gnutls` || vnc_tls="no"
+fi
+if test "$vnc_tls" = "yes" ; then
+  vnc_tls_cflags=`pkg-config --cflags gnutls`
+  vnc_tls_libs=`pkg-config --libs gnutls`
+fi
+
+##########################################
 
 if test -z "$target_list" ; then
 # these targets are portable
@@ -771,6 +787,12 @@ if test "$fmod" = "yes" ; then
   echo "CONFIG_FMOD_LIB=$fmod_lib" >> $config_mak
   echo "CONFIG_FMOD_INC=$fmod_inc" >> $config_mak
   echo "#define CONFIG_FMOD 1" >> $config_h
+fi
+if test "$vnc_tls" = "yes" ; then
+  echo "CONFIG_VNC_TLS=yes" >> $config_mak
+  echo "CONFIG_VNC_TLS_CFLAGS=$vnc_tls_cflags" >> $config_mak
+  echo "CONFIG_VNC_TLS_LIBS=$vnc_tls_libs" >> $config_mak
+  echo "#define CONFIG_VNC_TLS 1" >> $config_h
 fi
 qemu_version=`head $source_path/VERSION`
 echo "VERSION=$qemu_version" >>$config_mak
@@ -999,4 +1021,10 @@ if test "$source_path_used" = "yes" ; th
     done
 fi
 
+echo "VNC TLS support   $vnc_tls"
+if test "$vnc_tls" = "yes" ; then
+    echo "    TLS CFLAGS    $vnc_tls_cflags"
+    echo "    TLS LIBS      $vnc_tls_libs"
+fi
+
 rm -f $TMPO $TMPC $TMPE $TMPS
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/hw/cirrus_vga.c       Tue Oct 30 15:34:44 2007 -0600
@@ -294,6 +294,7 @@ void *shared_vram;
 
 static void cirrus_bitblt_reset(CirrusVGAState *s);
 static void cirrus_update_memory_access(CirrusVGAState *s);
+static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, 
uint32_t val);
 
 /***************************************
  *
@@ -1497,6 +1498,17 @@ cirrus_hook_write_gr(CirrusVGAState * s,
     case 0x31:                 // BLT STATUS/START
        cirrus_write_bitblt(s, reg_value);
        break;
+
+       // Extension to allow BIOS to clear 16K VRAM bank in one operation
+    case 0xFE:
+       s->gr[reg_index] = reg_value;  // Lower byte of value to be written
+       break;
+    case 0xFF: {
+       target_phys_addr_t addr;
+       for (addr = 0xa0000; addr < 0xa4000; addr += 2)
+           cirrus_vga_mem_writew(s, addr, (reg_value << 8) | s->gr[0xFE]);
+       }
+       break;
     default:
 #ifdef DEBUG_CIRRUS
        printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/xen_console.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xen_console.c      Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,432 @@
+/*
+ *  Copyright (C) International Business Machines  Corp., 2005
+ *  Author(s): Anthony Liguori <aliguori@xxxxxxxxxx>
+ *
+ *  Copyright (C) Red Hat 2007
+ *
+ *  Xen Console
+ *
+ *  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; under version 2 of the License.
+ * 
+ *  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 <malloc.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+#include <xs.h>
+#include <xen/io/console.h>
+#include <xenctrl.h>
+
+#include "vl.h"
+
+#include "xen_console.h"
+
+#define dolog(val, fmt, ...) fprintf(stderr, fmt "\n", ## __VA_ARGS__)
+
+struct buffer
+{
+       uint8_t *data;
+       size_t consumed;
+       size_t size;
+       size_t capacity;
+       size_t max_capacity;
+};
+
+struct domain
+{
+       int domid;
+       struct buffer buffer;
+
+       char *conspath;
+       char *serialpath;
+       int use_consolepath;
+       int ring_ref;
+       evtchn_port_t local_port;
+       evtchn_port_t remote_port;
+       int xce_handle;
+       struct xs_handle *xsh;
+       struct xencons_interface *interface;
+       CharDriverState *chr;
+};
+
+
+static void buffer_append(struct domain *dom)
+{
+       struct buffer *buffer = &dom->buffer;
+       XENCONS_RING_IDX cons, prod, size;
+       struct xencons_interface *intf = dom->interface;
+
+       cons = intf->out_cons;
+       prod = intf->out_prod;
+       mb();
+
+       size = prod - cons;
+       if ((size == 0) || (size > sizeof(intf->out)))
+               return;
+
+       if ((buffer->capacity - buffer->size) < size) {
+               buffer->capacity += (size + 1024);
+               buffer->data = realloc(buffer->data, buffer->capacity);
+               if (buffer->data == NULL) {
+                       dolog(LOG_ERR, "Memory allocation failed");
+                       exit(ENOMEM);
+               }
+       }
+
+       while (cons != prod)
+               buffer->data[buffer->size++] = intf->out[
+                       MASK_XENCONS_IDX(cons++, intf->out)];
+
+       mb();
+       intf->out_cons = cons;
+       xc_evtchn_notify(dom->xce_handle, dom->local_port);
+
+       if (buffer->max_capacity &&
+           buffer->size > buffer->max_capacity) {
+               /* Discard the middle of the data. */
+
+               size_t over = buffer->size - buffer->max_capacity;
+               uint8_t *maxpos = buffer->data + buffer->max_capacity;
+
+               memmove(maxpos - over, maxpos, over);
+               buffer->data = realloc(buffer->data, buffer->max_capacity);
+               buffer->size = buffer->capacity = buffer->max_capacity;
+
+               if (buffer->consumed > buffer->max_capacity - over)
+                       buffer->consumed = buffer->max_capacity - over;
+       }
+}
+
+static void buffer_advance(struct buffer *buffer, size_t len)
+{
+       buffer->consumed += len;
+       if (buffer->consumed == buffer->size) {
+               buffer->consumed = 0;
+               buffer->size = 0;
+       }
+}
+
+/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
+int xs_gather(struct xs_handle *xs, const char *dir, ...)
+{
+       va_list ap;
+       const char *name;
+       char *path;
+       int ret = 0;
+
+       va_start(ap, dir);
+       while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
+               const char *fmt = va_arg(ap, char *);
+               void *result = va_arg(ap, void *);
+               char *p;
+
+               if (asprintf(&path, "%s/%s", dir, name) == -1) {
+                       ret = ENOMEM;
+                       break;
+               }
+               p = xs_read(xs, XBT_NULL, path, NULL);
+               free(path);
+               if (p == NULL) {
+                       ret = ENOENT;
+                       break;
+               }
+               if (fmt) {
+                       if (sscanf(p, fmt, result) == 0)
+                               ret = EINVAL;
+                       free(p);
+               } else
+                       *(char **)result = p;
+       }
+       va_end(ap);
+       return ret;
+}
+
+static int domain_create_ring(struct domain *dom)
+{
+       int err, remote_port, ring_ref, rc;
+
+       err = xs_gather(dom->xsh, dom->serialpath,
+                       "ring-ref", "%u", &ring_ref,
+                       "port", "%i", &remote_port,
+                       NULL);
+       if (err) {
+               err = xs_gather(dom->xsh, dom->conspath,
+                               "ring-ref", "%u", &ring_ref,
+                               "port", "%i", &remote_port,
+                               NULL);
+               if (err) {
+                       fprintf(stderr, "Console: failed to find ring-ref/port 
yet\n");
+                       goto out;
+               }
+               dom->use_consolepath = 1;
+       } else
+               dom->use_consolepath = 0;
+       fprintf(stderr, "Console: got ring-ref %d port %d\n", ring_ref, 
remote_port);
+
+       if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
+               goto out;
+
+       if (ring_ref != dom->ring_ref) {
+               if (dom->interface != NULL)
+                       munmap(dom->interface, getpagesize());
+               dom->interface = xc_map_foreign_range(
+                       xc_handle, dom->domid, getpagesize(),
+                       PROT_READ|PROT_WRITE,
+                       (unsigned long)ring_ref);
+               if (dom->interface == NULL) {
+                       err = errno;
+                       goto out;
+               }
+               dom->ring_ref = ring_ref;
+       }
+
+       dom->local_port = -1;
+       dom->remote_port = -1;
+
+       dom->xce_handle = xc_evtchn_open();
+       if (dom->xce_handle == -1) {
+               err = errno;
+               goto out;
+       }
+
+       rc = xc_evtchn_bind_interdomain(dom->xce_handle,
+               dom->domid, remote_port);
+
+       if (rc == -1) {
+               err = errno;
+               xc_evtchn_close(dom->xce_handle);
+               dom->xce_handle = -1;
+               goto out;
+       }
+       dom->local_port = rc;
+       dom->remote_port = remote_port;
+
+ out:
+       return err;
+}
+
+
+static struct domain *create_domain(int domid, CharDriverState *chr)
+{
+       struct domain *dom;
+       char *s;
+
+       dom = (struct domain *)malloc(sizeof(struct domain));
+       if (dom == NULL) {
+               dolog(LOG_ERR, "Out of memory %s:%s():L%d",
+                     __FILE__, __FUNCTION__, __LINE__);
+               exit(ENOMEM);
+       }
+
+       dom->domid = domid;
+       dom->chr = chr;
+
+       dom->xsh = xs_daemon_open();
+       if (dom->xsh == NULL) {
+               fprintf(logfile, "Could not contact xenstore for console 
watch\n");
+               goto out;
+       }
+
+       dom->serialpath = xs_get_domain_path(dom->xsh, dom->domid);
+       s = realloc(dom->serialpath, strlen(dom->serialpath) +
+                   strlen("/serial/0") + 1);
+       if (s == NULL)
+               goto out;
+       dom->serialpath = s;
+       strcat(dom->serialpath, "/serial/0");
+
+       dom->conspath = xs_get_domain_path(dom->xsh, dom->domid);
+       s = realloc(dom->conspath, strlen(dom->conspath) +
+                   strlen("/console") + 1);
+       if (s == NULL)
+               goto out;
+       dom->conspath = s;
+       strcat(dom->conspath, "/console");
+
+       dom->buffer.data = 0;
+       dom->buffer.consumed = 0;
+       dom->buffer.size = 0;
+       dom->buffer.capacity = 0;
+       dom->buffer.max_capacity = 0;
+
+       dom->ring_ref = -1;
+       dom->local_port = -1;
+       dom->remote_port = -1;
+       dom->interface = NULL;
+       dom->xce_handle = -1;
+
+
+       return dom;
+ out:
+       free(dom->serialpath);
+       free(dom->conspath);
+       free(dom);
+       return NULL;
+}
+
+
+static int ring_free_bytes(struct domain *dom)
+{
+       struct xencons_interface *intf = dom->interface;
+       XENCONS_RING_IDX cons, prod, space;
+
+       cons = intf->in_cons;
+       prod = intf->in_prod;
+       mb();
+
+       space = prod - cons;
+       if (space > sizeof(intf->in))
+               return 0; /* ring is screwed: ignore it */
+
+       return (sizeof(intf->in) - space);
+}
+
+static int xencons_can_receive(void *opaque)
+{
+       struct domain *dom = (struct domain *)opaque;
+
+       return ring_free_bytes(dom);
+}
+
+static void xencons_receive(void *opaque, const uint8_t *buf, int len)
+{
+       struct domain *dom = (struct domain *)opaque;
+       int i, max;
+       struct xencons_interface *intf = dom->interface;
+       XENCONS_RING_IDX prod;
+
+       max = ring_free_bytes(dom);
+       /* The can_receive() func limits this, but check again anyway */
+       if (max < len)
+               len = max;
+
+       prod = intf->in_prod;
+       for (i = 0; i < len; i++) {
+               intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
+                       buf[i];
+       }
+       wmb();
+       intf->in_prod = prod;
+       xc_evtchn_notify(dom->xce_handle, dom->local_port);
+}
+
+static void xencons_send(struct domain *dom)
+{
+       ssize_t len;
+       len = qemu_chr_write(dom->chr, dom->buffer.data + dom->buffer.consumed,
+                            dom->buffer.size - dom->buffer.consumed);
+       if (len < 1) {
+               /*
+                * Disable log because if we're redirecting to /dev/pts/N we
+                * don't want to flood logs when no client has the PTY open
+                */
+               /*
+               dolog(LOG_DEBUG, "Write failed on domain %d: %zd, %d\n",
+                     dom->domid, len, errno);
+               */
+       } else {
+               buffer_advance(&dom->buffer, len);
+       }
+}
+
+static void xencons_ring_read(void *opaque)
+{
+       evtchn_port_t port;
+       struct domain *dom = (struct domain *)opaque;
+
+       if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
+               return;
+
+       buffer_append(dom);
+
+       (void)xc_evtchn_unmask(dom->xce_handle, port);
+
+       if (dom->buffer.size - dom->buffer.consumed)
+               xencons_send(dom);
+}
+
+static void xencons_startup(void *opaque)
+{
+       struct domain *dom = (struct domain *)opaque;
+       unsigned dummy;
+       char **vec;
+       int err;
+       vec = xs_read_watch(dom->xsh, &dummy);
+       if (vec)
+               free(vec);
+       fprintf(stderr, "Console: got watch\n");
+       err = domain_create_ring(dom);
+       if (err)
+               return;
+
+       xs_unwatch(dom->xsh, dom->conspath, "");
+       xs_unwatch(dom->xsh, dom->serialpath, "");
+       qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, NULL, NULL, NULL);
+
+       fprintf(stderr, "Console: connected to guest frontend\n");
+       if (qemu_set_fd_handler2(dom->xce_handle, NULL, xencons_ring_read, 
NULL, dom) < 0)
+               return;
+
+       qemu_chr_add_handlers(dom->chr, xencons_can_receive, xencons_receive,
+                             NULL, dom);
+}
+
+
+int xencons_init(int domid, CharDriverState *chr)
+{
+       struct domain *dom = create_domain(domid, chr);
+
+       if (!dom)
+               return -1;
+
+       /* Setup watches so we asynchronously connect to serial console */
+       if (!(xs_watch(dom->xsh, dom->conspath, ""))) {
+               fprintf(stderr, "Unable to watch console %s\n", dom->conspath);
+               goto fail;
+       }
+       if (!(xs_watch(dom->xsh, dom->serialpath, ""))) {
+               fprintf(stderr, "Unable to watch console %s\n", dom->conspath);
+               xs_unwatch(dom->xsh, dom->conspath, "");
+               goto fail;
+       }
+       qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, xencons_startup, NULL, 
dom);
+       fprintf(stderr, "Console: prepared domain, waiting for ringref at %s or 
%s\n",
+               dom->conspath, dom->serialpath);
+
+       return 0;
+
+fail:
+       xs_daemon_close(dom->xsh);
+       free(dom->serialpath);
+       free(dom->conspath);
+       free(dom);
+       return -1;
+}
+
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/xen_console.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xen_console.h      Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (C) International Business Machines  Corp., 2005
+ *  Author(s): Anthony Liguori <aliguori@xxxxxxxxxx>
+ *
+ *  Copyright (C) Red Hat 2007
+ *
+ *  Xen Console
+ *
+ *  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; under version 2 of the License.
+ * 
+ *  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 "vl.h"
+
+extern int xencons_init(int domid, CharDriverState *chr);
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/xen_machine_fv.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xen_machine_fv.c   Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,296 @@
+/*
+ * QEMU Xen FV Machine
+ *
+ * Copyright (c) 2003-2007 Fabrice Bellard
+ * Copyright (c) 2007 Red Hat
+ *
+ * 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.
+ */
+
+#include "vl.h"
+#include <xen/hvm/params.h>
+#include <sys/mman.h>
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE XC_PAGE_SIZE
+#endif
+#ifndef PAGE_SHIFT
+#define PAGE_SHIFT XC_PAGE_SHIFT
+#endif
+
+#if defined(MAPCACHE)
+
+#if defined(__i386__) 
+#define MAX_MCACHE_SIZE    0x40000000 /* 1GB max for x86 */
+#define MCACHE_BUCKET_SHIFT 16
+#elif defined(__x86_64__)
+#define MAX_MCACHE_SIZE    0x1000000000 /* 64GB max for x86_64 */
+#define MCACHE_BUCKET_SHIFT 20
+#endif
+
+#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
+
+#define BITS_PER_LONG (sizeof(long)*8)
+#define BITS_TO_LONGS(bits) \
+    (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
+#define DECLARE_BITMAP(name,bits) \
+    unsigned long name[BITS_TO_LONGS(bits)]
+#define test_bit(bit,map) \
+    (!!((map)[(bit)/BITS_PER_LONG] & (1UL << ((bit)%BITS_PER_LONG))))
+
+struct map_cache {
+    unsigned long paddr_index;
+    uint8_t      *vaddr_base;
+    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>PAGE_SHIFT);
+};
+
+static struct map_cache *mapcache_entry;
+static unsigned long nr_buckets;
+
+/* For most cases (>99.9%), the page address is the same. */
+static unsigned long last_address_index = ~0UL;
+static uint8_t      *last_address_vaddr;
+
+static int qemu_map_cache_init(void)
+{
+    unsigned long size;
+
+    nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
+                   (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
+                  (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
+
+    /*
+     * Use mmap() directly: lets us allocate a big hash table with no up-front
+     * cost in storage space. The OS will allocate memory only for the buckets
+     * that we actually use. All others will contain all zeroes.
+     */
+    size = nr_buckets * sizeof(struct map_cache);
+    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx size %lu\n", 
nr_buckets, size);
+    mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
+                          MAP_SHARED|MAP_ANON, -1, 0);
+    if (mapcache_entry == MAP_FAILED) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    return 0;
+}
+
+static void qemu_remap_bucket(struct map_cache *entry,
+                              unsigned long address_index)
+{
+    uint8_t *vaddr_base;
+    unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
+    unsigned int i, j;
+
+    if (entry->vaddr_base != NULL) {
+        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
+        if (errno) {
+            fprintf(logfile, "unmap fails %d\n", errno);
+            exit(-1);
+        }
+    }
+
+    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++)
+        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i;
+
+    vaddr_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE,
+                                      pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT);
+    if (vaddr_base == NULL) {
+        fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
+        exit(-1);
+    }
+
+    entry->vaddr_base  = vaddr_base;
+    entry->paddr_index = address_index;
+
+    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i += BITS_PER_LONG) {
+        unsigned long word = 0;
+        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
+            (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
+        while (j > 0)
+            word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
+        entry->valid_mapping[i / BITS_PER_LONG] = word;
+    }
+}
+
+uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
+{
+    struct map_cache *entry;
+    unsigned long address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
+
+    if (address_index == last_address_index)
+        return last_address_vaddr + address_offset;
+
+    entry = &mapcache_entry[address_index % nr_buckets];
+
+    if (entry->vaddr_base == NULL || entry->paddr_index != address_index ||
+        !test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
+        qemu_remap_bucket(entry, address_index);
+
+    if (!test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
+        return NULL;
+
+    last_address_index = address_index;
+    last_address_vaddr = entry->vaddr_base;
+
+    return last_address_vaddr + address_offset;
+}
+
+void qemu_invalidate_map_cache(void)
+{
+    unsigned long i;
+
+    mapcache_lock();
+
+    for (i = 0; i < nr_buckets; i++) {
+        struct map_cache *entry = &mapcache_entry[i];
+
+        if (entry->vaddr_base == NULL)
+            continue;
+
+        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
+        if (errno) {
+            fprintf(logfile, "unmap fails %d\n", errno);
+            exit(-1);
+        }
+
+        entry->paddr_index = 0;
+        entry->vaddr_base  = NULL;
+    }
+
+    last_address_index =  ~0UL;
+    last_address_vaddr = NULL;
+
+    mapcache_unlock();
+}
+
+#endif /* defined(MAPCACHE) */
+
+
+static void xen_init_fv(uint64_t ram_size, int vga_ram_size, char *boot_device,
+                        DisplayState *ds, const char **fd_filename,
+                        int snapshot,
+                        const char *kernel_filename,
+                        const char *kernel_cmdline,
+                        const char *initrd_filename,
+                        const char *direct_pci)
+{
+    unsigned long ioreq_pfn;
+    extern void *shared_page;
+    extern void *buffered_io_page;
+#ifdef __ia64__
+    unsigned long nr_pages;
+    xen_pfn_t *page_array;
+    extern void *buffered_pio_page;
+    int i;
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+
+    if (qemu_map_cache_init()) {
+        fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
+        exit(-1);
+    }
+
+    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
+    fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
+    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                       PROT_READ|PROT_WRITE, ioreq_pfn);
+    if (shared_page == NULL) {
+        fprintf(logfile, "map shared IO page returned error %d\n", errno);
+        exit(-1);
+    }
+
+    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
+    fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
+    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                            PROT_READ|PROT_WRITE, ioreq_pfn);
+    if (buffered_io_page == NULL) {
+        fprintf(logfile, "map buffered IO page returned error %d\n", errno);
+        exit(-1);
+    }
+
+#elif defined(__ia64__)
+
+    nr_pages = ram_size/PAGE_SIZE;
+
+    page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
+    if (page_array == NULL) {
+        fprintf(logfile, "malloc returned error %d\n", errno);
+        exit(-1);
+    }
+
+    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                       PROT_READ|PROT_WRITE,
+                                       IO_PAGE_START >> PAGE_SHIFT);
+
+    buffered_io_page =xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                       PROT_READ|PROT_WRITE,
+                                       BUFFER_IO_PAGE_START >> PAGE_SHIFT);
+
+    buffered_pio_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                       PROT_READ|PROT_WRITE,
+                                       BUFFER_PIO_PAGE_START >> PAGE_SHIFT);
+
+    for (i = 0; i < nr_pages; i++)
+        page_array[i] = i;
+       
+    /* VTI will not use memory between 3G~4G, so we just pass a legal pfn
+       to make QEMU map continuous virtual memory space */
+    if (ram_size > MMIO_START) {       
+        for (i = 0 ; i < (MEM_G >> PAGE_SHIFT); i++)
+            page_array[(MMIO_START >> PAGE_SHIFT) + i] =
+                (STORE_PAGE_START >> PAGE_SHIFT); 
+    }
+
+    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
+                                         PROT_READ|PROT_WRITE,
+                                         page_array, nr_pages);
+    if (phys_ram_base == 0) {
+        fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
+        exit(-1);
+    }
+    free(page_array);
+#endif
+
+    timeoffset_get();
+
+
+    pc_machine.init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
+                    snapshot, kernel_filename, kernel_cmdline, initrd_filename,
+                    direct_pci);
+}
+
+QEMUMachine xenfv_machine = {
+    "xenfv",
+    "Xen Fully-virtualized PC",
+    xen_init_fv,
+};
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/xen_machine_pv.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xen_machine_pv.c   Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,73 @@
+/*
+ * QEMU Xen PV Machine
+ *
+ * Copyright (c) 2007 Red Hat
+ *
+ * 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.
+ */
+
+#include "vl.h"
+#include "xen_console.h"
+#include "xenfb.h"
+
+/* The Xen PV machine currently provides
+ *   - a virtual framebuffer
+ *   - ....
+ */
+static void xen_init_pv(uint64_t ram_size, int vga_ram_size, char *boot_device,
+                       DisplayState *ds, const char **fd_filename,
+                       int snapshot,
+                       const char *kernel_filename,
+                       const char *kernel_cmdline,
+                       const char *initrd_filename)
+{
+    struct xenfb *xenfb;
+    extern int domid;
+
+    /* Connect to text console */
+    if (serial_hds[0]) {
+        if (xencons_init(domid, serial_hds[0]) < 0) {
+            fprintf(stderr, "Could not connect to domain console\n");
+            exit(1);
+        }
+    }
+
+    /* Prepare PVFB state */
+    xenfb = xenfb_new(domid, ds);
+    if (xenfb == NULL) {
+        fprintf(stderr, "Could not create framebuffer (%s)\n",
+                strerror(errno));
+        exit(1);
+    }
+}
+
+QEMUMachine xenpv_machine = {
+    "xenpv",
+    "Xen Para-virtualized PC",
+    xen_init_pv,
+};
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/xen_platform.c
--- a/tools/ioemu/hw/xen_platform.c     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/hw/xen_platform.c     Tue Oct 30 15:34:44 2007 -0600
@@ -36,14 +36,24 @@ static void platform_ioport_map(PCIDevic
 
 static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
 {
-    fprintf(logfile, "Warning: try read from xen platform mmio space\n");
+    static int warnings = 0;
+    if (warnings < 5) {
+           fprintf(logfile, "Warning: attempted read from physical address "
+                   "0x%lx in xen platform mmio space\n", addr);
+           warnings++;
+    }
     return 0;
 }
 
 static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
                               uint32_t val)
 {
-    fprintf(logfile, "Warning: try write to xen platform mmio space\n");
+    static int warnings = 0;
+    if (warnings < 5) {
+           fprintf(logfile, "Warning: attempted write of 0x%x to physical "
+                   "address 0x%lx in xen platform mmio space\n", val, addr);
+           warnings++;
+    }
     return;
 }
 
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/xenfb.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xenfb.c    Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,1157 @@
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <xenctrl.h>
+#include <xen/io/xenbus.h>
+#include <xen/io/fbif.h>
+#include <xen/io/kbdif.h>
+#include <xen/io/protocols.h>
+#include <stdbool.h>
+#include <xen/event_channel.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <xs.h>
+#include <linux/input.h>
+
+#include "xenfb.h"
+
+// FIXME defend against malicious frontend?
+
+struct xenfb;
+
+struct xenfb_device {
+       const char *devicetype;
+       char nodename[64];      /* backend xenstore dir */
+       char otherend[64];      /* frontend xenstore dir */
+       int otherend_id;        /* frontend domid */
+       enum xenbus_state state; /* backend state */
+       void *page;             /* shared page */
+       evtchn_port_t port;
+       struct xenfb *xenfb;
+};
+
+struct xenfb {
+       DisplayState *ds;       /* QEMU graphical console state */
+       int evt_xch;            /* event channel driver handle */
+       int xc;                 /* hypervisor interface handle */
+       struct xs_handle *xsh;  /* xs daemon handle */
+       struct xenfb_device fb, kbd;
+       void *pixels;           /* guest framebuffer data */
+       size_t fb_len;          /* size of framebuffer */
+       int row_stride;         /* width of one row in framebuffer */
+       int depth;              /* colour depth of guest framebuffer */
+       int width;              /* pixel width of guest framebuffer */
+       int height;             /* pixel height of guest framebuffer */
+       int abs_pointer_wanted; /* Whether guest supports absolute pointer */
+       int button_state;       /* Last seen pointer button state */
+       char protocol[64];      /* frontend protocol */
+};
+
+/* Functions for frontend/backend state machine*/
+static int xenfb_wait_for_frontend(struct xenfb_device *dev, IOHandler 
*handler);
+static int xenfb_wait_for_backend(struct xenfb_device *dev, IOHandler 
*handler);
+static void xenfb_backend_created_kbd(void *opaque);
+static void xenfb_backend_created_fb(void *opaque);
+static void xenfb_frontend_initialized_kbd(void *opaque);
+static void xenfb_frontend_initialized_fb(void *opaque);
+static void xenfb_frontend_connected_kbd(void *opaque);
+
+/* Helper functions for checking state of frontend/backend devices */
+static int xenfb_frontend_connected(struct xenfb_device *dev);
+static int xenfb_frontend_initialized(struct xenfb_device *dev);
+static int xenfb_backend_created(struct xenfb_device *dev);
+
+/* Functions which tie the PVFB into the QEMU device model */
+static void xenfb_key_event(void *opaque, int keycode);
+static void xenfb_mouse_event(void *opaque,
+                             int dx, int dy, int dz, int button_state);
+static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h);
+static void xenfb_update(void *opaque);
+static void xenfb_invalidate(void *opaque);
+static void xenfb_screen_dump(void *opaque, const char *name);
+static int xenfb_register_console(struct xenfb *xenfb);
+
+/*
+ * Tables to map from scancode to Linux input layer keycode.
+ * Scancodes are hardware-specific.  These maps assumes a 
+ * standard AT or PS/2 keyboard which is what QEMU feeds us.
+ */
+static const unsigned char atkbd_set2_keycode[512] = {
+
+         0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
+         0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
+         0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
+         0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
+         0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
+         0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
+         0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
+        82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
+
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+       217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
+       173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
+       159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
+       157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
+       226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
+       110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
+
+};
+
+static const unsigned char atkbd_unxlate_table[128] = {
+
+         0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
+        21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
+        35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
+        50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
+        11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
+       114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
+        71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
+        19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
+
+};
+
+static unsigned char scancode2linux[512];
+
+static int xenfb_xs_scanf1(struct xs_handle *xsh,
+                          const char *dir, const char *node,
+                          const char *fmt, void *dest)
+{
+       char buf[1024];
+       char *p;
+       int ret;
+
+       if (snprintf(buf, sizeof(buf), "%s/%s", dir, node) >= sizeof(buf)) {
+               errno = ENOENT;
+               return -1;
+        }
+       p = xs_read(xsh, XBT_NULL, buf, NULL);
+       if (!p) {
+               errno = ENOENT;
+               return -1;
+        }
+       ret = sscanf(p, fmt, dest);
+       free(p);
+       if (ret != 1) {
+               errno = EDOM;
+               return -1;
+        }
+       return ret;
+}
+
+static int xenfb_xs_printf(struct xs_handle *xsh,
+                          const char *dir, const char *node, char *fmt, ...)
+{
+       va_list ap;
+       char key[1024];
+       char val[1024];
+       int n;
+
+       if (snprintf(key, sizeof(key), "%s/%s", dir, node) >= sizeof(key)) {
+               errno = ENOENT;
+               return -1;
+        }
+
+       va_start(ap, fmt);
+       n = vsnprintf(val, sizeof(val), fmt, ap);
+       va_end(ap);
+       if (n >= sizeof(val)) {
+               errno = ENOSPC; /* close enough */
+               return -1;
+       }
+
+       if (!xs_write(xsh, XBT_NULL, key, val, n))
+               return -1;
+       return 0;
+}
+
+static void xenfb_device_init(struct xenfb_device *dev,
+                             const char *type,
+                             struct xenfb *xenfb)
+{
+       dev->devicetype = type;
+       dev->otherend_id = -1;
+       dev->port = -1;
+       dev->xenfb = xenfb;
+}
+
+static char *xenfb_path_in_dom(struct xs_handle *xsh,
+                               char *buf, size_t size,
+                               unsigned domid, const char *fmt, ...)
+{
+        va_list ap;
+        char *domp = xs_get_domain_path(xsh, domid);
+        int n;
+
+        if (domp == NULL)
+                return NULL;
+
+        n = snprintf(buf, size, "%s/", domp);
+        free(domp);
+        if (n >= size)
+                return NULL;
+
+        va_start(ap, fmt);
+        n += vsnprintf(buf + n, size - n, fmt, ap);
+        va_end(ap);
+        if (n >= size)
+                return NULL;
+
+        return buf;
+}
+
+static int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
+{
+        dev->otherend_id = domid;
+
+        if (!xenfb_path_in_dom(dev->xenfb->xsh,
+                               dev->otherend, sizeof(dev->otherend),
+                               domid, "device/%s/0", dev->devicetype)) {
+                errno = ENOENT;
+                return -1;
+        }
+        if (!xenfb_path_in_dom(dev->xenfb->xsh,
+                               dev->nodename, sizeof(dev->nodename),
+                               0, "backend/%s/%d/0", dev->devicetype, domid)) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        return 0;
+}
+
+struct xenfb *xenfb_new(int domid, DisplayState *ds)
+{
+       struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
+       int serrno;
+       int i;
+
+       if (xenfb == NULL)
+               return NULL;
+
+       /* Prepare scancode mapping table */
+       for (i = 0; i < 128; i++) {
+               scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
+               scancode2linux[i | 0x80] = 
+                       atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
+       }
+
+       memset(xenfb, 0, sizeof(*xenfb));
+       xenfb->evt_xch = xenfb->xc = -1;
+       xenfb_device_init(&xenfb->fb, "vfb", xenfb);
+       xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
+
+       xenfb->evt_xch = xc_evtchn_open();
+       if (xenfb->evt_xch == -1)
+               goto fail;
+
+       xenfb->xc = xc_interface_open();
+       if (xenfb->xc == -1)
+               goto fail;
+
+       xenfb->xsh = xs_daemon_open();
+       if (!xenfb->xsh)
+               goto fail;
+
+       xenfb->ds = ds;
+       xenfb_device_set_domain(&xenfb->fb, domid);
+       xenfb_device_set_domain(&xenfb->kbd, domid);
+
+       fprintf(stderr, "FB: Waiting for KBD backend creation\n");
+       xenfb_wait_for_backend(&xenfb->kbd, xenfb_backend_created_kbd);
+
+       return xenfb;
+
+ fail:
+       serrno = errno;
+       xenfb_shutdown(xenfb);
+       errno = serrno;
+       return NULL;
+}
+
+
+static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
+                                         const char *dir)
+{
+       int ret, state;
+
+       ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
+       if (ret < 0)
+               return XenbusStateUnknown;
+
+       if ((unsigned)state > XenbusStateClosed)
+               state = XenbusStateUnknown;
+       return state;
+}
+
+static int xenfb_switch_state(struct xenfb_device *dev,
+                             enum xenbus_state state)
+{
+       struct xs_handle *xsh = dev->xenfb->xsh;
+
+       if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
+               return -1;
+       dev->state = state;
+       return 0;
+}
+
+
+static int xenfb_hotplug(struct xenfb_device *dev)
+{
+       if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename,
+                           "hotplug-status", "connected"))
+               return -1;
+       return 0;
+}
+
+static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
+{
+       uint32_t *src32 = src;
+       uint64_t *src64 = src;
+       int i;
+
+       for (i = 0; i < count; i++)
+               dst[i] = (mode == 32) ? src32[i] : src64[i];
+}
+
+static int xenfb_map_fb(struct xenfb *xenfb, int domid)
+{
+       struct xenfb_page *page = xenfb->fb.page;
+       int n_fbmfns;
+       int n_fbdirs;
+       unsigned long *pgmfns = NULL;
+       unsigned long *fbmfns = NULL;
+       void *map, *pd;
+       int mode, ret = -1;
+
+       /* default to native */
+       pd = page->pd;
+       mode = sizeof(unsigned long) * 8;
+
+       if (0 == strlen(xenfb->protocol)) {
+               /*
+                * Undefined protocol, some guesswork needed.
+                *
+                * Old frontends which don't set the protocol use
+                * one page directory only, thus pd[1] must be zero.
+                * pd[1] of the 32bit struct layout and the lower
+                * 32 bits of pd[0] of the 64bit struct layout have
+                * the same location, so we can check that ...
+                */
+               uint32_t *ptr32 = NULL;
+               uint32_t *ptr64 = NULL;
+#if defined(__i386__)
+               ptr32 = (void*)page->pd;
+               ptr64 = ((void*)page->pd) + 4;
+#elif defined(__x86_64__)
+               ptr32 = ((void*)page->pd) - 4;
+               ptr64 = (void*)page->pd;
+#endif
+               if (ptr32) {
+                       if (0 == ptr32[1]) {
+                               mode = 32;
+                               pd   = ptr32;
+                       } else {
+                               mode = 64;
+                               pd   = ptr64;
+                       }
+               }
+#if defined(__x86_64__)
+       } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
+               /* 64bit dom0, 32bit domU */
+               mode = 32;
+               pd   = ((void*)page->pd) - 4;
+#elif defined(__i386__)
+       } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
+               /* 32bit dom0, 64bit domU */
+               mode = 64;
+               pd   = ((void*)page->pd) + 4;
+#endif
+       }
+
+       n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
+       n_fbdirs = n_fbmfns * mode / 8;
+       n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
+
+       pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
+       fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
+       if (!pgmfns || !fbmfns)
+               goto out;
+
+       xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
+       map = xc_map_foreign_pages(xenfb->xc, domid,
+                                  PROT_READ, pgmfns, n_fbdirs);
+       if (map == NULL)
+               goto out;
+       xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
+       munmap(map, n_fbdirs * XC_PAGE_SIZE);
+
+       xenfb->pixels = xc_map_foreign_pages(xenfb->xc, domid,
+                               PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
+       if (xenfb->pixels == NULL)
+               goto out;
+
+       ret = 0; /* all is fine */
+
+ out:
+       if (pgmfns)
+               free(pgmfns);
+       if (fbmfns)
+               free(fbmfns);
+       return ret;
+}
+
+static int xenfb_bind(struct xenfb_device *dev)
+{
+       struct xenfb *xenfb = dev->xenfb;
+       unsigned long mfn;
+       evtchn_port_t evtchn;
+
+       if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu",
+                           &mfn) < 0)
+               return -1;
+       if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u",
+                           &evtchn) < 0)
+               return -1;
+
+       dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch,
+                                              dev->otherend_id, evtchn);
+       if (dev->port == -1)
+               return -1;
+
+       dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id,
+                       XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
+       if (dev->page == NULL)
+               return -1;
+
+       return 0;
+}
+
+static void xenfb_unbind(struct xenfb_device *dev)
+{
+       if (dev->page) {
+               munmap(dev->page, XC_PAGE_SIZE);
+               dev->page = NULL;
+       }
+        if (dev->port >= 0) {
+               xc_evtchn_unbind(dev->xenfb->evt_xch, dev->port);
+               dev->port = -1;
+       }
+}
+
+
+static void xenfb_detach_dom(struct xenfb *xenfb)
+{
+       xenfb_unbind(&xenfb->fb);
+       xenfb_unbind(&xenfb->kbd);
+       if (xenfb->pixels) {
+               munmap(xenfb->pixels, xenfb->fb_len);
+               xenfb->pixels = NULL;
+       }
+}
+
+/* Remove the backend area in xenbus since the framebuffer really is
+   going away. */
+void xenfb_shutdown(struct xenfb *xenfb)
+{
+       fprintf(stderr, "FB: Shutting down backend\n");
+       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
+       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
+
+       xenfb_detach_dom(xenfb);
+       if (xenfb->xc >= 0)
+               xc_interface_close(xenfb->xc);
+       if (xenfb->evt_xch >= 0)
+               xc_evtchn_close(xenfb->evt_xch);
+       if (xenfb->xsh)
+               xs_daemon_close(xenfb->xsh);
+       free(xenfb);
+}
+
+
+static void xenfb_on_fb_event(struct xenfb *xenfb)
+{
+       uint32_t prod, cons;
+       struct xenfb_page *page = xenfb->fb.page;
+
+       prod = page->out_prod;
+       if (prod == page->out_cons)
+               return;
+       rmb();                  /* ensure we see ring contents up to prod */
+       for (cons = page->out_cons; cons != prod; cons++) {
+               union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
+
+               switch (event->type) {
+               case XENFB_TYPE_UPDATE:
+                       xenfb_guest_copy(xenfb,
+                                        event->update.x, event->update.y,
+                                        event->update.width, 
event->update.height);
+                       break;
+               }
+       }
+       mb();                   /* ensure we're done with ring contents */
+       page->out_cons = cons;
+       xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
+}
+
+static void xenfb_on_kbd_event(struct xenfb *xenfb)
+{
+       struct xenkbd_page *page = xenfb->kbd.page;
+
+       /* We don't understand any keyboard events, so just ignore them. */
+       if (page->out_prod == page->out_cons)
+               return;
+       page->out_cons = page->out_prod;
+       xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
+}
+
+static int xenfb_on_state_change(struct xenfb_device *dev)
+{
+       enum xenbus_state state;
+
+       state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
+
+       switch (state) {
+       case XenbusStateUnknown:
+               /* There was an error reading the frontend state.  The
+                  domain has probably gone away; in any case, there's
+                  not much point in us continuing. */
+               return -1;
+       case XenbusStateInitialising:
+       case XenbusStateInitWait:
+       case XenbusStateInitialised:
+       case XenbusStateConnected:
+               break;
+       case XenbusStateClosing:
+               xenfb_unbind(dev);
+               xenfb_switch_state(dev, state);
+               break;
+       case XenbusStateClosed:
+               xenfb_switch_state(dev, state);
+       }
+       return 0;
+}
+
+/* Send an event to the keyboard frontend driver */
+static int xenfb_kbd_event(struct xenfb *xenfb,
+                          union xenkbd_in_event *event)
+{
+       uint32_t prod;
+       struct xenkbd_page *page = xenfb->kbd.page;
+
+       if (xenfb->kbd.state != XenbusStateConnected)
+               return 0;
+
+       prod = page->in_prod;
+       if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
+               errno = EAGAIN;
+               return -1;
+       }
+
+       mb();                   /* ensure ring space available */
+       XENKBD_IN_RING_REF(page, prod) = *event;
+       wmb();                  /* ensure ring contents visible */
+       page->in_prod = prod + 1;
+       return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
+}
+
+/* Send a keyboard (or mouse button) event */
+static int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode)
+{
+       union xenkbd_in_event event;
+
+       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+       event.type = XENKBD_TYPE_KEY;
+       event.key.pressed = down ? 1 : 0;
+       event.key.keycode = keycode;
+
+       return xenfb_kbd_event(xenfb, &event);
+}
+
+/* Send a relative mouse movement event */
+static int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y)
+{
+       union xenkbd_in_event event;
+
+       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+       event.type = XENKBD_TYPE_MOTION;
+       event.motion.rel_x = rel_x;
+       event.motion.rel_y = rel_y;
+
+       return xenfb_kbd_event(xenfb, &event);
+}
+
+/* Send an absolute mouse movement event */
+static int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y)
+{
+       union xenkbd_in_event event;
+
+       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
+       event.type = XENKBD_TYPE_POS;
+       event.pos.abs_x = abs_x;
+       event.pos.abs_y = abs_y;
+
+       return xenfb_kbd_event(xenfb, &event);
+}
+
+/* Process events from the frontend event channel */
+static void xenfb_dispatch_channel(void *opaque)
+{
+       struct xenfb *xenfb = (struct xenfb *)opaque;
+       evtchn_port_t port;
+       port = xc_evtchn_pending(xenfb->evt_xch);
+       if (port == -1) {
+               xenfb_shutdown(xenfb);
+               exit(1);
+       }
+
+       if (port == xenfb->fb.port)
+               xenfb_on_fb_event(xenfb);
+       else if (port == xenfb->kbd.port)
+               xenfb_on_kbd_event(xenfb);
+
+       if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1) {
+               xenfb_shutdown(xenfb);
+               exit(1);
+       }
+}
+
+/* Process ongoing events from the frontend devices */
+static void xenfb_dispatch_store(void *opaque)
+{
+       struct xenfb *xenfb = (struct xenfb *)opaque;
+       unsigned dummy;
+       char **vec;
+       int r;
+
+       vec = xs_read_watch(xenfb->xsh, &dummy);
+       free(vec);
+       r = xenfb_on_state_change(&xenfb->fb);
+       if (r == 0)
+               r = xenfb_on_state_change(&xenfb->kbd);
+       if (r < 0) {
+               xenfb_shutdown(xenfb);
+               exit(1);
+       }
+}
+
+
+/****************************************************************
+ *
+ * Functions for processing frontend config
+ *
+ ****************************************************************/
+
+
+/* Process the frontend framebuffer config */
+static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) {
+       struct xenfb_page *fb_page;
+       int val;
+
+        if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update",
+                            "%d", &val) < 0)
+                val = 0;
+        if (!val) {
+                fprintf(stderr, "feature-update not supported\n");
+                errno = ENOTSUP;
+                return -1;
+        }
+        if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "protocol", "%63s",
+                            xenfb->protocol) < 0)
+                xenfb->protocol[0] = '\0';
+        xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1");
+
+        /* TODO check for permitted ranges */
+        fb_page = xenfb->fb.page;
+        xenfb->depth = fb_page->depth;
+        xenfb->width = fb_page->width;
+        xenfb->height = fb_page->height;
+        /* TODO check for consistency with the above */
+        xenfb->fb_len = fb_page->mem_length;
+        xenfb->row_stride = fb_page->line_length;
+        fprintf(stderr, "Framebuffer depth %d width %d height %d line %d\n",
+                fb_page->depth, fb_page->width, fb_page->height, 
fb_page->line_length);
+        if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0)
+               return -1;
+
+        if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
+                return -1;
+        if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
+                return -1;
+
+       return 0;
+}
+
+/* Process the frontend keyboard config */
+static int xenfb_read_frontend_kbd_config(struct xenfb *xenfb)
+{
+       int val;
+
+       if (xenfb_xs_scanf1(xenfb->xsh, xenfb->kbd.otherend, 
"request-abs-pointer",
+                           "%d", &val) < 0)
+               val = 0;
+       xenfb->abs_pointer_wanted = val;
+
+       return 0;
+}
+
+
+/****************************************************************
+ *
+ * Functions for frontend/backend state machine
+ *
+ ****************************************************************/
+
+/* Register a watch against a frontend device, and setup
+ * QEMU event loop to poll the xenstore FD for notification */
+static int xenfb_wait_for_frontend(struct xenfb_device *dev, IOHandler 
*handler)
+{
+        fprintf(stderr, "Doing frontend watch on %s\n", dev->otherend);
+       if (!xs_watch(dev->xenfb->xsh, dev->otherend, "")) {
+               fprintf(stderr, "Watch for dev failed\n");
+               return -1;
+       }
+
+       if (qemu_set_fd_handler2(xs_fileno(dev->xenfb->xsh), NULL, handler, 
NULL, dev) < 0)
+               return -1;
+
+       return 0;
+}
+
+/* Register a watch against a backend device, and setup
+ * QEMU event loop to poll the xenstore FD for notification */
+static int xenfb_wait_for_backend(struct xenfb_device *dev, IOHandler *handler)
+{
+       fprintf(stderr, "Doing backend watch on %s\n", dev->nodename);
+       if (!xs_watch(dev->xenfb->xsh, dev->nodename, "")) {
+               fprintf(stderr, "Watch for dev failed\n");
+               return -1;
+       }
+
+       if (qemu_set_fd_handler2(xs_fileno(dev->xenfb->xsh), NULL, handler, 
NULL, dev) < 0)
+               return -1;
+
+       return 0;
+}
+
+/* Callback invoked while waiting for KBD backend to change
+ * to the created state */
+static void xenfb_backend_created_kbd(void *opaque)
+{
+       struct xenfb_device *dev = (struct xenfb_device *)opaque;
+       int ret = xenfb_backend_created(dev);
+       if (ret < 0) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+       if (ret)
+               return; /* Still waiting */
+
+       if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename, 
"feature-abs-pointer", "1")) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+
+       fprintf(stderr, "FB: Waiting for FB backend creation\n");
+       xenfb_wait_for_backend(&dev->xenfb->fb, xenfb_backend_created_fb);
+}
+
+/* Callback invoked while waiting for FB backend to change
+ * to the created state */
+static void xenfb_backend_created_fb(void *opaque)
+{
+       struct xenfb_device *dev = (struct xenfb_device *)opaque;
+       int ret = xenfb_backend_created(dev);
+       if (ret < 0) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+       if (ret)
+               return; /* Still waiting */
+
+       fprintf(stderr, "FB: Waiting for KBD frontend initialization\n");
+       xenfb_wait_for_frontend(&dev->xenfb->kbd, 
xenfb_frontend_initialized_kbd);
+}
+
+/* Callback invoked while waiting for KBD frontend to change
+ * to the initialized state */
+static void xenfb_frontend_initialized_kbd(void *opaque)
+{
+       struct xenfb_device *dev = (struct xenfb_device *)opaque;
+       int ret = xenfb_frontend_initialized(dev);
+       if (ret < 0) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+       if (ret)
+               return; /* Still waiting */
+
+
+        fprintf(stderr, "FB: Waiting for FB frontend initialization\n");
+       xenfb_wait_for_frontend(&dev->xenfb->fb, xenfb_frontend_initialized_fb);
+}
+
+/* Callback invoked while waiting for FB frontend to change
+ * to the initialized state */
+static void xenfb_frontend_initialized_fb(void *opaque)
+{
+       struct xenfb_device *dev = (struct xenfb_device *)opaque;
+       int ret = xenfb_frontend_initialized(dev);
+       if (ret < 0) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+       if (ret)
+               return; /* Still waiting */
+
+
+       if (xenfb_read_frontend_fb_config(dev->xenfb)) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+
+        fprintf(stderr, "FB: Waiting for KBD frontend connection\n");
+       xenfb_wait_for_frontend(&dev->xenfb->kbd, xenfb_frontend_connected_kbd);
+}
+
+/* Callback invoked while waiting for KBD frontend to change
+ * to the connected state */
+static void xenfb_frontend_connected_kbd(void *opaque)
+{
+       struct xenfb_device *dev = (struct xenfb_device *)opaque;
+       int ret = xenfb_frontend_connected(dev);
+       if (ret < 0) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+       if (ret)
+               return; /* Still waiting */
+
+       if (xenfb_read_frontend_kbd_config(dev->xenfb) < 0) {
+               xenfb_shutdown(dev->xenfb);
+               exit(1);
+       }
+
+       xenfb_register_console(dev->xenfb);
+}
+
+
+/****************************************************************
+ *
+ * Helper functions for checking state of frontend/backend devices
+ *
+ ****************************************************************/
+
+/* Helper to determine if a frontend device is in Connected state */
+static int xenfb_frontend_connected(struct xenfb_device *dev)
+{
+       unsigned int state;
+       unsigned int dummy;
+       char **vec;
+       vec = xs_read_watch(dev->xenfb->xsh, &dummy);
+       if (!vec)
+               return -1;
+       free(vec);
+
+       state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
+       if (!((1 <<state) & ((1 << XenbusStateUnknown) |
+                            (1 << XenbusStateConnected)))) {
+               fprintf(stderr, "FB: Carry on waiting\n");
+               return 1;
+       }
+
+       /* Don't unwatch frontend - we need to detect shutdown */
+       /*xs_unwatch(dev->xenfb->xsh, dev->otherend, "");*/
+
+       switch (state) {
+       case XenbusStateConnected:
+               break;
+       default:
+               return -1;
+       }
+       return 0;
+}
+
+
+/* Helper to determine if a frontend device is in Initialized state */
+static int xenfb_frontend_initialized(struct xenfb_device *dev)
+{
+       unsigned int state;
+       unsigned int dummy;
+       char **vec;
+       vec = xs_read_watch(dev->xenfb->xsh, &dummy);
+       if (!vec)
+               return -1;
+       free(vec);
+
+       state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
+
+       if (!((1 << state) & ((1 << XenbusStateUnknown)
+                             | (1 << XenbusStateInitialised)
+#if 1 /* TODO fudging state to permit restarting; to be removed */
+                             | (1 << XenbusStateConnected)
+#endif
+                             ))) {
+               fprintf(stderr, "FB: Carry on waiting\n");
+               return 1;
+       }
+
+       xs_unwatch(dev->xenfb->xsh, dev->otherend, "");
+
+       switch (state) {
+#if 1
+       case XenbusStateConnected:
+                printf("Fudging state to %d\n", XenbusStateInitialised); /* 
FIXME */
+#endif
+        case XenbusStateInitialised:
+                break;
+        default:
+                return -1;
+        }
+
+       if (xenfb_bind(dev) < 0)
+               return -1;
+
+       return 0;
+}
+
+/* Helper to determine if a backend device is in Created state */
+static int xenfb_backend_created(struct xenfb_device *dev)
+{
+       unsigned int state;
+       unsigned int dummy;
+       char **vec;
+       vec = xs_read_watch(dev->xenfb->xsh, &dummy);
+       if (!vec)
+               return -1;
+       free(vec);
+
+       state = xenfb_read_state(dev->xenfb->xsh, dev->nodename);
+
+       if (!((1 <<state) & ((1 << XenbusStateUnknown)
+                            | (1 << XenbusStateInitialising)
+                            | (1 << XenbusStateClosed)
+#if 1 /* TODO fudging state to permit restarting; to be removed */
+                            | (1 << XenbusStateInitWait)
+                            | (1 << XenbusStateConnected)
+                            | (1 << XenbusStateClosing)
+#endif
+                            ))) {
+               fprintf(stderr, "FB: Carry on waiting\n");
+               return 1;
+       }
+
+       xs_unwatch(dev->xenfb->xsh, dev->nodename, "");
+
+        switch (state) {
+#if 1
+        case XenbusStateInitWait:
+        case XenbusStateConnected:
+                printf("Fudging state to %d\n", XenbusStateInitialising); /* 
FIXME */
+#endif
+        case XenbusStateInitialising:
+        case XenbusStateClosing:
+        case XenbusStateClosed:
+                break;
+        default:
+                fprintf(stderr, "Wrong state %d\n", state);
+                return -1;
+        }
+        xenfb_switch_state(dev, XenbusStateInitWait);
+        if (xenfb_hotplug(dev) < 0)
+                return -1;
+
+        return 0;
+}
+
+
+/****************************************************************
+ * 
+ * QEMU device model integration functions
+ *
+ ****************************************************************/
+
+/* 
+ * Send a key event from the client to the guest OS
+ * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
+ * We have to turn this into a Linux Input layer keycode.
+ * 
+ * Extra complexity from the fact that with extended scancodes 
+ * (like those produced by arrow keys) this method gets called
+ * twice, but we only want to send a single event. So we have to
+ * track the '0xe0' scancode state & collapse the extended keys
+ * as needed.
+ * 
+ * Wish we could just send scancodes straight to the guest which
+ * already has code for dealing with this...
+ */
+static void xenfb_key_event(void *opaque, int scancode)
+{
+    static int extended = 0;
+    int down = 1;
+    if (scancode == 0xe0) {
+        extended = 1;
+        return;
+    } else if (scancode & 0x80) {
+        scancode &= 0x7f;
+        down = 0;
+    }
+    if (extended) {
+        scancode |= 0x80;
+        extended = 0;
+    }
+    xenfb_send_key(opaque, down, scancode2linux[scancode]);
+}
+
+/*
+ * Send a mouse event from the client to the guest OS
+ * 
+ * The QEMU mouse can be in either relative, or absolute mode.
+ * Movement is sent separately from button state, which has to
+ * be encoded as virtual key events. We also don't actually get
+ * given any button up/down events, so have to track changes in
+ * the button state.
+ */
+static void xenfb_mouse_event(void *opaque,
+                             int dx, int dy, int dz, int button_state)
+{
+    int i;
+    struct xenfb *xenfb = opaque;
+    if (xenfb->abs_pointer_wanted)
+           xenfb_send_position(xenfb,
+                               dx * xenfb->ds->width / 0x7fff,
+                               dy * xenfb->ds->height / 0x7fff);
+    else
+           xenfb_send_motion(xenfb, dx, dy);
+
+    for (i = 0 ; i < 8 ; i++) {
+           int lastDown = xenfb->button_state & (1 << i);
+           int down = button_state & (1 << i);
+           if (down == lastDown)
+                   continue;
+
+           if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
+                   return;
+    }
+    xenfb->button_state = button_state;
+}
+
+/* A convenient function for munging pixels between different depths */
+#define BLT(SRC_T,DST_T,RLS,GLS,BLS,RRS,GRS,BRS,RM,GM,BM)               \
+    for (line = y ; line < h ; line++) {                                \
+        SRC_T *src = (SRC_T *)(xenfb->pixels                            \
+                               + (line * xenfb->row_stride)             \
+                               + (x * xenfb->depth / 8));               \
+        DST_T *dst = (DST_T *)(xenfb->ds->data                                 
\
+                               + (line * xenfb->ds->linesize)                  
\
+                               + (x * xenfb->ds->depth / 8));                  
\
+        int col;                                                        \
+        for (col = x ; col < w ; col++) {                               \
+            *dst = (((*src >> RRS) & RM) << RLS) |                      \
+                (((*src >> GRS) & GM) << GLS) |                         \
+                (((*src >> GRS) & BM) << BLS);                          \
+            src++;                                                      \
+            dst++;                                                      \
+        }                                                               \
+    }
+
+
+/* This copies data from the guest framebuffer region, into QEMU's copy
+ * NB. QEMU's copy is stored in the pixel format of a) the local X 
+ * server (SDL case) or b) the current VNC client pixel format.
+ * When shifting between colour depths we preserve the MSB.
+ */
+static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
+{
+    int line;
+
+    if (xenfb->depth == xenfb->ds->depth) { /* Perfect match can use fast path 
*/
+        for (line = y ; line < (y+h) ; line++) {
+            memcpy(xenfb->ds->data + (line * xenfb->ds->linesize) + (x * 
xenfb->ds->depth / 8),
+                   xenfb->pixels + (line * xenfb->row_stride) + (x * 
xenfb->depth / 8),
+                   w * xenfb->depth / 8);
+        }
+    } else { /* Mismatch requires slow pixel munging */
+        if (xenfb->depth == 8) {
+            /* 8 bit source == r:3 g:3 b:2 */
+            if (xenfb->ds->depth == 16) {
+                BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);
+            } else if (xenfb->ds->depth == 32) {
+                BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   7, 7, 3);
+            }
+        } else if (xenfb->depth == 16) {
+            /* 16 bit source == r:5 g:6 b:5 */
+            if (xenfb->ds->depth == 8) {
+                BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);
+            } else if (xenfb->ds->depth == 32) {
+                BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0,   31, 63, 31);
+            }
+        } else if (xenfb->depth == 32) {
+            /* 32 bit source == r:8 g:8 b:8 (padding:8) */
+            if (xenfb->ds->depth == 8) {
+                BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 
255);
+            } else if (xenfb->ds->depth == 16) {
+                BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 
255);
+            }
+        }
+    }
+    dpy_update(xenfb->ds, x, y, w, h);
+}
+
+/* QEMU display state changed, so refresh the framebuffer copy */
+/* XXX - can we optimize this, or the next func at all ? */ 
+static void xenfb_update(void *opaque)
+{
+    struct xenfb *xenfb = opaque;
+    xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+}
+
+/* QEMU display state changed, so refresh the framebuffer copy */
+static void xenfb_invalidate(void *opaque)
+{
+    struct xenfb *xenfb = opaque;
+    xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
+}
+
+/* Screen dump is not used in Xen, so no need to impl this....yet */
+static void xenfb_screen_dump(void *opaque, const char *name) { }
+
+
+/* Register a QEMU graphical console, and key/mouse handler,
+ * connecting up their events to the frontend */
+static int xenfb_register_console(struct xenfb *xenfb) {
+       /* Register our keyboard & mouse handlers */
+       qemu_add_kbd_event_handler(xenfb_key_event, xenfb);
+       qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
+                                    xenfb->abs_pointer_wanted,
+                                    "Xen PVFB Mouse");
+  
+       /* Tell QEMU to allocate a graphical console */
+       graphic_console_init(xenfb->ds,
+                            xenfb_update,
+                            xenfb_invalidate,
+                            xenfb_screen_dump,
+                            xenfb);
+       dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
+
+       if (qemu_set_fd_handler2(xenfb->evt_xch, NULL, xenfb_dispatch_channel, 
NULL, xenfb) < 0)
+               return -1;
+       if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, 
xenfb_dispatch_store, NULL, xenfb) < 0)
+               return -1;
+
+        fprintf(stderr, "Xen Framebuffer registered\n");
+        return 0;
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/hw/xenfb.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/xenfb.h    Tue Oct 30 15:34:44 2007 -0600
@@ -0,0 +1,13 @@
+#ifndef _XENFB_H_
+#define _XENFB_H_
+
+#include "vl.h"
+#include <stdbool.h>
+#include <sys/types.h>
+
+struct xenfb;
+
+struct xenfb *xenfb_new(int domid, DisplayState *ds);
+void xenfb_shutdown(struct xenfb *xenfb);
+
+#endif
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/monitor.c
--- a/tools/ioemu/monitor.c     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/monitor.c     Tue Oct 30 15:34:44 2007 -0600
@@ -374,7 +374,7 @@ void do_eject(int force, const char *fil
     eject_device(bs, force);
 }
 
-void do_change(const char *device, const char *filename)
+static void do_change_block(const char *device, const char *filename)
 {
     BlockDriverState *bs;
     int i;
@@ -396,6 +396,30 @@ void do_change(const char *device, const
                 break;
             term_printf("invalid password\n");
         }
+    }
+}
+
+static void do_change_vnc(const char *target)
+{
+    if (strcmp(target, "passwd") == 0 ||
+       strcmp(target, "password") == 0) {
+       char password[9];
+       monitor_readline("Password: ", 1, password, sizeof(password)-1);
+       password[sizeof(password)-1] = '\0';
+       if (vnc_display_password(NULL, password) < 0)
+           term_printf("could not set VNC server password\n");
+    } else {
+       if (vnc_display_open(NULL, target, 0) < 0)
+           term_printf("could not start VNC server on %s\n", target);
+    }
+}
+
+void do_change(const char *device, const char *target)
+{
+    if (strcmp(device, "vnc") == 0) {
+       do_change_vnc(target);
+    } else {
+       do_change_block(device, target);
     }
 }
 
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/target-i386-dm/helper2.c      Tue Oct 30 15:34:44 2007 -0600
@@ -478,6 +478,7 @@ void cpu_ioreq_timeoffset(CPUState *env,
 
     time_offset += (ulong)req->data;
 
+    fprintf(logfile, "Time offset set %ld, added offset %ld\n", time_offset, 
req->data);
     sprintf(b, "%ld", time_offset);
     xenstore_vm_write(domid, "rtc/timeoffset", b);
 }
@@ -538,20 +539,39 @@ void __handle_ioreq(CPUState *env, ioreq
 
 void __handle_buffered_iopage(CPUState *env)
 {
-    ioreq_t *req = NULL;
+    buf_ioreq_t *buf_req = NULL;
+    ioreq_t req;
+    int qw = 0;
 
     if (!buffered_io_page)
         return;
 
     while (buffered_io_page->read_pointer !=
            buffered_io_page->write_pointer) {
-        req = &buffered_io_page->ioreq[buffered_io_page->read_pointer %
+        memset(&req, 0, sizeof(req));
+        buf_req = &buffered_io_page->buf_ioreq[buffered_io_page->read_pointer %
                                       IOREQ_BUFFER_SLOT_NUM];
-
-        __handle_ioreq(env, req);
+        req.size = 1UL << buf_req->size;
+        req.count = 1;
+        req.data = buf_req->data;
+        req.state = STATE_IOREQ_READY;
+        req.dir  = buf_req->dir;
+        req.type = buf_req->type;
+        qw = req.size == 8;
+        if (qw) {
+            req.data |= ((uint64_t)buf_req->addr) << 16;
+            buf_req = 
&buffered_io_page->buf_ioreq[(buffered_io_page->read_pointer+1) %
+                                               IOREQ_BUFFER_SLOT_NUM];
+            req.data |= ((uint64_t)buf_req->data) << 32;
+            req.data |= ((uint64_t)buf_req->addr) << 48;
+        }
+        else
+            req.addr = buf_req->addr;
+
+        __handle_ioreq(env, &req);
 
         mb();
-        buffered_io_page->read_pointer++;
+        buffered_io_page->read_pointer += qw ? 2 : 1;
     }
 }
 
@@ -616,7 +636,7 @@ int main_loop(void)
     extern int shutdown_requested;
     extern int suspend_requested;
     CPUState *env = cpu_single_env;
-    int evtchn_fd = xc_evtchn_fd(xce_handle);
+    int evtchn_fd = xce_handle == -1 ? -1 : xc_evtchn_fd(xce_handle);
     char qemu_file[PATH_MAX];
     fd_set fds;
 
@@ -624,7 +644,8 @@ int main_loop(void)
                                       cpu_single_env);
     qemu_mod_timer(buffered_io_timer, qemu_get_clock(rt_clock));
 
-    qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
+    if (evtchn_fd != -1)
+        qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
 
     xenstore_record_dm_state("running");
     while (1) {
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/vl.c  Tue Oct 30 15:34:44 2007 -0600
@@ -96,7 +96,6 @@
 
 #include "exec-all.h"
 
-#include <xen/hvm/params.h>
 #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
 #ifdef _BSD
 #define DEFAULT_BRIDGE "bridge0"
@@ -194,11 +193,8 @@ extern int vcpus;
 
 int xc_handle;
 
-char domain_name[64] = "Xen-HVM-no-name";
+char domain_name[64] = "Xen-no-name";
 extern int domid;
-
-char vncpasswd[64];
-unsigned char challenge[AUTHCHALLENGESIZE];
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -6204,12 +6200,10 @@ void main_loop_wait(int timeout)
         IOHandlerRecord **pioh;
 
         for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
-            if (ioh->deleted)
-                continue;
-            if (ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
+            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
                 ioh->fd_read(ioh->opaque);
             }
-            if (ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
+            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
                 ioh->fd_write(ioh->opaque);
             }
         }
@@ -6696,8 +6690,13 @@ void register_machines(void)
 void register_machines(void)
 {
 #if defined(TARGET_I386)
+#ifndef CONFIG_DM
     qemu_register_machine(&pc_machine);
     qemu_register_machine(&isapc_machine);
+#else
+    qemu_register_machine(&xenfv_machine);
+    qemu_register_machine(&xenpv_machine);
+#endif
 #elif defined(TARGET_PPC)
     qemu_register_machine(&heathrow_machine);
     qemu_register_machine(&core99_machine);
@@ -6905,156 +6904,6 @@ int set_mm_mapping(int xc_handle, uint32
     return 0;
 }
 
-#if defined(MAPCACHE)
-
-#if defined(__i386__) 
-#define MAX_MCACHE_SIZE    0x40000000 /* 1GB max for x86 */
-#define MCACHE_BUCKET_SHIFT 16
-#elif defined(__x86_64__)
-#define MAX_MCACHE_SIZE    0x1000000000 /* 64GB max for x86_64 */
-#define MCACHE_BUCKET_SHIFT 20
-#endif
-
-#define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT)
-
-#define BITS_PER_LONG (sizeof(long)*8)
-#define BITS_TO_LONGS(bits) \
-    (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#define DECLARE_BITMAP(name,bits) \
-    unsigned long name[BITS_TO_LONGS(bits)]
-#define test_bit(bit,map) \
-    (!!((map)[(bit)/BITS_PER_LONG] & (1UL << ((bit)%BITS_PER_LONG))))
-
-struct map_cache {
-    unsigned long paddr_index;
-    uint8_t      *vaddr_base;
-    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>PAGE_SHIFT);
-};
-
-static struct map_cache *mapcache_entry;
-static unsigned long nr_buckets;
-
-/* For most cases (>99.9%), the page address is the same. */
-static unsigned long last_address_index = ~0UL;
-static uint8_t      *last_address_vaddr;
-
-static int qemu_map_cache_init(void)
-{
-    unsigned long size;
-
-    nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
-                   (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
-                  (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
-
-    /*
-     * Use mmap() directly: lets us allocate a big hash table with no up-front
-     * cost in storage space. The OS will allocate memory only for the buckets
-     * that we actually use. All others will contain all zeroes.
-     */
-    size = nr_buckets * sizeof(struct map_cache);
-    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
-    fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx size %lu\n", 
nr_buckets, size);
-    mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
-                          MAP_SHARED|MAP_ANON, -1, 0);
-    if (mapcache_entry == MAP_FAILED) {
-        errno = ENOMEM;
-        return -1;
-    }
-
-    return 0;
-}
-
-static void qemu_remap_bucket(struct map_cache *entry,
-                              unsigned long address_index)
-{
-    uint8_t *vaddr_base;
-    unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
-    unsigned int i, j;
-
-    if (entry->vaddr_base != NULL) {
-        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
-        if (errno) {
-            fprintf(logfile, "unmap fails %d\n", errno);
-            exit(-1);
-        }
-    }
-
-    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++)
-        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i;
-
-    vaddr_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE,
-                                      pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT);
-    if (vaddr_base == NULL) {
-        fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
-        exit(-1);
-    }
-
-    entry->vaddr_base  = vaddr_base;
-    entry->paddr_index = address_index;
-
-    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i += BITS_PER_LONG) {
-        unsigned long word = 0;
-        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
-            (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
-        while (j > 0)
-            word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
-        entry->valid_mapping[i / BITS_PER_LONG] = word;
-    }
-}
-
-uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
-{
-    struct map_cache *entry;
-    unsigned long address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-    unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
-
-    if (address_index == last_address_index)
-        return last_address_vaddr + address_offset;
-
-    entry = &mapcache_entry[address_index % nr_buckets];
-
-    if (entry->vaddr_base == NULL || entry->paddr_index != address_index ||
-        !test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
-        qemu_remap_bucket(entry, address_index);
-
-    if (!test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
-        return NULL;
-
-    last_address_index = address_index;
-    last_address_vaddr = entry->vaddr_base;
-
-    return last_address_vaddr + address_offset;
-}
-
-void qemu_invalidate_map_cache(void)
-{
-    unsigned long i;
-
-    mapcache_lock();
-
-    for (i = 0; i < nr_buckets; i++) {
-        struct map_cache *entry = &mapcache_entry[i];
-
-        if (entry->vaddr_base == NULL)
-            continue;
-
-        errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
-        if (errno) {
-            fprintf(logfile, "unmap fails %d\n", errno);
-            exit(-1);
-        }
-
-        entry->paddr_index = 0;
-        entry->vaddr_base  = NULL;
-    }
-
-    last_address_index =  ~0UL;
-    last_address_vaddr = NULL;
-
-    mapcache_unlock();
-}
-
-#endif /* defined(MAPCACHE) */
 
 int main(int argc, char **argv)
 {
@@ -7089,15 +6938,7 @@ int main(int argc, char **argv)
     char usb_devices[MAX_USB_CMDLINE][128];
     int usb_devices_index;
     int fds[2];
-    unsigned long ioreq_pfn;
-    extern void *shared_page;
-    extern void *buffered_io_page;
     struct rlimit rl;
-#ifdef __ia64__
-    unsigned long nr_pages;
-    xen_pfn_t *page_array;
-    extern void *buffered_pio_page;
-#endif
     sigset_t set;
     char qemu_dm_logfilename[128];
     const char *direct_pci = NULL;
@@ -7193,7 +7034,6 @@ int main(int argc, char **argv)
     vncunused = 0;
     kernel_filename = NULL;
     kernel_cmdline = "";
-    *vncpasswd = '\0';
 #ifndef CONFIG_DM
 #ifdef TARGET_PPC
     cdrom_index = 1;
@@ -7601,7 +7441,7 @@ int main(int argc, char **argv)
                 break;
             case QEMU_OPTION_domainname:
                 snprintf(domain_name, sizeof(domain_name),
-                         "Xen-HVM-%s", optarg);
+                         "Xen-%s", optarg);
                 break;
             case QEMU_OPTION_d:
                 domid = atoi(optarg);
@@ -7681,6 +7521,7 @@ int main(int argc, char **argv)
 
 #ifdef CONFIG_DM
     bdrv_init();
+    xc_handle = xc_interface_open();
     xenstore_parse_domain_config(domid);
 #endif /* CONFIG_DM */
 
@@ -7774,83 +7615,6 @@ int main(int argc, char **argv)
        }
        phys_ram_size += ret;
     }
-#endif /* !CONFIG_DM */
-
-#ifdef CONFIG_DM
-
-    xc_handle = xc_interface_open();
-
-#if defined(__i386__) || defined(__x86_64__)
-
-    if (qemu_map_cache_init()) {
-        fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
-        exit(-1);
-    }
-
-    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
-    fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
-    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                       PROT_READ|PROT_WRITE, ioreq_pfn);
-    if (shared_page == NULL) {
-        fprintf(logfile, "map shared IO page returned error %d\n", errno);
-        exit(-1);
-    }
-
-    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
-    fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
-    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                            PROT_READ|PROT_WRITE, ioreq_pfn);
-    if (buffered_io_page == NULL) {
-        fprintf(logfile, "map buffered IO page returned error %d\n", errno);
-        exit(-1);
-    }
-
-#elif defined(__ia64__)
-
-    nr_pages = ram_size/PAGE_SIZE;
-
-    page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
-    if (page_array == NULL) {
-        fprintf(logfile, "malloc returned error %d\n", errno);
-        exit(-1);
-    }
-
-    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                       PROT_READ|PROT_WRITE,
-                                       IO_PAGE_START >> PAGE_SHIFT);
-
-    buffered_io_page =xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                       PROT_READ|PROT_WRITE,
-                                       BUFFER_IO_PAGE_START >> PAGE_SHIFT);
-
-    buffered_pio_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
-                                       PROT_READ|PROT_WRITE,
-                                       BUFFER_PIO_PAGE_START >> PAGE_SHIFT);
-
-    for (i = 0; i < nr_pages; i++)
-        page_array[i] = i;
-       
-    /* VTI will not use memory between 3G~4G, so we just pass a legal pfn
-       to make QEMU map continuous virtual memory space */
-    if (ram_size > MMIO_START) {       
-        for (i = 0 ; i < (MEM_G >> PAGE_SHIFT); i++)
-            page_array[(MMIO_START >> PAGE_SHIFT) + i] =
-                (STORE_PAGE_START >> PAGE_SHIFT); 
-    }
-
-    phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
-                                         PROT_READ|PROT_WRITE,
-                                         page_array, nr_pages);
-    if (phys_ram_base == 0) {
-        fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
-        exit(-1);
-    }
-    free(page_array);
-#endif
-
-    timeoffset_get();
-
-#else  /* !CONFIG_DM */
 
     phys_ram_base = qemu_vmalloc(phys_ram_size);
     if (!phys_ram_base) {
@@ -7858,9 +7622,6 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-#endif /* !CONFIG_DM */
-
-#ifndef CONFIG_DM
     /* we always create the cdrom drive, even if no disk is there */
     bdrv_init();
     if (cdrom_index >= 0) {
@@ -7917,17 +7678,19 @@ int main(int argc, char **argv)
 
     init_ioports();
 
-    /* read vncpasswd from xenstore */
-    if (0 > xenstore_read_vncpasswd(domid))
-        exit(1);
-
     /* terminal init */
     if (nographic) {
         dumb_display_init(ds);
     } else if (vnc_display != NULL || vncunused != 0) {
        int vnc_display_port;
-       vnc_display_port = vnc_display_init(ds, vnc_display, vncunused);
-       if (vncviewer)
+       char password[20];
+       vnc_display_init(ds);
+       if (xenstore_read_vncpasswd(domid, password, sizeof(password)) < 0)
+           exit(0);
+       vnc_display_password(ds, password);
+       if ((vnc_display_port = vnc_display_open(ds, vnc_display, vncunused)) < 
0) 
+           exit (0);
+       if (vncviewer)
            vnc_start_viewer(vnc_display_port);
        xenstore_write_vncport(vnc_display_port);
     } else {
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/vl.h  Tue Oct 30 15:34:44 2007 -0600
@@ -943,7 +943,10 @@ void cocoa_display_init(DisplayState *ds
 void cocoa_display_init(DisplayState *ds, int full_screen);
 
 /* vnc.c */
-int vnc_display_init(DisplayState *ds, const char *display, int find_unused);
+void vnc_display_init(DisplayState *ds);
+void vnc_display_close(DisplayState *ds);
+int vnc_display_open(DisplayState *ds, const char * display, int find_unused);
+int vnc_display_password(DisplayState *ds, const char *password);
 void do_info_vnc(void);
 int vnc_start_viewer(int port);
 
@@ -1108,6 +1111,10 @@ extern void pci_piix4_acpi_init(PCIBus *
 /* pc.c */
 extern QEMUMachine pc_machine;
 extern QEMUMachine isapc_machine;
+#ifdef CONFIG_DM
+extern QEMUMachine xenfv_machine;
+extern QEMUMachine xenpv_machine;
+#endif
 extern int fd_bootchk;
 
 void ioport_set_a20(int enable);
@@ -1449,7 +1456,7 @@ void xenstore_record_dm_state(char *stat
 void xenstore_record_dm_state(char *state);
 void xenstore_check_new_media_present(int timeout);
 void xenstore_write_vncport(int vnc_display);
-int xenstore_read_vncpasswd(int domid);
+int xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen);
 
 int xenstore_domain_has_devtype(struct xs_handle *handle,
                                 const char *devtype);
@@ -1486,9 +1493,6 @@ extern char domain_name[];
 
 void destroy_hvm_domain(void);
 
-/* VNC Authentication */
-#define AUTHCHALLENGESIZE 16
-
 #ifdef __ia64__
 static inline void xc_domain_shutdown_hook(int xc_handle, uint32_t domid)
 {
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/vnc.c Tue Oct 30 15:34:44 2007 -0600
@@ -49,6 +49,27 @@
 #include "keymaps.c"
 #include "d3des.h"
 
+#if CONFIG_VNC_TLS
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#endif /* CONFIG_VNC_TLS */
+
+// #define _VNC_DEBUG 1
+
+#if _VNC_DEBUG
+#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while 
(0)
+
+#if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
+/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
+static void vnc_debug_gnutls_log(int level, const char* str) {
+    VNC_DEBUG("%d %s", level, str);
+}
+#endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
+#else
+#define VNC_DEBUG(fmt, ...) do { } while (0)
+#endif
+
+
 typedef struct Buffer
 {
     size_t capacity;
@@ -73,6 +94,45 @@ typedef void VncSendHextileTile(VncState
 #define VNC_MAX_HEIGHT 2048
 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
 #endif
+
+#define VNC_AUTH_CHALLENGE_SIZE 16
+
+enum {
+    VNC_AUTH_INVALID = 0,
+    VNC_AUTH_NONE = 1,
+    VNC_AUTH_VNC = 2,
+    VNC_AUTH_RA2 = 5,
+    VNC_AUTH_RA2NE = 6,
+    VNC_AUTH_TIGHT = 16,
+    VNC_AUTH_ULTRA = 17,
+    VNC_AUTH_TLS = 18,
+    VNC_AUTH_VENCRYPT = 19
+};
+
+#if CONFIG_VNC_TLS
+enum {
+    VNC_WIREMODE_CLEAR,
+    VNC_WIREMODE_TLS,
+};
+
+enum {
+    VNC_AUTH_VENCRYPT_PLAIN = 256,
+    VNC_AUTH_VENCRYPT_TLSNONE = 257,
+    VNC_AUTH_VENCRYPT_TLSVNC = 258,
+    VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
+    VNC_AUTH_VENCRYPT_X509NONE = 260,
+    VNC_AUTH_VENCRYPT_X509VNC = 261,
+    VNC_AUTH_VENCRYPT_X509PLAIN = 262,
+};
+
+#if CONFIG_VNC_TLS
+#define X509_CA_CERT_FILE "ca-cert.pem"
+#define X509_CA_CRL_FILE "ca-crl.pem"
+#define X509_SERVER_KEY_FILE "server-key.pem"
+#define X509_SERVER_CERT_FILE "server-cert.pem"
+#endif
+
+#endif /* CONFIG_VNC_TLS */
 
 struct VncState
 {
@@ -98,7 +158,27 @@ struct VncState
     int last_x;
     int last_y;
 
-    const char *display;
+    int major;
+    int minor;
+
+    char *display;
+    char *password;
+    int auth;
+#if CONFIG_VNC_TLS
+    int subauth;
+    int x509verify;
+
+    char *x509cacert;
+    char *x509cacrl;
+    char *x509cert;
+    char *x509key;
+#endif
+    char challenge[VNC_AUTH_CHALLENGE_SIZE];
+
+#if CONFIG_VNC_TLS
+    int wiremode;
+    gnutls_session_t tls_session;
+#endif
 
     Buffer output;
     Buffer input;
@@ -164,9 +244,6 @@ static void vnc_update_client(void *opaq
 static void vnc_update_client(void *opaque);
 static void vnc_client_read(void *opaque);
 static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
-static int make_challenge(unsigned char *random, int size);
-static void set_seed(unsigned int *seedp);
-static void get_random(int len, unsigned char *buf);
 
 #if 0
 static inline void vnc_set_bit(uint32_t *d, int k)
@@ -702,11 +779,19 @@ static int vnc_client_io_error(VncState 
        if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN))
            return 0;
 
+       VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno 
: 0);
        qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
        closesocket(vs->csock);
        vs->csock = -1;
        buffer_reset(&vs->input);
        buffer_reset(&vs->output);
+#if CONFIG_VNC_TLS
+       if (vs->tls_session) {
+           gnutls_deinit(vs->tls_session);
+           vs->tls_session = NULL;
+       }
+       vs->wiremode = VNC_WIREMODE_CLEAR;
+#endif /* CONFIG_VNC_TLS */
        return 0;
     }
     return ret;
@@ -722,7 +807,19 @@ static void vnc_client_write(void *opaqu
     long ret;
     VncState *vs = opaque;
 
-    ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
+#if CONFIG_VNC_TLS
+    if (vs->tls_session) {
+       ret = gnutls_write(vs->tls_session, vs->output.buffer, 
vs->output.offset);
+       if (ret < 0) {
+           if (ret == GNUTLS_E_AGAIN)
+               errno = EAGAIN;
+           else
+               errno = EIO;
+           ret = -1;
+       }
+    } else
+#endif /* CONFIG_VNC_TLS */
+       ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
     ret = vnc_client_io_error(vs, ret, socket_error());
     if (!ret)
        return;
@@ -748,7 +845,19 @@ static void vnc_client_read(void *opaque
 
     buffer_reserve(&vs->input, 4096);
 
-    ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
+#if CONFIG_VNC_TLS
+    if (vs->tls_session) {
+       ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
+       if (ret < 0) {
+           if (ret == GNUTLS_E_AGAIN)
+               errno = EAGAIN;
+           else
+               errno = EIO;
+           ret = -1;
+       }
+    } else
+#endif /* CONFIG_VNC_TLS */
+       ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
     ret = vnc_client_io_error(vs, ret, socket_error());
     if (!ret)
        return;
@@ -844,6 +953,41 @@ static uint32_t read_u32(uint8_t *data, 
     return ((data[offset] << 24) | (data[offset + 1] << 16) |
            (data[offset + 2] << 8) | data[offset + 3]);
 }
+
+#if CONFIG_VNC_TLS
+ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
+                    const void *data,
+                    size_t len) {
+    struct VncState *vs = (struct VncState *)transport;
+    int ret;
+
+ retry:
+    ret = send(vs->csock, data, len, 0);
+    if (ret < 0) {
+       if (errno == EINTR)
+           goto retry;
+       return -1;
+    }
+    return ret;
+}
+
+
+ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
+                    void *data,
+                    size_t len) {
+    struct VncState *vs = (struct VncState *)transport;
+    int ret;
+
+ retry:
+    ret = recv(vs->csock, data, len, 0);
+    if (ret < 0) {
+       if (errno == EINTR)
+           goto retry;
+       return -1;
+    }
+    return ret;
+}
+#endif /* CONFIG_VNC_TLS */
 
 static void client_cut_text(VncState *vs, size_t len, char *text)
 {
@@ -1387,91 +1531,591 @@ static int protocol_client_init(VncState
     return 0;
 }
 
-static int protocol_response(VncState *vs, uint8_t *client_response, size_t 
len)
-{
-    extern char vncpasswd[64];
-    extern unsigned char challenge[AUTHCHALLENGESIZE];
-    unsigned char cryptchallenge[AUTHCHALLENGESIZE];
-    unsigned char key[8];
-    int passwdlen, i, j;
-
-    memcpy(cryptchallenge, challenge, AUTHCHALLENGESIZE);
-
-    /* Calculate the sent challenge */
-    passwdlen = strlen(vncpasswd);
-    for (i=0; i<8; i++)
-       key[i] = i<passwdlen ? vncpasswd[i] : 0;
-    deskey(key, EN0);
-    for (j = 0; j < AUTHCHALLENGESIZE; j += 8)
-       des(cryptchallenge+j, cryptchallenge+j);
-
-    /* Check the actual response */
-    if (memcmp(cryptchallenge, client_response, AUTHCHALLENGESIZE) != 0) {
-       /* password error */
-       vnc_write_u32(vs, 1);
-       vnc_write_u32(vs, 22);
-       vnc_write(vs, "Authentication failure", 22);
+
+static void make_challenge(VncState *vs)
+{
+    int i;
+
+    srand(time(NULL)+getpid()+getpid()*987654+rand());
+
+    for (i = 0 ; i < sizeof(vs->challenge) ; i++)
+        vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
+}
+
+static int protocol_client_auth_vnc(VncState *vs, char *data, size_t len)
+{
+    char response[VNC_AUTH_CHALLENGE_SIZE];
+    int i, j, pwlen;
+    char key[8];
+
+    if (!vs->password || !vs->password[0]) {
+       VNC_DEBUG("No password configured on server");
+       vnc_write_u32(vs, 1); /* Reject auth */
+       if (vs->minor >= 8) {
+           static const char err[] = "Authentication failed";
+           vnc_write_u32(vs, sizeof(err));
+           vnc_write(vs, err, sizeof(err));
+       }
        vnc_flush(vs);
-       fprintf(stderr, "VNC Password error.\n");
        vnc_client_error(vs);
        return 0;
     }
 
-    vnc_write_u32(vs, 0);
+    memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
+
+    /* Calculate the expected challenge response */
+    pwlen = strlen(vs->password);
+    for (i=0; i<sizeof(key); i++)
+        key[i] = i<pwlen ? vs->password[i] : 0;
+    deskey(key, EN0);
+    for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
+        des(response+j, response+j);
+
+    /* Compare expected vs actual challenge response */
+    if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
+       VNC_DEBUG("Client challenge reponse did not match\n");
+       vnc_write_u32(vs, 1); /* Reject auth */
+       if (vs->minor >= 8) {
+           static const char err[] = "Authentication failed";
+           vnc_write_u32(vs, sizeof(err));
+           vnc_write(vs, err, sizeof(err));
+       }
+       vnc_flush(vs);
+       vnc_client_error(vs);
+    } else {
+       VNC_DEBUG("Accepting VNC challenge response\n");
+       vnc_write_u32(vs, 0); /* Accept auth */
+       vnc_flush(vs);
+
+       vnc_read_when(vs, protocol_client_init, 1);
+    }
+    return 0;
+}
+
+static int start_auth_vnc(VncState *vs)
+{
+    make_challenge(vs);
+    /* Send client a 'random' challenge */
+    vnc_write(vs, vs->challenge, sizeof(vs->challenge));
     vnc_flush(vs);
 
-    vnc_read_when(vs, protocol_client_init, 1);
-
+    vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
     return 0;
 }
 
-static int protocol_version(VncState *vs, uint8_t *version, size_t len)
-{
-    extern char vncpasswd[64];
-    extern unsigned char challenge[AUTHCHALLENGESIZE];
+
+#if CONFIG_VNC_TLS
+#define DH_BITS 1024
+static gnutls_dh_params_t dh_params;
+
+static int vnc_tls_initialize(void)
+{
+    static int tlsinitialized = 0;
+
+    if (tlsinitialized)
+       return 1;
+
+    if (gnutls_global_init () < 0)
+       return 0;
+
+    /* XXX ought to re-generate diffie-hellmen params periodically */
+    if (gnutls_dh_params_init (&dh_params) < 0)
+       return 0;
+    if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
+       return 0;
+
+#if _VNC_DEBUG == 2
+    gnutls_global_set_log_level(10);
+    gnutls_global_set_log_function(vnc_debug_gnutls_log);
+#endif
+
+    tlsinitialized = 1;
+
+    return 1;
+}
+
+static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
+{
+    gnutls_anon_server_credentials anon_cred;
+    int ret;
+
+    if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
+       VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
+       return NULL;
+    }
+
+    gnutls_anon_set_server_dh_params(anon_cred, dh_params);
+
+    return anon_cred;
+}
+
+
+static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState 
*vs)
+{
+    gnutls_certificate_credentials_t x509_cred;
+    int ret;
+
+    if (!vs->x509cacert) {
+       VNC_DEBUG("No CA x509 certificate specified\n");
+       return NULL;
+    }
+    if (!vs->x509cert) {
+       VNC_DEBUG("No server x509 certificate specified\n");
+       return NULL;
+    }
+    if (!vs->x509key) {
+       VNC_DEBUG("No server private key specified\n");
+       return NULL;
+    }
+
+    if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
+       VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
+       return NULL;
+    }
+    if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
+                                                     vs->x509cacert,
+                                                     GNUTLS_X509_FMT_PEM)) < 
0) {
+       VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
+       gnutls_certificate_free_credentials(x509_cred);
+       return NULL;
+    }
+
+    if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
+                                                    vs->x509cert,
+                                                    vs->x509key,
+                                                    GNUTLS_X509_FMT_PEM)) < 0) 
{
+       VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
+       gnutls_certificate_free_credentials(x509_cred);
+       return NULL;
+    }
+
+    if (vs->x509cacrl) {
+       if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
+                                                       vs->x509cacrl,
+                                                       GNUTLS_X509_FMT_PEM)) < 
0) {
+           VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
+           gnutls_certificate_free_credentials(x509_cred);
+           return NULL;
+       }
+    }
+
+    gnutls_certificate_set_dh_params (x509_cred, dh_params);
+
+    return x509_cred;
+}
+
+static int vnc_validate_certificate(struct VncState *vs)
+{
+    int ret;
+    unsigned int status;
+    const gnutls_datum_t *certs;
+    unsigned int nCerts, i;
+    time_t now;
+
+    VNC_DEBUG("Validating client certificate\n");
+    if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 
0) {
+       VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
+       return -1;
+    }
+
+    if ((now = time(NULL)) == ((time_t)-1)) {
+       return -1;
+    }
+
+    if (status != 0) {
+       if (status & GNUTLS_CERT_INVALID)
+           VNC_DEBUG("The certificate is not trusted.\n");
+
+       if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
+           VNC_DEBUG("The certificate hasn't got a known issuer.\n");
+
+       if (status & GNUTLS_CERT_REVOKED)
+           VNC_DEBUG("The certificate has been revoked.\n");
+
+       if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
+           VNC_DEBUG("The certificate uses an insecure algorithm\n");
+
+       return -1;
+    } else {
+       VNC_DEBUG("Certificate is valid!\n");
+    }
+
+    /* Only support x509 for now */
+    if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
+       return -1;
+
+    if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
+       return -1;
+
+    for (i = 0 ; i < nCerts ; i++) {
+       gnutls_x509_crt_t cert;
+       VNC_DEBUG ("Checking certificate chain %d\n", i);
+       if (gnutls_x509_crt_init (&cert) < 0)
+           return -1;
+
+       if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
+           gnutls_x509_crt_deinit (cert);
+           return -1;
+       }
+
+       if (gnutls_x509_crt_get_expiration_time (cert) < now) {
+           VNC_DEBUG("The certificate has expired\n");
+           gnutls_x509_crt_deinit (cert);
+           return -1;
+       }
+
+       if (gnutls_x509_crt_get_activation_time (cert) > now) {
+           VNC_DEBUG("The certificate is not yet activated\n");
+           gnutls_x509_crt_deinit (cert);
+           return -1;
+       }
+
+       if (gnutls_x509_crt_get_activation_time (cert) > now) {
+           VNC_DEBUG("The certificate is not yet activated\n");
+           gnutls_x509_crt_deinit (cert);
+           return -1;
+       }
+
+       gnutls_x509_crt_deinit (cert);
+    }
+
+    return 0;
+}
+
+
+static int start_auth_vencrypt_subauth(VncState *vs)
+{
+    switch (vs->subauth) {
+    case VNC_AUTH_VENCRYPT_TLSNONE:
+    case VNC_AUTH_VENCRYPT_X509NONE:
+       VNC_DEBUG("Accept TLS auth none\n");
+       vnc_write_u32(vs, 0); /* Accept auth completion */
+       vnc_read_when(vs, protocol_client_init, 1);
+       break;
+
+    case VNC_AUTH_VENCRYPT_TLSVNC:
+    case VNC_AUTH_VENCRYPT_X509VNC:
+       VNC_DEBUG("Start TLS auth VNC\n");
+       return start_auth_vnc(vs);
+
+    default: /* Should not be possible, but just in case */
+       VNC_DEBUG("Reject auth %d\n", vs->auth);
+       vnc_write_u8(vs, 1);
+       if (vs->minor >= 8) {
+           static const char err[] = "Unsupported authentication type";
+           vnc_write_u32(vs, sizeof(err));
+           vnc_write(vs, err, sizeof(err));
+       }
+       vnc_client_error(vs);
+    }
+
+    return 0;
+}
+
+static void vnc_handshake_io(void *opaque);
+
+static int vnc_continue_handshake(struct VncState *vs) {
+    int ret;
+
+    if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
+       if (!gnutls_error_is_fatal(ret)) {
+           VNC_DEBUG("Handshake interrupted (blocking)\n");
+           if (!gnutls_record_get_direction(vs->tls_session))
+               qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
+           else
+               qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
+           return 0;
+       }
+       VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
+       vnc_client_error(vs);
+       return -1;
+    }
+
+    if (vs->x509verify) {
+       if (vnc_validate_certificate(vs) < 0) {
+           VNC_DEBUG("Client verification failed\n");
+           vnc_client_error(vs);
+           return -1;
+       } else {
+           VNC_DEBUG("Client verification passed\n");
+       }
+    }
+
+    VNC_DEBUG("Handshake done, switching to TLS data mode\n");
+    vs->wiremode = VNC_WIREMODE_TLS;
+    qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, 
vs);
+
+    return start_auth_vencrypt_subauth(vs);
+}
+
+static void vnc_handshake_io(void *opaque) {
+    struct VncState *vs = (struct VncState *)opaque;
+
+    VNC_DEBUG("Handshake IO continue\n");
+    vnc_continue_handshake(vs);
+}
+
+#define NEED_X509_AUTH(vs)                           \
+    ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \
+     (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \
+     (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
+
+
+static int vnc_start_tls(struct VncState *vs) {
+    static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
+    static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, 
GNUTLS_SSL3, 0 };
+    static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
+    static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, 
GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
+
+    VNC_DEBUG("Do TLS setup\n");
+    if (vnc_tls_initialize() < 0) {
+       VNC_DEBUG("Failed to init TLS\n");
+       vnc_client_error(vs);
+       return -1;
+    }
+    if (vs->tls_session == NULL) {
+       if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
+           vnc_client_error(vs);
+           return -1;
+       }
+
+       if (gnutls_set_default_priority(vs->tls_session) < 0) {
+           gnutls_deinit(vs->tls_session);
+           vs->tls_session = NULL;
+           vnc_client_error(vs);
+           return -1;
+       }
+
+       if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? 
kx_x509 : kx_anon) < 0) {
+           gnutls_deinit(vs->tls_session);
+           vs->tls_session = NULL;
+           vnc_client_error(vs);
+           return -1;
+       }
+
+       if (gnutls_certificate_type_set_priority(vs->tls_session, 
cert_type_priority) < 0) {
+           gnutls_deinit(vs->tls_session);
+           vs->tls_session = NULL;
+           vnc_client_error(vs);
+           return -1;
+       }
+
+       if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 
0) {
+           gnutls_deinit(vs->tls_session);
+           vs->tls_session = NULL;
+           vnc_client_error(vs);
+           return -1;
+       }
+
+       if (NEED_X509_AUTH(vs)) {
+           gnutls_certificate_server_credentials x509_cred = 
vnc_tls_initialize_x509_cred(vs);
+           if (!x509_cred) {
+               gnutls_deinit(vs->tls_session);
+               vs->tls_session = NULL;
+               vnc_client_error(vs);
+               return -1;
+           }
+           if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, 
x509_cred) < 0) {
+               gnutls_deinit(vs->tls_session);
+               vs->tls_session = NULL;
+               gnutls_certificate_free_credentials(x509_cred);
+               vnc_client_error(vs);
+               return -1;
+           }
+           if (vs->x509verify) {
+               VNC_DEBUG("Requesting a client certificate\n");
+               gnutls_certificate_server_set_request (vs->tls_session, 
GNUTLS_CERT_REQUEST);
+           }
+
+       } else {
+           gnutls_anon_server_credentials anon_cred = 
vnc_tls_initialize_anon_cred();
+           if (!anon_cred) {
+               gnutls_deinit(vs->tls_session);
+               vs->tls_session = NULL;
+               vnc_client_error(vs);
+               return -1;
+           }
+           if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, 
anon_cred) < 0) {
+               gnutls_deinit(vs->tls_session);
+               vs->tls_session = NULL;
+               gnutls_anon_free_server_credentials(anon_cred);
+               vnc_client_error(vs);
+               return -1;
+           }
+       }
+
+       gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
+       gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
+       gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
+    }
+
+    VNC_DEBUG("Start TLS handshake process\n");
+    return vnc_continue_handshake(vs);
+}
+
+static int protocol_client_vencrypt_auth(VncState *vs, char *data, size_t len)
+{
+    int auth = read_u32(data, 0);
+
+    if (auth != vs->subauth) {
+       VNC_DEBUG("Rejecting auth %d\n", auth);
+       vnc_write_u8(vs, 0); /* Reject auth */
+       vnc_flush(vs);
+       vnc_client_error(vs);
+    } else {
+       VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
+       vnc_write_u8(vs, 1); /* Accept auth */
+       vnc_flush(vs);
+
+       if (vnc_start_tls(vs) < 0) {
+           VNC_DEBUG("Failed to complete TLS\n");
+           return 0;
+       }
+
+       if (vs->wiremode == VNC_WIREMODE_TLS) {
+           VNC_DEBUG("Starting VeNCrypt subauth\n");
+           return start_auth_vencrypt_subauth(vs);
+       } else {
+           VNC_DEBUG("TLS handshake blocked\n");
+           return 0;
+       }
+    }
+    return 0;
+}
+
+static int protocol_client_vencrypt_init(VncState *vs, char *data, size_t len)
+{
+    if (data[0] != 0 ||
+       data[1] != 2) {
+       VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], 
(int)data[1]);
+       vnc_write_u8(vs, 1); /* Reject version */
+       vnc_flush(vs);
+       vnc_client_error(vs);
+    } else {
+       VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
+       vnc_write_u8(vs, 0); /* Accept version */
+       vnc_write_u8(vs, 1); /* Number of sub-auths */
+       vnc_write_u32(vs, vs->subauth); /* The supported auth */
+       vnc_flush(vs);
+       vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
+    }
+    return 0;
+}
+
+static int start_auth_vencrypt(VncState *vs)
+{
+    /* Send VeNCrypt version 0.2 */
+    vnc_write_u8(vs, 0);
+    vnc_write_u8(vs, 2);
+
+    vnc_read_when(vs, protocol_client_vencrypt_init, 2);
+    return 0;
+}
+#endif /* CONFIG_VNC_TLS */
+
+static int protocol_client_auth(VncState *vs, char *data, size_t len)
+{
+    /* We only advertise 1 auth scheme at a time, so client
+     * must pick the one we sent. Verify this */
+    if (data[0] != vs->auth) { /* Reject auth */
+       VNC_DEBUG("Reject auth %d\n", (int)data[0]);
+       vnc_write_u32(vs, 1);
+       if (vs->minor >= 8) {
+           static const char err[] = "Authentication failed";
+           vnc_write_u32(vs, sizeof(err));
+           vnc_write(vs, err, sizeof(err));
+       }
+       vnc_client_error(vs);
+    } else { /* Accept requested auth */
+       VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
+       switch (vs->auth) {
+       case VNC_AUTH_NONE:
+           VNC_DEBUG("Accept auth none\n");
+           if (vs->minor >= 8) {
+               vnc_write_u32(vs, 0); /* Accept auth completion */
+               vnc_flush(vs);
+           }
+           vnc_read_when(vs, protocol_client_init, 1);
+           break;
+
+       case VNC_AUTH_VNC:
+           VNC_DEBUG("Start VNC auth\n");
+           return start_auth_vnc(vs);
+
+#if CONFIG_VNC_TLS
+       case VNC_AUTH_VENCRYPT:
+           VNC_DEBUG("Accept VeNCrypt auth\n");;
+           return start_auth_vencrypt(vs);
+#endif /* CONFIG_VNC_TLS */
+
+       default: /* Should not be possible, but just in case */
+           VNC_DEBUG("Reject auth %d\n", vs->auth);
+           vnc_write_u8(vs, 1);
+           if (vs->minor >= 8) {
+               static const char err[] = "Authentication failed";
+               vnc_write_u32(vs, sizeof(err));
+               vnc_write(vs, err, sizeof(err));
+           }
+           vnc_client_error(vs);
+       }
+    }
+    return 0;
+}
+
+static int protocol_version(VncState *vs, char *version, size_t len)
+{
     char local[13];
-    int  support, maj, min;
 
     memcpy(local, version, 12);
     local[12] = 0;
 
-    /* protocol version check */
-    if (sscanf(local, "RFB %03d.%03d\n", &maj, &min) != 2) {
-       fprintf(stderr, "Protocol version error.\n");
+    if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
+       VNC_DEBUG("Malformed protocol version %s\n", local);
        vnc_client_error(vs);
        return 0;
     }
-
-
-    support = 0;
-    if (maj == 3) {
-       if (min == 3 || min ==4) {
-           support = 1;
-       }
-    }
-
-    if (! support) {
-       fprintf(stderr, "Client uses unsupported protocol version %d.%d.\n",
-               maj, min);
+    VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
+    if (vs->major != 3 ||
+       (vs->minor != 3 &&
+        vs->minor != 4 &&
+        vs->minor != 5 &&
+        vs->minor != 7 &&
+        vs->minor != 8)) {
+       VNC_DEBUG("Unsupported client version\n");
+       vnc_write_u32(vs, VNC_AUTH_INVALID);
+       vnc_flush(vs);
        vnc_client_error(vs);
        return 0;
     }
-
-    if (*vncpasswd == '\0') {
-       /* AuthType is None */
-       vnc_write_u32(vs, 1);
+    /* Some broken clients report v3.4 or v3.5, which spec requires to be 
treated
+     * as equivalent to v3.3 by servers
+     */
+    if (vs->minor == 4 || vs->minor == 5)
+       vs->minor = 3;
+
+    if (vs->minor == 3) {
+       if (vs->auth == VNC_AUTH_NONE) {
+            VNC_DEBUG("Tell client auth none\n");
+            vnc_write_u32(vs, vs->auth);
+            vnc_flush(vs);
+            vnc_read_when(vs, protocol_client_init, 1);
+       } else if (vs->auth == VNC_AUTH_VNC) {
+            VNC_DEBUG("Tell client VNC auth\n");
+            vnc_write_u32(vs, vs->auth);
+            vnc_flush(vs);
+            start_auth_vnc(vs);
+       } else {
+            VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
+            vnc_write_u32(vs, VNC_AUTH_INVALID);
+            vnc_flush(vs);
+            vnc_client_error(vs);
+       }
+    } else {
+       VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
+       vnc_write_u8(vs, 1); /* num auth */
+       vnc_write_u8(vs, vs->auth);
+       vnc_read_when(vs, protocol_client_auth, 1);
        vnc_flush(vs);
-       vnc_read_when(vs, protocol_client_init, 1);
-    } else {
-       /* AuthType is VncAuth */
-       vnc_write_u32(vs, 2);
-
-       /* Challenge-Responce authentication */
-       /* Send Challenge */
-       make_challenge(challenge, AUTHCHALLENGESIZE);
-       vnc_write(vs, challenge, AUTHCHALLENGESIZE);
-       vnc_flush(vs);
-       vnc_read_when(vs, protocol_response, AUTHCHALLENGESIZE);
     }
 
     return 0;
@@ -1485,9 +2129,10 @@ static void vnc_listen_read(void *opaque
 
     vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
     if (vs->csock != -1) {
+       VNC_DEBUG("New client on socket %d\n", vs->csock);
         socket_set_nonblock(vs->csock);
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
-       vnc_write(vs, "RFB 003.003\n", 12);
+       vnc_write(vs, "RFB 003.008\n", 12);
        vnc_flush(vs);
        vnc_read_when(vs, protocol_version, 12);
        framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height);
@@ -1500,7 +2145,155 @@ static void vnc_listen_read(void *opaque
 
 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
 
-int vnc_display_init(DisplayState *ds, const char *arg, int find_unused)
+void vnc_display_init(DisplayState *ds)
+{
+    VncState *vs;
+
+    vs = qemu_mallocz(sizeof(VncState));
+    if (!vs)
+       exit(1);
+
+    ds->opaque = vs;
+    vnc_state = vs;
+    vs->display = NULL;
+    vs->password = NULL;
+
+    vs->lsock = -1;
+    vs->csock = -1;
+    vs->depth = 4;
+    vs->last_x = -1;
+    vs->last_y = -1;
+
+    vs->ds = ds;
+
+    if (!keyboard_layout)
+       keyboard_layout = "en-us";
+
+    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
+    if (!vs->kbd_layout)
+       exit(1);
+    vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
+
+    vs->ds->data = NULL;
+    vs->ds->dpy_update = vnc_dpy_update;
+    vs->ds->dpy_resize = vnc_dpy_resize;
+    vs->ds->dpy_refresh = vnc_dpy_refresh;
+
+    vnc_dpy_resize(vs->ds, 640, 400);
+}
+
+#if CONFIG_VNC_TLS
+static int vnc_set_x509_credential(VncState *vs,
+                                  const char *certdir,
+                                  const char *filename,
+                                  char **cred,
+                                  int ignoreMissing)
+{
+    struct stat sb;
+
+    if (*cred) {
+       qemu_free(*cred);
+       *cred = NULL;
+    }
+
+    if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
+       return -1;
+
+    strcpy(*cred, certdir);
+    strcat(*cred, "/");
+    strcat(*cred, filename);
+
+    VNC_DEBUG("Check %s\n", *cred);
+    if (stat(*cred, &sb) < 0) {
+       qemu_free(*cred);
+       *cred = NULL;
+       if (ignoreMissing && errno == ENOENT)
+           return 0;
+       return -1;
+    }
+
+    return 0;
+}
+
+static int vnc_set_x509_credential_dir(VncState *vs,
+                                      const char *certdir)
+{
+    if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, 
&vs->x509cacert, 0) < 0)
+       goto cleanup;
+    if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 
1) < 0)
+       goto cleanup;
+    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, 
&vs->x509cert, 0) < 0)
+       goto cleanup;
+    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, 
&vs->x509key, 0) < 0)
+       goto cleanup;
+
+    return 0;
+
+ cleanup:
+    qemu_free(vs->x509cacert);
+    qemu_free(vs->x509cacrl);
+    qemu_free(vs->x509cert);
+    qemu_free(vs->x509key);
+    vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
+    return -1;
+}
+#endif /* CONFIG_VNC_TLS */
+
+void vnc_display_close(DisplayState *ds)
+{
+    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
+
+    if (vs->display) {
+       qemu_free(vs->display);
+       vs->display = NULL;
+    }
+    if (vs->lsock != -1) {
+       qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
+       close(vs->lsock);
+       vs->lsock = -1;
+    }
+    if (vs->csock != -1) {
+       qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
+       closesocket(vs->csock);
+       vs->csock = -1;
+       buffer_reset(&vs->input);
+       buffer_reset(&vs->output);
+#if CONFIG_VNC_TLS
+       if (vs->tls_session) {
+           gnutls_deinit(vs->tls_session);
+           vs->tls_session = NULL;
+       }
+       vs->wiremode = VNC_WIREMODE_CLEAR;
+#endif /* CONFIG_VNC_TLS */
+    }
+    vs->auth = VNC_AUTH_INVALID;
+#if CONFIG_VNC_TLS
+    vs->subauth = VNC_AUTH_INVALID;
+    vs->x509verify = 0;
+#endif
+}
+
+int parse_host_port(struct sockaddr_in *saddr, const char *str);
+
+
+
+int vnc_display_password(DisplayState *ds, const char *password)
+{
+    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
+
+    if (vs->password) {
+       qemu_free(vs->password);
+       vs->password = NULL;
+    }
+    if (password && password[0]) {
+       if (!(vs->password = qemu_strdup(password)))
+           return -1;
+    }
+
+    return 0;
+}
+
+int vnc_display_open(DisplayState *ds, const char *display, int find_unused)
 {
     struct sockaddr *addr;
     struct sockaddr_in iaddr;
@@ -1510,51 +2303,115 @@ int vnc_display_init(DisplayState *ds, c
     int reuse_addr, ret;
     socklen_t addrlen;
     const char *p;
-    VncState *vs;
-
-    vs = qemu_mallocz(sizeof(VncState));
-    if (!vs)
-       exit(1);
-
-    ds->opaque = vs;
-    vnc_state = vs;
-    vs->display = arg;
-
-    vs->lsock = -1;
-    vs->csock = -1;
-    vs->depth = 4;
-    vs->last_x = -1;
-    vs->last_y = -1;
-
-    vs->ds = ds;
-
-    if (!keyboard_layout)
-       keyboard_layout = "en-us";
-
-    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
-    if (!vs->kbd_layout)
-       exit(1);
-    vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
-
-    vs->ds->data = NULL;
-    vs->ds->dpy_update = vnc_dpy_update;
-    vs->ds->dpy_resize = vnc_dpy_resize;
-    vs->ds->dpy_refresh = vnc_dpy_refresh;
-
-    vnc_dpy_resize(vs->ds, 640, 400);
-
-    if (arg == NULL)
-       arg = "localhost:0";
-    
+    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
+    const char *options;
+    int password = 0;
+#if CONFIG_VNC_TLS
+    int tls = 0, x509 = 0;
+#endif
+
+    if (display == NULL)
+       display = "localhost:0";
+
+    vnc_display_close(ds);
+    if (strcmp(display, "none") == 0)
+        return 0;
+
+    if (!(vs->display = strdup(display)))
+        return -1;
+
+    options = display;
+    while ((options = strchr(options, ','))) {
+       options++;
+       if (strncmp(options, "password", 8) == 0) {
+           password = 1; /* Require password auth */
+#if CONFIG_VNC_TLS
+       } else if (strncmp(options, "tls", 3) == 0) {
+           tls = 1; /* Require TLS */
+       } else if (strncmp(options, "x509", 4) == 0) {
+           char *start, *end;
+           x509 = 1; /* Require x509 certificates */
+           if (strncmp(options, "x509verify", 10) == 0)
+               vs->x509verify = 1; /* ...and verify client certs */
+
+           /* Now check for 'x509=/some/path' postfix
+            * and use that to setup x509 certificate/key paths */
+           start = strchr(options, '=');
+           end = strchr(options, ',');
+           if (start && (!end || (start < end))) {
+               int len = end ? end-(start+1) : strlen(start+1);
+               char *path = qemu_malloc(len+1);
+               strncpy(path, start+1, len);
+               path[len] = '\0';
+               VNC_DEBUG("Trying certificate path '%s'\n", path);
+               if (vnc_set_x509_credential_dir(vs, path) < 0) {
+                   fprintf(stderr, "Failed to find x509 certificates/keys in 
%s\n", path);
+                   qemu_free(path);
+                   qemu_free(vs->display);
+                   vs->display = NULL;
+                   return -1;
+               }
+               qemu_free(path);
+           } else {
+               fprintf(stderr, "No certificate path provided\n");
+               qemu_free(vs->display);
+               vs->display = NULL;
+               return -1;
+           }
+#endif
+       }
+    }
+
+    if (password) {
+#if CONFIG_VNC_TLS
+       if (tls) {
+           vs->auth = VNC_AUTH_VENCRYPT;
+           if (x509) {
+               VNC_DEBUG("Initializing VNC server with x509 password auth\n");
+               vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
+           } else {
+               VNC_DEBUG("Initializing VNC server with TLS password auth\n");
+               vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
+           }
+       } else {
+#endif
+           VNC_DEBUG("Initializing VNC server with password auth\n");
+           vs->auth = VNC_AUTH_VNC;
+#if CONFIG_VNC_TLS
+           vs->subauth = VNC_AUTH_INVALID;
+       }
+#endif
+    } else {
+#if CONFIG_VNC_TLS
+       if (tls) {
+           vs->auth = VNC_AUTH_VENCRYPT;
+           if (x509) {
+               VNC_DEBUG("Initializing VNC server with x509 no auth\n");
+               vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
+           } else {
+               VNC_DEBUG("Initializing VNC server with TLS no auth\n");
+               vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
+           }
+       } else {
+#endif
+           VNC_DEBUG("Initializing VNC server with no auth\n");
+           vs->auth = VNC_AUTH_NONE;
+#if CONFIG_VNC_TLS
+           vs->subauth = VNC_AUTH_INVALID;
+       }
+#endif
+    }
 #ifndef _WIN32
-    if (strstart(arg, "unix:", &p)) {
+    if (strstart(display, "unix:", &p)) {
        addr = (struct sockaddr *)&uaddr;
        addrlen = sizeof(uaddr);
 
        vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
        if (vs->lsock == -1) {
            fprintf(stderr, "Could not create socket\n");
-           exit(1);
+           free(vs->display);
+           vs->display = NULL;
+           return -1;
        }
 
        uaddr.sun_family = AF_UNIX;
@@ -1568,25 +2425,33 @@ int vnc_display_init(DisplayState *ds, c
        addr = (struct sockaddr *)&iaddr;
        addrlen = sizeof(iaddr);
 
+       if (parse_host_port(&iaddr, display) < 0) {
+           fprintf(stderr, "Could not parse VNC address\n");
+           free(vs->display);
+           vs->display = NULL;
+           return -1;
+       }
+
+       iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
+
        vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
        if (vs->lsock == -1) {
            fprintf(stderr, "Could not create socket\n");
-           exit(1);
-       }
-
-       if (parse_host_port(&iaddr, arg) < 0) {
-           fprintf(stderr, "Could not parse VNC address\n");
-           exit(1);
-       }
-           
-       iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
+           free(vs->display);
+           vs->display = NULL;
+           return -1;
+       }
 
        reuse_addr = 1;
        ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
                         (const char *)&reuse_addr, sizeof(reuse_addr));
        if (ret == -1) {
            fprintf(stderr, "setsockopt() failed\n");
-           exit(1);
+           close(vs->lsock);
+           vs->lsock = -1;
+           free(vs->display);
+           vs->display = NULL;
+           return -1;
        }
     }
 
@@ -1596,18 +2461,24 @@ int vnc_display_init(DisplayState *ds, c
            continue;
        }
        fprintf(stderr, "bind() failed\n");
-       exit(1);
+       close(vs->lsock);
+       vs->lsock = -1;
+       free(vs->display);
+       vs->display = NULL;
+       return -1;
     }
 
     if (listen(vs->lsock, 1) == -1) {
        fprintf(stderr, "listen() failed\n");
-       exit(1);
-    }
-
-    ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, 
NULL, vs);
-    if (ret == -1) {
-       exit(1);
-    }
+       close(vs->lsock);
+       vs->lsock = -1;
+       free(vs->display);
+       vs->display = NULL;
+       return -1;
+    }
+
+    if (qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, 
NULL, vs) < 0)
+       return -1;
 
     return ntohs(iaddr.sin_port);
 }
@@ -1640,31 +2511,3 @@ int vnc_start_viewer(int port)
     }
 }
 
-unsigned int seed;
-
-static int make_challenge(unsigned char *random, int size)
-{
- 
-    set_seed(&seed);
-    get_random(size, random);
-
-    return 0;
-}
-
-static void set_seed(unsigned int *seedp)
-{
-    *seedp += (unsigned int)(time(NULL)+getpid()+getpid()*987654+rand());
-    srand(*seedp);
-
-    return;
-}
-
-static void get_random(int len, unsigned char *buf)
-{
-    int i;
-
-    for (i=0; i<len; i++)
-       buf[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-
-    return;
-}
diff -r c17bfb091790 -r a07288a84785 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c    Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/ioemu/xenstore.c    Tue Oct 30 15:34:44 2007 -0600
@@ -17,7 +17,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
-static struct xs_handle *xsh = NULL;
+struct xs_handle *xsh = NULL;
 static char *media_filename[MAX_DISKS + MAX_SCSI_DISKS];
 static QEMUTimer *insert_timer = NULL;
 
@@ -303,12 +303,19 @@ void xenstore_process_logdirty_event(voi
         logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
 
         /* Map the shared-memory segment */
-        if ((shmid = shmget(key, 
-                            2 * logdirty_bitmap_size, 
-                            S_IRUSR|S_IWUSR)) == -1 
-            || (seg = shmat(shmid, NULL, 0)) == (void *)-1) {
-            fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n",
-                    (unsigned long long) key, strerror(errno));
+        fprintf(logfile, "%s: key=%16.16llx size=%d\n", __FUNCTION__,
+                (unsigned long long)key, logdirty_bitmap_size);
+        shmid = shmget(key, 2 * logdirty_bitmap_size, S_IRUSR|S_IWUSR);
+        if (shmid == -1) {
+            fprintf(logfile, "Log-dirty: shmget failed: segment %16.16llx "
+                    "(%s)\n", (unsigned long long)key, strerror(errno));
+            exit(1);
+        }
+
+        seg = shmat(shmid, NULL, 0);
+        if (seg == (void *)-1) {
+            fprintf(logfile, "Log-dirty: shmat failed: segment %16.16llx "
+                    "(%s)\n", (unsigned long long)key, strerror(errno));
             exit(1);
         }
 
@@ -318,6 +325,9 @@ void xenstore_process_logdirty_event(voi
         if (logdirty_bitmap_size != *(uint32_t *)seg) {
             fprintf(logfile, "Log-dirty: got %u, calc %lu\n", 
                     *(uint32_t *)seg, logdirty_bitmap_size);
+            /* Stale key: wait for next watch */
+            shmdt(seg);
+            seg = NULL;
             return;
         }
 
@@ -478,9 +488,8 @@ void xenstore_write_vncport(int display)
     free(buf);
 }
 
-int xenstore_read_vncpasswd(int domid)
-{
-    extern char vncpasswd[64];
+int xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen)
+{
     char *buf = NULL, *path, *uuid = NULL, *passwd = NULL;
     unsigned int i, len, rc = 0;
 
@@ -506,16 +515,17 @@ int xenstore_read_vncpasswd(int domid)
     passwd = xs_read(xsh, XBT_NULL, buf, &len);
     if (passwd == NULL) {
         fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf);
+        pwbuf[0] = '\0';
         free(uuid);
         free(path);
         return rc;
     }
 
-    for (i=0; i<len && i<63; i++) {
-        vncpasswd[i] = passwd[i];
-        passwd[i] = '\0';
-    }
-    vncpasswd[len] = '\0';
+    for (i=0; i<len && i<pwbuflen; i++) {
+        pwbuf[i] = passwd[i];
+    }
+    pwbuf[len < (pwbuflen-1) ? len : (pwbuflen-1)] = '\0';
+    passwd[0] = '\0';
     pasprintf(&buf, "%s/vncpasswd", uuid);
     if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
         fprintf(logfile, "xs_write() vncpasswd failed.\n");
@@ -724,7 +734,7 @@ int xenstore_vm_write(int domid, char *k
 
     pasprintf(&buf, "%s/%s", path, key);
     rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value));
-    if (rc) {
+    if (rc == 0) {
         fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key);
         goto out;
     }
diff -r c17bfb091790 -r a07288a84785 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/libxc/xc_domain.c   Tue Oct 30 15:34:44 2007 -0600
@@ -378,9 +378,9 @@ int xc_domain_setmaxmem(int xc_handle,
 
 int xc_domain_pin_memory_cacheattr(int xc_handle,
                                    uint32_t domid,
-                                   unsigned long start,
-                                   unsigned long end,
-                                   unsigned int type)
+                                   uint64_t start,
+                                   uint64_t end,
+                                   uint32_t type)
 {
     DECLARE_DOMCTL;
     domctl.cmd = XEN_DOMCTL_pin_mem_cacheattr;
diff -r c17bfb091790 -r a07288a84785 tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c   Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/libxc/xc_domain_restore.c   Tue Oct 30 15:34:44 2007 -0600
@@ -169,7 +169,8 @@ static int uncanonicalize_pagetable(int 
 
 
 /* Load the p2m frame list, plus potential extended info chunk */
-static xen_pfn_t *load_p2m_frame_list(int io_fd, int *pae_extended_cr3)
+static xen_pfn_t *load_p2m_frame_list(
+    int io_fd, int *pae_extended_cr3, int *ext_vcpucontext)
 {
     xen_pfn_t *p2m_frame_list;
     vcpu_guest_context_either_t ctxt;
@@ -200,7 +201,8 @@ static xen_pfn_t *load_p2m_frame_list(in
             
             /* 4-character chunk signature + 4-byte remaining chunk size. */
             if ( !read_exact(io_fd, chunk_sig, sizeof(chunk_sig)) ||
-                 !read_exact(io_fd, &chunk_bytes, sizeof(chunk_bytes)) )
+                 !read_exact(io_fd, &chunk_bytes, sizeof(chunk_bytes)) ||
+                 (tot_bytes < (chunk_bytes + 8)) )
             {
                 ERROR("read extended-info chunk signature failed");
                 return NULL;
@@ -240,6 +242,10 @@ static xen_pfn_t *load_p2m_frame_list(in
                      & (1UL << VMASST_TYPE_pae_extended_cr3) )
                     *pae_extended_cr3 = 1;
             }
+            else if ( !strncmp(chunk_sig, "extv", 4) )
+            {
+                *ext_vcpucontext = 1;
+            }
             
             /* Any remaining bytes of this chunk: read and discard. */
             while ( chunk_bytes )
@@ -289,7 +295,7 @@ int xc_domain_restore(int xc_handle, int
                       unsigned int hvm, unsigned int pae)
 {
     DECLARE_DOMCTL;
-    int rc = 1, i, j, n, m, pae_extended_cr3 = 0;
+    int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0;
     unsigned long mfn, pfn;
     unsigned int prev_pc, this_pc;
     int verify = 0;
@@ -373,7 +379,8 @@ int xc_domain_restore(int xc_handle, int
     if ( !hvm ) 
     {
         /* Load the p2m frame list, plus potential extended info chunk */
-        p2m_frame_list = load_p2m_frame_list(io_fd, &pae_extended_cr3);
+        p2m_frame_list = load_p2m_frame_list(
+            io_fd, &pae_extended_cr3, &ext_vcpucontext);
         if ( !p2m_frame_list )
             goto out;
 
@@ -382,13 +389,12 @@ int xc_domain_restore(int xc_handle, int
         domctl.domain = dom;
         domctl.cmd    = XEN_DOMCTL_set_address_size;
         domctl.u.address_size.size = guest_width * 8;
-        rc = do_domctl(xc_handle, &domctl);
-        if ( rc != 0 )
+        frc = do_domctl(xc_handle, &domctl);
+        if ( frc != 0 )
         {
             ERROR("Unable to set guest address size.");
             goto out;
         }
-        rc = 1;
     }
 
     /* We want zeroed memory so use calloc rather than malloc. */
@@ -713,18 +719,19 @@ int xc_domain_restore(int xc_handle, int
             goto out;
         }
                 
-        if ( (rc = xc_set_hvm_param(xc_handle, dom, 
-                                    HVM_PARAM_IOREQ_PFN, magic_pfns[0]))
-             || (rc = xc_set_hvm_param(xc_handle, dom, 
-                                       HVM_PARAM_BUFIOREQ_PFN, magic_pfns[1]))
-             || (rc = xc_set_hvm_param(xc_handle, dom, 
-                                       HVM_PARAM_STORE_PFN, magic_pfns[2]))
-             || (rc = xc_set_hvm_param(xc_handle, dom, 
-                                       HVM_PARAM_PAE_ENABLED, pae))
-             || (rc = xc_set_hvm_param(xc_handle, dom, 
-                                       HVM_PARAM_STORE_EVTCHN, store_evtchn)) )
-        {
-            ERROR("error setting HVM params: %i", rc);
+        if ( (frc = xc_set_hvm_param(xc_handle, dom, 
+                                     HVM_PARAM_IOREQ_PFN, magic_pfns[0]))
+             || (frc = xc_set_hvm_param(xc_handle, dom, 
+                                        HVM_PARAM_BUFIOREQ_PFN, magic_pfns[1]))
+             || (frc = xc_set_hvm_param(xc_handle, dom, 
+                                        HVM_PARAM_STORE_PFN, magic_pfns[2]))
+             || (frc = xc_set_hvm_param(xc_handle, dom, 
+                                        HVM_PARAM_PAE_ENABLED, pae))
+             || (frc = xc_set_hvm_param(xc_handle, dom, 
+                                        HVM_PARAM_STORE_EVTCHN,
+                                        store_evtchn)) )
+        {
+            ERROR("error setting HVM params: %i", frc);
             goto out;
         }
         *store_mfn = magic_pfns[2];
@@ -750,10 +757,15 @@ int xc_domain_restore(int xc_handle, int
             goto out;
         }
         
-        rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len);
-        if ( rc ) 
+        frc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len);
+        if ( frc )
+        {
             ERROR("error setting the HVM context");
-       
+            goto out;
+        }
+
+        /* HVM success! */
+        rc = 0;
         goto out;
     }
 
@@ -929,7 +941,7 @@ int xc_domain_restore(int xc_handle, int
     {
         unsigned int count = 0;
         unsigned long *pfntab;
-        int nr_frees, rc;
+        int nr_frees;
 
         if ( !read_exact(io_fd, &count, sizeof(count)) ||
              (count > (1U << 28)) ) /* up to 1TB of address space */
@@ -973,10 +985,10 @@ int xc_domain_restore(int xc_handle, int
             };
             set_xen_guest_handle(reservation.extent_start, pfntab);
 
-            if ( (rc = xc_memory_op(xc_handle, XENMEM_decrease_reservation,
-                                    &reservation)) != nr_frees )
-            {
-                ERROR("Could not decrease reservation : %d", rc);
+            if ( (frc = xc_memory_op(xc_handle, XENMEM_decrease_reservation,
+                                     &reservation)) != nr_frees )
+            {
+                ERROR("Could not decrease reservation : %d", frc);
                 goto out;
             }
             else
@@ -1091,13 +1103,29 @@ int xc_domain_restore(int xc_handle, int
         domctl.domain = (domid_t)dom;
         domctl.u.vcpucontext.vcpu = i;
         set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt.c);
-        rc = xc_domctl(xc_handle, &domctl);
-        if ( rc != 0 )
+        frc = xc_domctl(xc_handle, &domctl);
+        if ( frc != 0 )
         {
             ERROR("Couldn't build vcpu%d", i);
             goto out;
         }
-        rc = 1;
+
+        if ( !ext_vcpucontext )
+            continue;
+        if ( !read_exact(io_fd, &domctl.u.ext_vcpucontext, 128) ||
+             (domctl.u.ext_vcpucontext.vcpu != i) )
+        {
+            ERROR("Error when reading extended ctxt %d", i);
+            goto out;
+        }
+        domctl.cmd = XEN_DOMCTL_set_ext_vcpucontext;
+        domctl.domain = dom;
+        frc = xc_domctl(xc_handle, &domctl);
+        if ( frc != 0 )
+        {
+            ERROR("Couldn't set extended vcpu%d info\n", i);
+            goto out;
+        }
     }
 
     if ( !read_exact(io_fd, shared_info_page, PAGE_SIZE) )
diff -r c17bfb091790 -r a07288a84785 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/libxc/xc_domain_save.c      Tue Oct 30 15:34:44 2007 -0600
@@ -777,16 +777,18 @@ static xen_pfn_t *map_and_save_p2m_table
      */
     {
         unsigned long signature = ~0UL;
-        uint32_t chunk_sz = ((guest_width==8) 
-                             ? sizeof(ctxt.x64) 
-                             : sizeof(ctxt.x32));
-        uint32_t tot_sz   = chunk_sz + 8;
-        char chunk_sig[]  = "vcpu";
+        uint32_t chunk1_sz = ((guest_width==8) 
+                              ? sizeof(ctxt.x64) 
+                              : sizeof(ctxt.x32));
+        uint32_t chunk2_sz = 0;
+        uint32_t tot_sz    = (chunk1_sz + 8) + (chunk2_sz + 8);
         if ( !write_exact(io_fd, &signature, sizeof(signature)) ||
-             !write_exact(io_fd, &tot_sz,    sizeof(tot_sz)) ||
-             !write_exact(io_fd, &chunk_sig, 4) ||
-             !write_exact(io_fd, &chunk_sz,  sizeof(chunk_sz)) ||
-             !write_exact(io_fd, &ctxt,      chunk_sz) )
+             !write_exact(io_fd, &tot_sz, sizeof(tot_sz)) ||
+             !write_exact(io_fd, "vcpu", 4) ||
+             !write_exact(io_fd, &chunk1_sz, sizeof(chunk1_sz)) ||
+             !write_exact(io_fd, &ctxt, chunk1_sz) ||
+             !write_exact(io_fd, "extv", 4) ||
+             !write_exact(io_fd, &chunk2_sz, sizeof(chunk2_sz)) )
         {
             ERROR("write: extended info");
             goto out;
@@ -830,6 +832,7 @@ int xc_domain_save(int xc_handle, int io
                    void (*qemu_flip_buffer)(int, int))
 {
     xc_dominfo_t info;
+    DECLARE_DOMCTL;
 
     int rc = 1, frc, i, j, last_iter, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
@@ -1095,7 +1098,6 @@ int xc_domain_save(int xc_handle, int io
         while ( N < p2m_size )
         {
             unsigned int this_pc = (N * 100) / p2m_size;
-            int rc;
 
             if ( (this_pc - prev_pc) >= 5 )
             {
@@ -1107,10 +1109,10 @@ int xc_domain_save(int xc_handle, int io
             {
                 /* Slightly wasteful to peek the whole array evey time,
                    but this is fast enough for the moment. */
-                rc = xc_shadow_control(
+                frc = xc_shadow_control(
                     xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, 
                     p2m_size, NULL, 0, NULL);
-                if ( rc != p2m_size )
+                if ( frc != p2m_size )
                 {
                     ERROR("Error peeking shadow bitmap");
                     goto out;
@@ -1601,6 +1603,20 @@ int xc_domain_save(int xc_handle, int io
             ERROR("Error when writing to state file (1) (errno %d)", errno);
             goto out;
         }
+
+        domctl.cmd = XEN_DOMCTL_get_ext_vcpucontext;
+        domctl.domain = dom;
+        domctl.u.ext_vcpucontext.vcpu = i;
+        if ( xc_domctl(xc_handle, &domctl) < 0 )
+        {
+            ERROR("No extended context for VCPU%d", i);
+            goto out;
+        }
+        if ( !write_exact(io_fd, &domctl.u.ext_vcpucontext, 128) )
+        {
+            ERROR("Error when writing to state file (2) (errno %d)", errno);
+            goto out;
+        }
     }
 
     /*
diff -r c17bfb091790 -r a07288a84785 tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/libxc/xc_misc.c     Tue Oct 30 15:34:44 2007 -0600
@@ -10,7 +10,7 @@ int xc_readconsolering(int xc_handle,
 int xc_readconsolering(int xc_handle,
                        char **pbuffer,
                        unsigned int *pnr_chars,
-                       int clear)
+                       int clear, int incremental, uint32_t *pindex)
 {
     int ret;
     DECLARE_SYSCTL;
@@ -19,14 +19,24 @@ int xc_readconsolering(int xc_handle,
 
     sysctl.cmd = XEN_SYSCTL_readconsole;
     set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer);
-    sysctl.u.readconsole.count  = nr_chars;
-    sysctl.u.readconsole.clear  = clear;
+    sysctl.u.readconsole.count = nr_chars;
+    sysctl.u.readconsole.clear = clear;
+    sysctl.u.readconsole.incremental = 0;
+    if ( pindex )
+    {
+        sysctl.u.readconsole.index = *pindex;
+        sysctl.u.readconsole.incremental = incremental;
+    }
 
     if ( (ret = lock_pages(buffer, nr_chars)) != 0 )
         return ret;
 
     if ( (ret = do_sysctl(xc_handle, &sysctl)) == 0 )
+    {
         *pnr_chars = sysctl.u.readconsole.count;
+        if ( pindex )
+            *pindex = sysctl.u.readconsole.index;
+    }
 
     unlock_pages(buffer, nr_chars);
 
diff -r c17bfb091790 -r a07288a84785 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/libxc/xenctrl.h     Tue Oct 30 15:34:44 2007 -0600
@@ -549,7 +549,7 @@ int xc_readconsolering(int xc_handle,
 int xc_readconsolering(int xc_handle,
                        char **pbuffer,
                        unsigned int *pnr_chars,
-                       int clear);
+                       int clear, int incremental, uint32_t *pindex);
 
 int xc_send_debug_keys(int xc_handle, char *keys);
 
@@ -616,9 +616,9 @@ int xc_domain_iomem_permission(int xc_ha
 
 int xc_domain_pin_memory_cacheattr(int xc_handle,
                                    uint32_t domid,
-                                   unsigned long start,
-                                   unsigned long end,
-                                   unsigned int type);
+                                   uint64_t start,
+                                   uint64_t end,
+                                   uint32_t type);
 
 unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid,
                                     unsigned long mfn);
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Tue Oct 30 15:34:44 2007 -0600
@@ -716,17 +716,19 @@ static PyObject *pyxc_readconsolering(Xc
                                       PyObject *args,
                                       PyObject *kwds)
 {
-    unsigned int clear = 0;
+    unsigned int clear = 0, index = 0, incremental = 0;
     char         _str[32768], *str = _str;
     unsigned int count = 32768;
     int          ret;
 
-    static char *kwd_list[] = { "clear", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
-        return NULL;
-
-    ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
+    static char *kwd_list[] = { "clear", "index", "incremental", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iii", kwd_list,
+                                      &clear, &index, &incremental) )
+        return NULL;
+
+    ret = xc_readconsolering(self->xc_handle, &str, &count, clear,
+                             incremental, &index);
     if ( ret < 0 )
         return pyxc_error_to_exception();
 
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/util/acmpolicy.py
--- a/tools/python/xen/util/acmpolicy.py        Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/util/acmpolicy.py        Tue Oct 30 15:34:44 2007 -0600
@@ -46,7 +46,7 @@ ACM_POLICY_UNDEFINED = 15
 ACM_POLICY_UNDEFINED = 15
 
 
-ACM_SCHEMA_FILE = "/etc/xen/acm-security/policies/security_policy.xsd"
+ACM_SCHEMA_FILE = ACM_POLICIES_DIR + "security_policy.xsd"
 
 ACM_LABEL_UNLABELED = "__UNLABELED__"
 ACM_LABEL_UNLABELED_DISPLAY = "unlabeled"
@@ -263,7 +263,7 @@ class ACMPolicy(XSPolicy):
         else:
             #Not loaded in HV
             self.dom = acmpol_new.dom
-            self.compile()
+            rc = self.compile()
         return rc, errors
 
 
@@ -842,9 +842,15 @@ class ACMPolicy(XSPolicy):
             rc, mapfile, bin_pol = self.policy_create_map_and_bin()
 
             if rc == 0:
-                rc = self.__write_to_file(".map", mapfile)
-                if rc != 0:
-                    log.error("Error writing map file")
+                try:
+                    security.mapfile_lock()
+
+                    rc = self.__write_to_file(".map", mapfile)
+                    if rc != 0:
+                        log.error("Error writing map file")
+
+                finally:
+                    security.mapfile_unlock()
 
             if rc == 0:
                 rc = self.__write_to_file(".bin", bin_pol)
@@ -919,7 +925,7 @@ class ACMPolicy(XSPolicy):
     def policy_get_domain_label_formatted(self, domid):
         label = self.policy_get_domain_label(domid)
         if label == "":
-            return ""
+            label = ACM_LABEL_UNLABELED
         return "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, self.get_name(), label)
 
     def policy_get_domain_label_by_ssidref_formatted(self, ssidref):
@@ -941,6 +947,8 @@ class ACMPolicy(XSPolicy):
         secpolcode  = ACM_POLICY_UNDEFINED
         unknown_ste = set()
         unknown_chw = set()
+        unlabeled_ste = "__NULL_LABEL__"
+        unlabeled_chw = "__NULL_LABEL__"
 
         rc = self.validate()
         if rc:
@@ -979,6 +987,7 @@ class ACMPolicy(XSPolicy):
             vms_with_chws.sort()
 
         if ACM_LABEL_UNLABELED in vms_with_chws:
+            unlabeled_chw = ACM_LABEL_UNLABELED
             vms_with_chws.remove(ACM_LABEL_UNLABELED) ; # @1
 
         vms_with_stes = []
@@ -996,6 +1005,7 @@ class ACMPolicy(XSPolicy):
             vms_with_stes.sort()
 
         if ACM_LABEL_UNLABELED in vms_with_stes:
+            unlabeled_ste = ACM_LABEL_UNLABELED
             vms_with_stes.remove(ACM_LABEL_UNLABELED) ; # @2
 
         resnames = self.policy_get_resourcelabel_names()
@@ -1050,7 +1060,8 @@ class ACMPolicy(XSPolicy):
 
         if len(vms_with_chws) > 0:
             mapfile += \
-                 "LABEL->SSID ANY CHWALL __NULL_LABEL__       %x\n" % 0
+                 "LABEL->SSID ANY CHWALL %-20s %x\n" % \
+                 (unlabeled_chw, 0)
             i = 0
             for v in vms_with_chws:
                 mapfile += \
@@ -1061,7 +1072,8 @@ class ACMPolicy(XSPolicy):
 
         if len(vms_with_stes) > 0 or len(resnames) > 0:
             mapfile += \
-                 "LABEL->SSID ANY STE    __NULL_LABEL__       %08x\n" % 0
+                 "LABEL->SSID ANY STE    %-20s %08x\n" % \
+                 (unlabeled_ste, 0)
             i = 0
             for v in vms_with_stes:
                 mapfile += \
@@ -1260,9 +1272,11 @@ class ACMPolicy(XSPolicy):
         if len(unknown_ste) > 0:
             log.info("The following STEs in VM/res labels were unknown:" \
                      " %s" % list(unknown_ste))
+            rc = -xsconstants.XSERR_BAD_LABEL
         if len(unknown_chw) > 0:
             log.info("The following Ch. Wall types in labels were unknown:" \
                      " %s" % list(unknown_chw))
+            rc = -xsconstants.XSERR_BAD_LABEL
         return rc, mapfile, all_bin.tostring()
 
     def get_enforced_binary(self):
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/util/xsm/acm/acm.py
--- a/tools/python/xen/util/xsm/acm/acm.py      Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/util/xsm/acm/acm.py      Tue Oct 30 15:34:44 2007 -0600
@@ -27,6 +27,7 @@ from xen.lowlevel import acm
 from xen.lowlevel import acm
 from xen.xend import sxp
 from xen.xend import XendConstants
+from xen.xend import XendOptions
 from xen.xend.XendLogging import log
 from xen.xend.XendError import VmError
 from xen.util import dictio, xsconstants
@@ -655,6 +656,10 @@ def get_res_security_details(resource):
     if policy == 'NULL':
         log.info("Resource label for "+resource+" not in file, using DEFAULT.")
         return default_security_details()
+
+    if policytype != xsconstants.ACM_POLICY_ID:
+        raise VmError("Unknown policy type '%s in label for resource '%s'" %
+                      (policytype, resource))
 
     # is this resource label for the running policy?
     if policy == active_policy:
@@ -1077,9 +1082,14 @@ def set_resource_label(resource, policyt
         if reslabel != "":
             new_entry = { resource : tuple([policytype, policyref, reslabel])}
             access_control.update(new_entry)
+            command = "add"
+            reslbl = ":".join([policytype, policyref, reslabel])
         else:
             if access_control.has_key(resource):
                 del access_control[resource]
+            command = "remove"
+            reslbl = ""
+        run_resource_label_change_script(resource, reslbl, command)
         dictio.dict_write(access_control, "resources", res_label_filename)
     finally:
         resfile_unlock()
@@ -1269,6 +1279,7 @@ def change_acm_policy(bin_pol, del_array
                 label = reslabel_map[label]
             elif label not in polnew_reslabels:
                 policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
+                run_resource_label_change_script(key, "", "remove")
             # Update entry
             access_control[key] = \
                    tuple([ policytype, new_policyname, label ])
@@ -1373,11 +1384,24 @@ def get_security_label(self, xspol=None)
         from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
         xspol = XSPolicyAdminInstance().get_loaded_policy()
 
-    if domid == 0:
-        if xspol:
-            label = xspol.policy_get_domain_label_formatted(domid)
-        else:
-            label = ""
-    else:
-        label = self.info.get('security_label', '')
+    label = ""
+    if xspol:
+        label = xspol.policy_get_domain_label_formatted(domid)
+    if domid != 0:
+        label = self.info.get('security_label', label)
     return label
+
+def run_resource_label_change_script(resource, label, command):
+    script = XendOptions.instance().get_resource_label_change_script()
+    if script:
+        parms = {
+            'resource' : resource,
+            'label'    : label,
+            'command'  : command,
+        }
+        log.info("Running resource label change script %s: %s" %
+                 (script, parms))
+        parms.update(os.environ)
+        os.spawnve(os.P_NOWAIT, script[0], script, parms)
+    else:
+        log.info("No script given for relabeling of resources.")
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/XendCheckpoint.py   Tue Oct 30 15:34:44 2007 -0600
@@ -6,6 +6,7 @@
 # this archive for more details.
 
 import os
+import os.path
 import re
 import string
 import threading
@@ -108,7 +109,7 @@ def save(fd, dominfo, network, live, dst
         forkHelper(cmd, fd, saveInputHandler, False)
 
         # put qemu device model state
-        if hvm:
+        if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()):
             write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature")
             qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(),
                               os.O_RDONLY)
@@ -245,6 +246,8 @@ def restore(xd, fd, dominfo = None, paus
             raise XendError('Could not read console MFN')        
 
         # get qemu state and create a tmp file for dm restore
+        # Even PV guests may have QEMU stat, but its not currently
+        # used so only bother with HVM currently.
         if is_hvm:
             qemu_signature = read_exact(fd, len(QEMU_SIGNATURE),
                                         "invalid device model signature read")
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/XendConfig.py       Tue Oct 30 15:34:44 2007 -0600
@@ -28,10 +28,12 @@ from xen.xend.XendDevices import XendDev
 from xen.xend.XendDevices import XendDevices
 from xen.xend.PrettyPrint import prettyprintstring
 from xen.xend.XendConstants import DOM_STATE_HALTED
+from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.server.BlktapController import blktap_disk_types
 from xen.xend.server.netif import randomMAC
 from xen.util.blkif import blkdev_name_to_number
 from xen.util import xsconstants
+import xen.util.auxbin
 
 log = logging.getLogger("xend.XendConfig")
 log.setLevel(logging.WARN)
@@ -126,7 +128,7 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 
                         'fda', 'fdb', 'keymap', 'isa', 'localtime', 'monitor', 
                         'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl',
                         'soundhw','stdvga', 'usb', 'usbdevice', 'vnc',
-                        'vncconsole', 'vncdisplay', 'vnclisten',
+                        'vncconsole', 'vncdisplay', 'vnclisten', 'timer_mode',
                         'vncpasswd', 'vncunused', 'xauthority', 'pci', 'vhpt']
 
 # Xen API console 'other_config' keys.
@@ -233,8 +235,6 @@ LEGACY_XENSTORE_VM_PARAMS = [
     'on_xend_start',
     'on_xend_stop',
 ]
-
-DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm'
 
 ##
 ## Config Choices
@@ -393,13 +393,14 @@ class XendConfig(dict):
             self['name_label'] = 'Domain-' + self['uuid']
 
     def _platform_sanity_check(self):
+        if 'keymap' not in self['platform'] and 
XendOptions.instance().get_keymap():
+            self['platform']['keymap'] = XendOptions.instance().get_keymap()
+
+        if self.is_hvm() or self.has_rfb():
+            if 'device_model' not in self['platform']:
+                self['platform']['device_model'] = 
xen.util.auxbin.pathTo("qemu-dm")
+
         if self.is_hvm():
-            if 'keymap' not in self['platform'] and 
XendOptions.instance().get_keymap():
-                self['platform']['keymap'] = 
XendOptions.instance().get_keymap()
-
-            if 'device_model' not in self['platform']:
-                self['platform']['device_model'] = DEFAULT_DM
-
             # Compatibility hack, can go away soon.
             if 'soundhw' not in self['platform'] and \
                self['platform'].get('enable_audio'):
@@ -744,16 +745,7 @@ class XendConfig(dict):
         # coalesce hvm vnc frame buffer with vfb config
         if self.is_hvm() and int(self['platform'].get('vnc', 0)) != 0:
             # add vfb device if it isn't there already
-            has_rfb = False
-            for console_uuid in self['console_refs']:
-                if self['devices'][console_uuid][1].get('protocol') == 'rfb':
-                    has_rfb = True
-                    break
-                if self['devices'][console_uuid][0] == 'vfb':
-                    has_rfb = True
-                    break
-
-            if not has_rfb:
+            if not self.has_rfb():
                 dev_config = ['vfb']
                 dev_config.append(['type', 'vnc'])
                 # copy VNC related params from platform config to vfb dev conf
@@ -764,6 +756,14 @@ class XendConfig(dict):
 
                 self.device_add('vfb', cfg_sxp = dev_config)
 
+
+    def has_rfb(self):
+        for console_uuid in self['console_refs']:
+            if self['devices'][console_uuid][1].get('protocol') == 'rfb':
+                return True
+            if self['devices'][console_uuid][0] == 'vfb':
+                return True
+        return False
 
     def _sxp_to_xapi_unsupported(self, sxp_cfg):
         """Read in an SXP configuration object and populate
@@ -942,36 +942,43 @@ class XendConfig(dict):
 
         # Marshall devices (running or from configuration)
         if not ignore_devices:
-            for cls in XendDevices.valid_devices():
-                found = False
+            txn = xstransact()
+            try:
+                for cls in XendDevices.valid_devices():
+                    found = False
                 
-                # figure if there is a dev controller is valid and running
-                if domain and domain.getDomid() != None:
-                    try:
-                        controller = domain.getDeviceController(cls)
-                        configs = controller.configurations()
-                        for config in configs:
-                            if sxp.name(config) in ('vbd', 'tap'):
-                                # The bootable flag is never written to the
-                                # store as part of the device config.
-                                dev_uuid = sxp.child_value(config, 'uuid')
-                                dev_type, dev_cfg = self['devices'][dev_uuid]
-                                is_bootable = dev_cfg.get('bootable', 0)
-                                config.append(['bootable', int(is_bootable)])
-
-                            sxpr.append(['device', config])
-
-                        found = True
-                    except:
-                        log.exception("dumping sxp from device controllers")
-                        pass
+                    # figure if there is a dev controller is valid and running
+                    if domain and domain.getDomid() != None:
+                        try:
+                            controller = domain.getDeviceController(cls)
+                            configs = controller.configurations(txn)
+                            for config in configs:
+                                if sxp.name(config) in ('vbd', 'tap'):
+                                    # The bootable flag is never written to the
+                                    # store as part of the device config.
+                                    dev_uuid = sxp.child_value(config, 'uuid')
+                                    dev_type, dev_cfg = 
self['devices'][dev_uuid]
+                                    is_bootable = dev_cfg.get('bootable', 0)
+                                    config.append(['bootable', 
int(is_bootable)])
+
+                                sxpr.append(['device', config])
+
+                            found = True
+                        except:
+                            log.exception("dumping sxp from device 
controllers")
+                            pass
                     
-                # if we didn't find that device, check the existing config
-                # for a device in the same class
-                if not found:
-                    for dev_type, dev_info in self.all_devices_sxpr():
-                        if dev_type == cls:
-                            sxpr.append(['device', dev_info])
+                    # if we didn't find that device, check the existing config
+                    # for a device in the same class
+                    if not found:
+                        for dev_type, dev_info in self.all_devices_sxpr():
+                            if dev_type == cls:
+                                sxpr.append(['device', dev_info])
+
+                txn.commit()
+            except:
+                txn.abort()
+                raise
 
         return sxpr    
     
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/XendConstants.py
--- a/tools/python/xen/xend/XendConstants.py    Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/XendConstants.py    Tue Oct 30 15:34:44 2007 -0600
@@ -46,6 +46,7 @@ HVM_PARAM_NVRAM_FD     = 7
 HVM_PARAM_NVRAM_FD     = 7
 HVM_PARAM_VHPT_SIZE    = 8
 HVM_PARAM_BUFPIOREQ_PFN = 9
+HVM_PARAM_TIMER_MODE   = 10
 
 restart_modes = [
     "restart",
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/XendDomain.py       Tue Oct 30 15:34:44 2007 -0600
@@ -393,13 +393,22 @@ class XendDomain:
         @rtype: None
         """
 
+        txn = xstransact()
+        try:
+            self._refreshTxn(txn, refresh_shutdown)
+            txn.commit()
+        except:
+            txn.abort()
+            raise
+
+    def _refreshTxn(self, transaction, refresh_shutdown):
         running = self._running_domains()
         # Add domains that are not already tracked but running in Xen,
         # and update domain state for those that are running and tracked.
         for dom in running:
             domid = dom['domid']
             if domid in self.domains:
-                self.domains[domid].update(dom, refresh_shutdown)
+                self.domains[domid].update(dom, refresh_shutdown, transaction)
             elif domid not in self.domains and dom['dying'] != 1:
                 try:
                     new_dom = XendDomainInfo.recreate(dom, False)
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Oct 30 15:34:44 2007 -0600
@@ -819,12 +819,15 @@ class XendDomainInfo:
 
         self._update_consoles()
 
-    def _update_consoles(self):
+    def _update_consoles(self, transaction = None):
         if self.domid == None or self.domid == 0:
             return
 
         # Update VT100 port if it exists
-        self.console_port = self.readDom('console/port')
+        if transaction is None:
+            self.console_port = self.readDom('console/port')
+        else:
+            self.console_port = self.readDomTxn(transaction, 'console/port')
         if self.console_port is not None:
             serial_consoles = self.info.console_get_all('vt100')
             if not serial_consoles:
@@ -837,7 +840,10 @@ class XendDomainInfo:
                 
 
         # Update VNC port if it exists and write to xenstore
-        vnc_port = self.readDom('console/vnc-port')
+        if transaction is None:
+            vnc_port = self.readDom('console/vnc-port')
+        else:
+            vnc_port = self.readDomTxn(transaction, 'console/vnc-port')
         if vnc_port is not None:
             for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
                 if dev_type == 'vfb':
@@ -872,6 +878,27 @@ class XendDomainInfo:
     def storeVm(self, *args):
         return xstransact.Store(self.vmpath, *args)
 
+
+    def _readVmTxn(self, transaction,  *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.read(*paths)
+
+    def _writeVmTxn(self, transaction,  *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.write(*paths)
+
+    def _removeVmTxn(self, transaction,  *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.remove(*paths)
+
+    def _gatherVmTxn(self, transaction,  *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.gather(paths)
+
+    def storeVmTxn(self, transaction,  *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.store(*paths)
+
     #
     # Function to update xenstore /dom/*
     #
@@ -890,6 +917,28 @@ class XendDomainInfo:
 
     def storeDom(self, *args):
         return xstransact.Store(self.dompath, *args)
+
+
+    def readDomTxn(self, transaction, *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.read(*paths)
+
+    def gatherDomTxn(self, transaction, *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.gather(*paths)
+
+    def _writeDomTxn(self, transaction, *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.write(*paths)
+
+    def _removeDomTxn(self, transaction, *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.remove(*paths)
+
+    def storeDomTxn(self, transaction, *args):
+        paths = map(lambda x: self.vmpath + "/" + x, args)
+        return transaction.store(*paths)
+
 
     def _recreateDom(self):
         complete(self.dompath, lambda t: self._recreateDomFunc(t))
@@ -916,8 +965,15 @@ class XendDomainInfo:
                 else:
                     to_store[n] = str(v)
 
+        # Figure out if we need to tell xenconsoled to ignore this guest's
+        # console - device model will handle console if it is running
+        constype = "ioemu"
+        if 'device_model' not in self.info['platform']:
+            constype = "xenconsoled"
+
         f('console/port',     self.console_port)
         f('console/ring-ref', self.console_mfn)
+        f('console/type',     constype)
         f('store/port',       self.store_port)
         f('store/ring-ref',   self.store_mfn)
 
@@ -1455,10 +1511,16 @@ class XendDomainInfo:
 
     def _releaseDevices(self, suspend = False):
         """Release all domain's devices.  Nothrow guarantee."""
-        if suspend and self.image:
-            self.image.destroy(suspend)
-            return
-
+        if self.image:
+            try:
+                log.debug("Destroying device model")
+                self.image.destroyDeviceModel()
+            except Exception, e:
+                log.exception("Device model destroy failed %s" % str(e))
+        else:
+            log.debug("No device model")
+
+        log.debug("Releasing devices")
         t = xstransact("%s/device" % self.dompath)
         for devclass in XendDevices.valid_devices():
             for dev in t.list(devclass):
@@ -1583,6 +1645,11 @@ class XendDomainInfo:
 
         self._recreateDom()
 
+        # Set timer configration of domain
+        if hvm:
+            xc.hvm_set_param(self.domid, HVM_PARAM_TIMER_MODE,
+                long(self.info["platform"].get("timer_mode")))
+
         # Set maximum number of vcpus in domain
         xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
 
@@ -1709,11 +1776,6 @@ class XendDomainInfo:
             bootloader_tidy(self)
 
             if self.image:
-                try:
-                    self.image.destroy()
-                except:
-                    log.exception(
-                        "XendDomainInfo.cleanup: image.destroy() failed.")
                 self.image = None
 
             try:
@@ -1761,10 +1823,9 @@ class XendDomainInfo:
         self.console_mfn = console_mfn
 
         self._introduceDomain()
-        if self.info.is_hvm():
-            self.image = image.create(self, self.info)
-            if self.image:
-                self.image.createDeviceModel(True)
+        self.image = image.create(self, self.info)
+        if self.image:
+            self.image.createDeviceModel(True)
         self._storeDomDetails()
         self._registerWatches()
         self.refreshShutdown()
@@ -1882,8 +1943,8 @@ class XendDomainInfo:
             ResumeDomain(self.domid)
         except:
             log.exception("XendDomainInfo.resume: xc.domain_resume failed on 
domain %s." % (str(self.domid)))
-        if self.is_hvm():
-            self.image.resumeDeviceModel()
+        self.image.resumeDeviceModel()
+        log.debug("XendDomainInfo.resumeDomain: completed")
 
 
     #
@@ -2211,7 +2272,7 @@ class XendDomainInfo:
                            (" as domain %s" % str(dom.domid)) or ""))
         
 
-    def update(self, info = None, refresh = True):
+    def update(self, info = None, refresh = True, transaction = None):
         """Update with info from xc.domain_getinfo().
         """
         log.trace("XendDomainInfo.update(%s) on domain %s", info,
@@ -2234,7 +2295,7 @@ class XendDomainInfo:
         # TODO: we should eventually get rid of old_dom_states
 
         self.info.update_config(info)
-        self._update_consoles()
+        self._update_consoles(transaction)
         
         if refresh:
             self.refreshShutdown(info)
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py      Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/XendOptions.py      Tue Oct 30 15:34:44 2007 -0600
@@ -102,6 +102,15 @@ class XendOptions:
     """Default interface to listen for VNC connections on"""
     xend_vnc_listen_default = '127.0.0.1'
 
+    """Use of TLS mode in QEMU VNC server"""
+    xend_vnc_tls = 0
+
+    """x509 certificate directory for QEMU VNC server"""
+    xend_vnc_x509_cert_dir = "/etc/xen/vnc"
+
+    """Verify incoming client x509 certs"""
+    xend_vnc_x509_verify = 0
+
     """Default session storage path."""
     xend_domains_path_default = '/var/lib/xend/domains'
 
@@ -277,6 +286,26 @@ class XendOptions:
 
     def get_keymap(self):
         return self.get_config_value('keymap', None)
+
+    def get_resource_label_change_script(self):
+        s = self.get_config_value('resource-label-change-script')
+        if s:
+            result = s.split(" ")
+            result[0] = os.path.join(osdep.scripts_dir, result[0])
+            return result
+        else:
+            return None
+
+
+    def get_vnc_tls(self):
+        return self.get_config_string('vnc-tls', self.xend_vnc_tls)
+
+    def get_vnc_x509_cert_dir(self):
+        return self.get_config_string('vnc-x509-cert-dir', 
self.xend_vnc_x509_cert_dir)
+
+    def get_vnc_x509_verify(self):
+        return self.get_config_string('vnc-x509-verify', 
self.xend_vnc_x509_verify)
+
 
 class XendOptionsFile(XendOptions):
 
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/XendXSPolicyAdmin.py
--- a/tools/python/xen/xend/XendXSPolicyAdmin.py        Tue Oct 30 11:33:55 
2007 -0600
+++ b/tools/python/xen/xend/XendXSPolicyAdmin.py        Tue Oct 30 15:34:44 
2007 -0600
@@ -28,7 +28,6 @@ from xen.util.acmpolicy import ACMPolicy
 from xen.util.acmpolicy import ACMPolicy
 from xen.xend.XendError import SecurityError
 
-XS_MANAGED_POLICIES_FILE = "/etc/xen/acm-security/policies/managed_policies"
 
 class XSPolicyAdmin:
     """ The class that handles the managed policies in the system.
@@ -45,28 +44,19 @@ class XSPolicyAdmin:
                                 on the system (currently '1')
         """
         self.maxpolicies = maxpolicies
-        try:
-            self.policies = dictio.dict_read("managed_policies",
-                                             XS_MANAGED_POLICIES_FILE)
+        self.policies = {}
+        self.xsobjs = {}
+
+        act_pol_name = self.get_hv_loaded_policy_name()
+
+        ref = uuid.createString()
+        try:
+            self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref)
+            self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID)
         except Exception, e:
-            self.policies = {}
-
-        self.xsobjs = {}
-        for ref, data in self.policies.items():
-            name = data[0]
-            typ = data[1]
-            try:
-                if typ == xsconstants.ACM_POLICY_ID:
-                    try:
-                        self.xsobjs[ref] = ACMPolicy(name=name, ref=ref)
-                    except Exception, e:
-                        del self.policies[ref]
-                else:
-                    del self.policies[ref]
-            except Exception, e:
-                log.error("XSPolicyAdmin: Could not find policy '%s': %s" %
-                         (name, str(e)))
-                del self.policies[ref]
+            log.error("Could not find XML representation of policy '%s': "
+                      "%s" % (act_pol_name,e))
+
         log.debug("XSPolicyAdmin: Known policies: %s" % self.policies)
 
     def isXSEnabled(self):
@@ -113,6 +103,7 @@ class XSPolicyAdmin:
             if rc == 0:
                 self.rm_bootpolicy()
                 irc = self.activate_xspolicy(loadedpol, flags)
+                # policy is loaded; if setting the boot flag fails it's ok.
             return (loadedpol, rc, errors)
 
         try:
@@ -166,9 +157,6 @@ class XSPolicyAdmin:
                                        xsconstants.ACM_POLICY_ID]) }
             self.policies.update(new_entry)
             self.xsobjs[ref]  = acmpol
-            dictio.dict_write(self.policies,
-                              "managed_policies",
-                              XS_MANAGED_POLICIES_FILE)
         return (acmpol, xsconstants.XSERR_SUCCESS, errors)
 
     def make_boot_policy(self, acmpol):
@@ -217,9 +205,6 @@ class XSPolicyAdmin:
             if rc == xsconstants.XSERR_SUCCESS or force:
                 del self.policies[ref]
                 del self.xsobjs[ref]
-                dictio.dict_write(self.policies,
-                                  "managed_policies",
-                                  XS_MANAGED_POLICIES_FILE)
                 rc = xsconstants.XSERR_SUCCESS
             return rc
 
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/image.py    Tue Oct 30 15:34:44 2007 -0600
@@ -17,7 +17,7 @@
 #============================================================================
 
 
-import os, string
+import os, os.path, string
 import re
 import math
 import time
@@ -31,6 +31,7 @@ from xen.xend.xenstore.xstransact import
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xswatch import xswatch
 from xen.xend import arch
+from xen.xend import XendOptions
 
 xc = xen.lowlevel.xc.xc()
 
@@ -56,10 +57,9 @@ class ImageHandler:
     defining in a subclass.
 
     The method createDeviceModel() is called to create the domain device
-    model if it needs one.  The default is to do nothing.
-
-    The method destroy() is called when the domain is destroyed.
-    The default is to do nothing.
+    model.
+
+    The method destroyDeviceModel() is called to reap the device model
     """
 
     ostype = None
@@ -91,6 +91,15 @@ class ImageHandler:
                         ("image/cmdline", self.cmdline),
                         ("image/ramdisk", self.ramdisk))
 
+        self.dmargs = self.parseDeviceModelArgs(vmConfig)
+        self.device_model = vmConfig['platform'].get('device_model')
+
+        self.display = vmConfig['platform'].get('display')
+        self.xauthority = vmConfig['platform'].get('xauthority')
+        self.vncconsole = vmConfig['platform'].get('vncconsole')
+        self.pid = None
+
+
 
     def cleanupBootloading(self):
         if self.bootloader:
@@ -173,25 +182,158 @@ class ImageHandler:
         """Build the domain. Define in subclass."""
         raise NotImplementedError()
 
+    # Return a list of cmd line args to the device models based on the
+    # xm config file
+    def parseDeviceModelArgs(self, vmConfig):
+        ret = ["-domain-name", str(self.vm.info['name_label'])]
+
+        # Find RFB console device, and if it exists, make QEMU enable
+        # the VNC console.
+        if int(vmConfig['platform'].get('nographic', 0)) != 0:
+            # skip vnc init if nographic is set
+            ret.append('-nographic')
+            return ret
+
+        vnc_config = {}
+        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
+        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
+        for dev_uuid in vmConfig['console_refs']:
+            dev_type, dev_info = vmConfig['devices'][dev_uuid]
+            if dev_type == 'vfb':
+                vnc_config = dev_info.get('other_config', {})
+                has_vnc = True
+                break
+
+        keymap = vmConfig['platform'].get("keymap")
+        if keymap:
+            ret.append("-k")
+            ret.append(keymap)
+
+        if has_vnc:
+            if not vnc_config:
+                for key in ('vncunused', 'vnclisten', 'vncdisplay',
+                            'vncpasswd'):
+                    if key in vmConfig['platform']:
+                        vnc_config[key] = vmConfig['platform'][key]
+            if vnc_config.has_key("vncpasswd"):
+                passwd = vnc_config["vncpasswd"]
+            else:
+                passwd = XendOptions.instance().get_vncpasswd_default()
+            vncopts = ""
+            if passwd:
+                self.vm.storeVm("vncpasswd", passwd)
+                vncopts = vncopts + ",password"
+                log.debug("Stored a VNC password for vfb access")
+            else:
+                log.debug("No VNC passwd configured for vfb access")
+
+            if XendOptions.instance().get_vnc_tls():
+                vncx509certdir = XendOptions.instance().get_vnc_x509_cert_dir()
+                vncx509verify = XendOptions.instance().get_vnc_x509_verify()
+
+                if not os.path.exists(vncx509certdir):
+                    raise VmError("VNC x509 certificate dir %s does not exist" 
% vncx509certdir)
+
+                if vncx509verify:
+                    vncopts = vncopts + ",tls,x509verify=%s" % vncx509certdir
+                else:
+                    vncopts = vncopts + ",tls,x509=%s" % vncx509certdir
+
+
+            vnclisten = vnc_config.get('vnclisten',
+                                       
XendOptions.instance().get_vnclisten_address())
+            vncdisplay = vnc_config.get('vncdisplay', 0)
+            ret.append('-vnc')
+            ret.append("%s:%s%s" % (vnclisten, vncdisplay, vncopts))
+
+            if vnc_config.get('vncunused', 0):
+                ret.append('-vncunused')
+
+        elif has_sdl:
+            # SDL is default in QEMU.
+            pass
+        else:
+            ret.append('-nographic')
+
+        if int(vmConfig['platform'].get('monitor', 0)) != 0:
+            ret = ret + ['-monitor', 'vc']
+        return ret
+
+    def getDeviceModelArgs(self, restore = False):
+        args = [self.device_model]
+        args = args + ([ "-d",  "%d" % self.vm.getDomid() ])
+        args = args + self.dmargs
+        return args
+
     def createDeviceModel(self, restore = False):
-        """Create device model for the domain (define in subclass if 
needed)."""
-        pass
-    
+        if self.device_model is None:
+            return
+        if self.pid:
+            return
+        # Execute device model.
+        #todo: Error handling
+        args = self.getDeviceModelArgs(restore)
+        env = dict(os.environ)
+        if self.display:
+            env['DISPLAY'] = self.display
+        if self.xauthority:
+            env['XAUTHORITY'] = self.xauthority
+        if self.vncconsole:
+            args = args + ([ "-vncviewer" ])
+        log.info("spawning device models: %s %s", self.device_model, args)
+        # keep track of pid and spawned options to kill it later
+        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
+        self.vm.storeDom("image/device-model-pid", self.pid)
+        log.info("device model pid: %d", self.pid)
+
     def saveDeviceModel(self):
-        """Save device model for the domain (define in subclass if needed)."""
-        pass
+        if self.device_model is None:
+            return
+        # Signal the device model to pause itself and save its state
+        xstransact.Store("/local/domain/0/device-model/%i"
+                         % self.vm.getDomid(), ('command', 'save'))
+        # Wait for confirmation.  Could do this with a watch but we'd
+        # still end up spinning here waiting for the watch to fire. 
+        state = ''
+        count = 0
+        while state != 'paused':
+            state = xstransact.Read("/local/domain/0/device-model/%i/state"
+                                    % self.vm.getDomid())
+            time.sleep(0.1)
+            count += 1
+            if count > 100:
+                raise VmError('Timed out waiting for device model to save')
 
     def resumeDeviceModel(self):
-        """Unpause device model for the domain (define in subclass if 
needed)."""
-        pass
-
-    def destroy(self):
-        """Extra cleanup on domain destroy (define in subclass if needed)."""
-        pass
-
+        if self.device_model is None:
+            return
+        # Signal the device model to resume activity after pausing to save.
+        xstransact.Store("/local/domain/0/device-model/%i"
+                         % self.vm.getDomid(), ('command', 'continue'))
 
     def recreate(self):
-        pass
+        if self.device_model is None:
+            return
+        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
+
+    def destroyDeviceModel(self):
+        if self.device_model is None:
+            return
+        if self.pid:
+            try:
+                os.kill(self.pid, signal.SIGKILL)
+            except OSError, exn:
+                log.exception(exn)
+            try:
+                os.waitpid(self.pid, 0)
+            except OSError, exn:
+                # This is expected if Xend has been restarted within the
+                # life of this domain.  In this case, we can kill the process,
+                # but we can't wait for it because it's not our child.
+                pass
+            self.pid = None
+            state = xstransact.Remove("/local/domain/0/device-model/%i"
+                                      % self.vm.getDomid())
 
 
 class LinuxImageHandler(ImageHandler):
@@ -229,6 +371,19 @@ class LinuxImageHandler(ImageHandler):
                               flags          = self.flags,
                               vhpt           = self.vhpt)
 
+    def parseDeviceModelArgs(self, vmConfig):
+        ret = ImageHandler.parseDeviceModelArgs(self, vmConfig)
+        # Equivalent to old xenconsoled behaviour. Should make
+        # it configurable in future
+        ret = ret + ["-serial", "pty"]
+        return ret
+
+    def getDeviceModelArgs(self, restore = False):
+        args = ImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-M", "xenpv"])
+        return args
+
+
 class PPC_LinuxImageHandler(LinuxImageHandler):
 
     ostype = "linux"
@@ -262,15 +417,6 @@ class HVMImageHandler(ImageHandler):
         if 'hvm' not in info['xen_caps']:
             raise HVMRequired()
 
-        self.dmargs = self.parseDeviceModelArgs(vmConfig)
-        self.device_model = vmConfig['platform'].get('device_model')
-        if not self.device_model:
-            raise VmError("hvm: missing device model")
-        
-        self.display = vmConfig['platform'].get('display')
-        self.xauthority = vmConfig['platform'].get('xauthority')
-        self.vncconsole = vmConfig['platform'].get('vncconsole')
-
         rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
 
         self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
@@ -278,49 +424,18 @@ class HVMImageHandler(ImageHandler):
                         ("image/display", self.display))
         self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset))
 
-        self.pid = None
-
         self.apic = int(vmConfig['platform'].get('apic', 0))
         self.acpi = int(vmConfig['platform'].get('acpi', 0))
-        
-
-    def buildDomain(self):
-        store_evtchn = self.vm.getStorePort()
-
-        mem_mb = self.getRequiredInitialReservation() / 1024
-
-        log.debug("domid          = %d", self.vm.getDomid())
-        log.debug("image          = %s", self.kernel)
-        log.debug("store_evtchn   = %d", store_evtchn)
-        log.debug("memsize        = %d", mem_mb)
-        log.debug("vcpus          = %d", self.vm.getVCpuCount())
-        log.debug("acpi           = %d", self.acpi)
-        log.debug("apic           = %d", self.apic)
-
-        rc = xc.hvm_build(domid          = self.vm.getDomid(),
-                          image          = self.kernel,
-                          memsize        = mem_mb,
-                          vcpus          = self.vm.getVCpuCount(),
-                          acpi           = self.acpi,
-                          apic           = self.apic)
-
-        rc['notes'] = { 'SUSPEND_CANCEL': 1 }
-
-        rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(),
-                                           HVM_PARAM_STORE_PFN)
-        xc.hvm_set_param(self.vm.getDomid(), HVM_PARAM_STORE_EVTCHN,
-                         store_evtchn)
-
-        return rc
 
     # Return a list of cmd line args to the device models based on the
     # xm config file
     def parseDeviceModelArgs(self, vmConfig):
+        ret = ImageHandler.parseDeviceModelArgs(self, vmConfig)
+        ret = ret + ['-vcpus', str(self.vm.getVCpuCount())]
+
         dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
                    'localtime', 'serial', 'stdvga', 'isa',
-                   'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ]
-        
-        ret = ['-vcpus', str(self.vm.getVCpuCount())]
+                   'acpi', 'usb', 'usbdevice', 'pci' ]
 
         for a in dmargs:
             v = vmConfig['platform'].get(a)
@@ -349,7 +464,6 @@ class HVMImageHandler(ImageHandler):
 
         # Handle disk/network related options
         mac = None
-        ret = ret + ["-domain-name", str(self.vm.info['name_label'])]
         nics = 0
         
         for devuuid in vmConfig['vbd_refs']:
@@ -378,130 +492,43 @@ class HVMImageHandler(ImageHandler):
             ret.append("-net")
             ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
 
-
-        #
-        # Find RFB console device, and if it exists, make QEMU enable
-        # the VNC console.
-        #
-        if int(vmConfig['platform'].get('nographic', 0)) != 0:
-            # skip vnc init if nographic is set
-            ret.append('-nographic')
-            return ret
-
-        vnc_config = {}
-        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
-        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
-        for dev_uuid in vmConfig['console_refs']:
-            dev_type, dev_info = vmConfig['devices'][dev_uuid]
-            if dev_type == 'vfb':
-                vnc_config = dev_info.get('other_config', {})
-                has_vnc = True
-                break
-
-        if has_vnc:
-            if not vnc_config:
-                for key in ('vncunused', 'vnclisten', 'vncdisplay',
-                            'vncpasswd'):
-                    if key in vmConfig['platform']:
-                        vnc_config[key] = vmConfig['platform'][key]
-
-            vnclisten = vnc_config.get('vnclisten',
-                                       xenopts().get_vnclisten_address())
-            vncdisplay = vnc_config.get('vncdisplay', 0)
-            ret.append('-vnc')
-            ret.append("%s:%d" % (vnclisten, vncdisplay))
-            
-            if vnc_config.get('vncunused', 0):
-                ret.append('-vncunused')
-
-            # Store vncpassword in xenstore
-            vncpasswd = vnc_config.get('vncpasswd')
-            if not vncpasswd:
-                vncpasswd = xenopts().get_vncpasswd_default()
-
-            if vncpasswd is None:
-                raise VmError('vncpasswd is not setup in vmconfig or '
-                              'xend-config.sxp')
-
-            if vncpasswd != '':
-                self.vm.storeVm('vncpasswd', vncpasswd)
-        elif has_sdl:
-            # SDL is default in QEMU.
-            pass
-        else:
-            ret.append('-nographic')
-
-        if int(vmConfig['platform'].get('monitor', 0)) != 0:
-            ret = ret + ['-monitor', 'vc']
         return ret
 
-    def createDeviceModel(self, restore = False):
-        if self.pid:
-            return
-        # Execute device model.
-        #todo: Error handling
-        args = [self.device_model]
-        args = args + ([ "-d",  "%d" % self.vm.getDomid() ])
-        if arch.type == "ia64":
-            args = args + ([ "-m", "%s" %
-                             (self.getRequiredInitialReservation() / 1024) ])
-        args = args + self.dmargs
+    def getDeviceModelArgs(self, restore = False):
+        args = ImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-M", "xenfv"])
         if restore:
             args = args + ([ "-loadvm", "/var/lib/xen/qemu-save.%d" %
                              self.vm.getDomid() ])
-        env = dict(os.environ)
-        if self.display:
-            env['DISPLAY'] = self.display
-        if self.xauthority:
-            env['XAUTHORITY'] = self.xauthority
-        if self.vncconsole:
-            args = args + ([ "-vncviewer" ])
-        log.info("spawning device models: %s %s", self.device_model, args)
-        # keep track of pid and spawned options to kill it later
-        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
-        self.vm.storeDom("image/device-model-pid", self.pid)
-        log.info("device model pid: %d", self.pid)
-
-    def saveDeviceModel(self):
-        # Signal the device model to pause itself and save its state
-        xstransact.Store("/local/domain/0/device-model/%i"
-                         % self.vm.getDomid(), ('command', 'save'))
-        # Wait for confirmation.  Could do this with a watch but we'd
-        # still end up spinning here waiting for the watch to fire. 
-        state = ''
-        count = 0
-        while state != 'paused':
-            state = xstransact.Read("/local/domain/0/device-model/%i/state"
-                                    % self.vm.getDomid())
-            time.sleep(0.1)
-            count += 1
-            if count > 100:
-                raise VmError('Timed out waiting for device model to save')
-
-    def resumeDeviceModel(self):
-        # Signal the device model to resume activity after pausing to save.
-        xstransact.Store("/local/domain/0/device-model/%i"
-                         % self.vm.getDomid(), ('command', 'continue'))
-
-    def recreate(self):
-        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
-
-    def destroy(self, suspend = False):
-        if self.pid and not suspend:
-            try:
-                os.kill(self.pid, signal.SIGKILL)
-            except OSError, exn:
-                log.exception(exn)
-            try:
-                os.waitpid(self.pid, 0)
-            except OSError, exn:
-                # This is expected if Xend has been restarted within the
-                # life of this domain.  In this case, we can kill the process,
-                # but we can't wait for it because it's not our child.
-                pass
-            self.pid = None
-            state = xstransact.Remove("/local/domain/0/device-model/%i"
-                                      % self.vm.getDomid())
+        return args
+
+    def buildDomain(self):
+        store_evtchn = self.vm.getStorePort()
+
+        mem_mb = self.getRequiredInitialReservation() / 1024
+
+        log.debug("domid          = %d", self.vm.getDomid())
+        log.debug("image          = %s", self.kernel)
+        log.debug("store_evtchn   = %d", store_evtchn)
+        log.debug("memsize        = %d", mem_mb)
+        log.debug("vcpus          = %d", self.vm.getVCpuCount())
+        log.debug("acpi           = %d", self.acpi)
+        log.debug("apic           = %d", self.apic)
+
+        rc = xc.hvm_build(domid          = self.vm.getDomid(),
+                          image          = self.kernel,
+                          memsize        = mem_mb,
+                          vcpus          = self.vm.getVCpuCount(),
+                          acpi           = self.acpi,
+                          apic           = self.apic)
+        rc['notes'] = { 'SUSPEND_CANCEL': 1 }
+
+        rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(),
+                                           HVM_PARAM_STORE_PFN)
+        xc.hvm_set_param(self.vm.getDomid(), HVM_PARAM_STORE_EVTCHN,
+                         store_evtchn)
+
+        return rc
 
 
 class IA64_HVM_ImageHandler(HVMImageHandler):
@@ -528,6 +555,13 @@ class IA64_HVM_ImageHandler(HVMImageHand
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
         # Explicit shadow memory is not a concept 
         return 0
+
+    def getDeviceModelArgs(self, restore = False):
+        args = HVMImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-m", "%s" %
+                         (self.getRequiredInitialReservation() / 1024) ])
+        return args
+
 
 class IA64_Linux_ImageHandler(LinuxImageHandler):
 
diff -r c17bfb091790 -r a07288a84785 
tools/python/xen/xend/server/ConsoleController.py
--- a/tools/python/xen/xend/server/ConsoleController.py Tue Oct 30 11:33:55 
2007 -0600
+++ b/tools/python/xen/xend/server/ConsoleController.py Tue Oct 30 15:34:44 
2007 -0600
@@ -19,9 +19,12 @@ class ConsoleController(DevController):
         return (self.allocateDeviceID(), back, {})
 
 
-    def getDeviceConfiguration(self, devid):
-        result = DevController.getDeviceConfiguration(self, devid)
-        devinfo = self.readBackend(devid, *self.valid_cfg)
+    def getDeviceConfiguration(self, devid, transaction = None):
+        result = DevController.getDeviceConfiguration(self, devid, transaction)
+        if transaction is None:
+            devinfo = self.readBackend(devid, *self.valid_cfg)
+        else:
+            devinfo = self.readBackendTxn(transaction, devid, *self.valid_cfg)
         config = dict(zip(self.valid_cfg, devinfo))
         config = dict([(key, val) for key, val in config.items()
                        if val != None])
diff -r c17bfb091790 -r a07288a84785 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Tue Oct 30 11:33:55 
2007 -0600
+++ b/tools/python/xen/xend/server/DevController.py     Tue Oct 30 15:34:44 
2007 -0600
@@ -239,15 +239,15 @@ class DevController:
 
         self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev))
 
-    def configurations(self):
-        return map(self.configuration, self.deviceIDs())
-
-
-    def configuration(self, devid):
+    def configurations(self, transaction = None):
+        return map(lambda x: self.configuration(x, transaction), 
self.deviceIDs(transaction))
+
+
+    def configuration(self, devid, transaction = None):
         """@return an s-expression giving the current configuration of the
         specified device.  This would be suitable for giving to {@link
         #createDevice} in order to recreate that device."""
-        configDict = self.getDeviceConfiguration(devid)
+        configDict = self.getDeviceConfiguration(devid, transaction)
         sxpr = [self.deviceClass]
         for key, val in configDict.items():
             if isinstance(val, (types.ListType, types.TupleType)):
@@ -273,13 +273,16 @@ class DevController:
                                    'id', devid]]
 
 
-    def getDeviceConfiguration(self, devid):
+    def getDeviceConfiguration(self, devid, transaction = None):
         """Returns the configuration of a device.
 
         @note: Similar to L{configuration} except it returns a dict.
         @return: dict
         """
-        backdomid = xstransact.Read(self.frontendPath(devid), "backend-id")
+        if transaction is None:
+            backdomid = xstransact.Read(self.frontendPath(devid), "backend-id")
+        else:
+            backdomid = transaction.read(self.frontendPath(devid) + 
"/backend-id")
         if backdomid is None:
             raise VmError("Device %s not connected" % devid)
 
@@ -416,14 +419,28 @@ class DevController:
         else:
             raise VmError("Device %s not connected" % devid)
 
+    def readBackendTxn(self, transaction, devid, *args):
+        frontpath = self.frontendPath(devid)
+        backpath = transaction.read(frontpath + "/backend")
+        if backpath:
+            paths = map(lambda x: backpath + "/" + x, args)
+            return transaction.read(*paths)
+        else:
+            raise VmError("Device %s not connected" % devid)
+
     def readFrontend(self, devid, *args):
         return xstransact.Read(self.frontendPath(devid), *args)
+
+    def readFrontendTxn(self, transaction, devid, *args):
+        paths = map(lambda x: self.frontendPath(devid) + "/" + x, args)
+        return transaction.read(*paths)
 
     def deviceIDs(self, transaction = None):
         """@return The IDs of each of the devices currently configured for
         this instance's deviceClass.
         """
         fe = self.backendRoot()
+
         if transaction:
             return map(lambda x: int(x.split('/')[-1]), transaction.list(fe))
         else:
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/server/blkif.py     Tue Oct 30 15:34:44 2007 -0600
@@ -124,19 +124,26 @@ class BlkifController(DevController):
                           (self.deviceClass, devid, config))
 
 
-    def getDeviceConfiguration(self, devid):
+    def getDeviceConfiguration(self, devid, transaction = None):
         """Returns the configuration of a device.
 
         @note: Similar to L{configuration} except it returns a dict.
         @return: dict
         """
-        config = DevController.getDeviceConfiguration(self, devid)
-        devinfo = self.readBackend(devid, 'dev', 'type', 'params', 'mode',
-                                   'uuid')
+        config = DevController.getDeviceConfiguration(self, devid, transaction)
+        if transaction is None:
+            devinfo = self.readBackend(devid, 'dev', 'type', 'params', 'mode',
+                                       'uuid')
+        else:
+            devinfo = self.readBackendTxn(transaction, devid,
+                                          'dev', 'type', 'params', 'mode', 
'uuid')
         dev, typ, params, mode, uuid = devinfo
         
         if dev:
-            dev_type = self.readFrontend(devid, 'device-type')
+            if transaction is None:
+                dev_type = self.readFrontend(devid, 'device-type')
+            else:
+                dev_type = self.readFrontendTxn(transaction, devid, 
'device-type')
             if dev_type:
                 dev += ':' + dev_type
             config['dev'] = dev
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/server/netif.py     Tue Oct 30 15:34:44 2007 -0600
@@ -183,17 +183,20 @@ class NetifController(DevController):
                               "network device")
 
 
-    def getDeviceConfiguration(self, devid):
+    def getDeviceConfiguration(self, devid, transaction = None):
         """@see DevController.configuration"""
 
-        result = DevController.getDeviceConfiguration(self, devid)
+        result = DevController.getDeviceConfiguration(self, devid, transaction)
 
         config_path = "device/%s/%d/" % (self.deviceClass, devid)
         devinfo = ()
         for x in ( 'script', 'ip', 'bridge', 'mac',
                    'type', 'vifname', 'rate', 'uuid', 'model', 'accel',
                    'security_label'):
-            y = self.vm._readVm(config_path + x)
+            if transaction is None:
+                y = self.vm._readVm(config_path + x)
+            else:
+                y = self.vm._readVmTxn(transaction, config_path + x)
             devinfo += (y,)
         (script, ip, bridge, mac, typ, vifname, rate, uuid,
          model, accel, security_label) = devinfo
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/server/pciif.py     Tue Oct 30 15:34:44 2007 -0600
@@ -78,8 +78,8 @@ class PciController(DevController):
         back['uuid'] = config.get('uuid','')
         return (0, back, {})
 
-    def getDeviceConfiguration(self, devid):
-        result = DevController.getDeviceConfiguration(self, devid)
+    def getDeviceConfiguration(self, devid, transaction = None):
+        result = DevController.getDeviceConfiguration(self, devid, transaction)
         num_devs = self.readBackend(devid, 'num_devs')
         pci_devs = []
         
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/server/tpmif.py     Tue Oct 30 15:34:44 2007 -0600
@@ -75,9 +75,9 @@ class TPMifController(DevController):
 
         return (devid, back, front)
 
-    def getDeviceConfiguration(self, devid):
+    def getDeviceConfiguration(self, devid, transaction = None):
         """Returns the configuration of a device"""
-        result = DevController.getDeviceConfiguration(self, devid)
+        result = DevController.getDeviceConfiguration(self, devid, transaction)
 
         (instance, uuid, type) = \
                            self.readBackend(devid, 'instance',
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xend/server/vfbif.py     Tue Oct 30 15:34:44 2007 -0600
@@ -5,14 +5,6 @@ import xen.xend
 import xen.xend
 import os
 
-def spawn_detached(path, args, env):
-    p = os.fork()
-    if p == 0:
-        os.spawnve(os.P_NOWAIT, path, args, env)
-        os._exit(0)
-    else:
-        os.waitpid(p, 0)
-        
 CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
                   'display', 'xauthority', 'keymap',
                   'uuid', 'location', 'protocol']
@@ -35,73 +27,20 @@ class VfbifController(DevController):
         return (devid, back, {})
 
 
-    def getDeviceConfiguration(self, devid):
-        result = DevController.getDeviceConfiguration(self, devid)
+    def getDeviceConfiguration(self, devid, transaction = None):
+        result = DevController.getDeviceConfiguration(self, devid, transaction)
 
-        devinfo = self.readBackend(devid, *CONFIG_ENTRIES)
+        if transaction is None:
+            devinfo = self.readBackend(devid, *CONFIG_ENTRIES)
+        else:
+            devinfo = self.readBackendTxn(transaction, devid, *CONFIG_ENTRIES)
         return dict([(CONFIG_ENTRIES[i], devinfo[i])
                      for i in range(len(CONFIG_ENTRIES))
                      if devinfo[i] is not None])
 
-
-    def createDevice(self, config):
-        DevController.createDevice(self, config)
-        if self.vm.info.is_hvm():
-            # is HVM, so qemu-dm will handle the vfb.
-            return
-        
-        std_args = [ "--domid", "%d" % self.vm.getDomid(),
-                     "--title", self.vm.getName() ]
-        t = config.get("type", None)
-        if t == "vnc":
-            passwd = None
-            if config.has_key("vncpasswd"):
-                passwd = config["vncpasswd"]
-            else:
-                passwd = 
xen.xend.XendOptions.instance().get_vncpasswd_default()
-            if passwd:
-                self.vm.storeVm("vncpasswd", passwd)
-                log.debug("Stored a VNC password for vfb access")
-            else:
-                log.debug("No VNC passwd configured for vfb access")
-
-            # Try to start the vnc backend
-            args = [xen.util.auxbin.pathTo("xen-vncfb")]
-            if config.has_key("vncunused"):
-                args += ["--unused"]
-            elif config.has_key("vncdisplay"):
-                args += ["--vncport", "%d" % (5900 + 
int(config["vncdisplay"]))]
-            vnclisten = config.get("vnclisten",
-                                   
xen.xend.XendOptions.instance().get_vnclisten_address())
-            args += [ "--listen", vnclisten ]
-            if config.has_key("keymap"):
-                args += ["-k", "%s" % config["keymap"]]
-            else:
-                xoptions = xen.xend.XendOptions.instance()
-                if xoptions.get_keymap():
-                    args += ["-k", "%s" % xoptions.get_keymap()]
-
-            spawn_detached(args[0], args + std_args, os.environ)
-        elif t == "sdl":
-            args = [xen.util.auxbin.pathTo("xen-sdlfb")]
-            env = dict(os.environ)
-            if config.has_key("display"):
-                env['DISPLAY'] = config["display"]
-            if config.has_key("xauthority"):
-                env['XAUTHORITY'] = config["xauthority"]
-            spawn_detached(args[0], args + std_args, env)
-        else:
-            raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
-
-
     def waitForDevice(self, devid):
-        if self.vm.info.get('HVM_boot_policy'):
-            log.debug('skip waiting for HVM vfb')
-            # is a qemu-dm managed device, don't wait for hotplug for these.
-            return
-
-        DevController.waitForDevice(self, devid)
-
+        # is a qemu-dm managed device, don't wait for hotplug for these.
+        return
 
     def reconfigureDevice(self, _, config):
         """ Only allow appending location information of vnc port into
@@ -115,19 +54,16 @@ class VfbifController(DevController):
         raise VmError('Refusing to reconfigure device vfb:%d' % devid)
 
     def destroyDevice(self, devid, force):
-        if self.vm.info.get('HVM_boot_policy'):
-            # remove the backend xenstore entries for HVM guests no matter
-            # what
-            DevController.destroyDevice(self, devid, True)
-        else:
-            DevController.destroyDevice(self, devid, force)
+        # remove the backend xenstore entries no matter what
+        # because we kill qemu-dm with extreme prejudice
+        # not giving it a chance to remove them itself
+        DevController.destroyDevice(self, devid, True)
 
 
     def migrate(self, deviceConfig, network, dst, step, domName):
-        if self.vm.info.get('HVM_boot_policy'):        
-            return 0
-        return DevController.migrate(self, deviceConfig, network, dst, step,
-                                     domName)
+        # Handled by qemu-dm so no action needed
+        return 0
+
     
 class VkbdifController(DevController):
     """Virtual keyboard controller. Handles all vkbd devices for a domain.
@@ -141,22 +77,15 @@ class VkbdifController(DevController):
         return (devid, back, front)
 
     def waitForDevice(self, config):
-        if self.vm.info.get('HVM_boot_policy'):
-            # is a qemu-dm managed device, don't wait for hotplug for these.
-            return
-
-        DevController.waitForDevice(self, config)
+        # is a qemu-dm managed device, don't wait for hotplug for these.
+        return
 
     def destroyDevice(self, devid, force):
-        if self.vm.info.get('HVM_boot_policy'):
-            # remove the backend xenstore entries for HVM guests no matter
-            # what
-            DevController.destroyDevice(self, devid, True)
-        else:
-            DevController.destroyDevice(self, devid, force)
+        # remove the backend xenstore entries no matter what
+        # because we kill qemu-dm with extreme prejudice
+        # not giving it a chance to remove them itself
+        DevController.destroyDevice(self, devid, True)
 
     def migrate(self, deviceConfig, network, dst, step, domName):
-        if self.vm.info.get('HVM_boot_policy'):        
-            return 0
-        return DevController.migrate(self, deviceConfig, network, dst, step,
-                                     domName)        
+        # Handled by qemu-dm so no action needed
+        return 0
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xm/addlabel.py
--- a/tools/python/xen/xm/addlabel.py   Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xm/addlabel.py   Tue Oct 30 15:34:44 2007 -0600
@@ -117,15 +117,18 @@ def add_resource_label(label, resource, 
                                                           res_xapi,
                                                           "")
             except Exception, e:
-                security.err("Could not label this resource: %s" % e)
-        else:
-            security.err("'%s' is already labeled with '%s'" % (resource,old))
+                raise security.XSMError("Could not label this resource: %s" %
+                                        str(e))
+        else:
+            raise security.XSMError("'%s' is already labeled with '%s'" %
+                                    (resource,old))
 
 def add_domain_label(label, configfile, policyref):
     # sanity checks: make sure this label can be instantiated later on
     ssidref = security.label2ssidref(label, policyref, 'dom')
 
-    new_label = "access_control = ['policy=%s,label=%s']\n" % (policyref, 
label)
+    new_label = "access_control = ['policy=%s,label=%s']\n" % \
+                (policyref, label)
     if not os.path.isfile(configfile):
         security.err("Configuration file \'" + configfile + "\' not found.")
     config_fd = open(configfile, "ra+")
@@ -150,14 +153,14 @@ def add_domain_label_xapi(label, domainn
     try:
         old_lab = server.xenapi.VM.get_security_label(uuid)
         rc = server.xenapi.VM.set_security_label(uuid, sec_lab, old_lab)
-    except:
-        rc = -1
+    except Exception, e:
+        raise security.XSMError("Could not label the domain: %s" % e)
     if int(rc) < 0:
         raise OptionError('Could not label domain.')
     else:
         ssidref = int(rc)
         if ssidref != 0:
-            print "Set the label of domain '%s' to '%s'. New ssidref = %08x" % 
\
+            print "Set the label of domain '%s' to '%s'. New ssidref = %08x" %\
                   (domainname,label,ssidref)
         else:
             print "Set the label of dormant domain '%s' to '%s'." % \
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xm/create.py     Tue Oct 30 15:34:44 2007 -0600
@@ -193,6 +193,11 @@ gopts.var('pae', val='PAE',
 gopts.var('pae', val='PAE',
           fn=set_int, default=1,
           use="Disable or enable PAE of HVM domain.")
+
+gopts.var('timer_mode', val='TIMER_MODE',
+          fn=set_int, default=0,
+          use="""Timer mode (0=delay virtual time when ticks are missed;
+          1=virtual time is always wallclock time.""")
 
 gopts.var('acpi', val='ACPI',
           fn=set_int, default=1,
@@ -724,7 +729,7 @@ def configure_hvm(config_image, vals):
 def configure_hvm(config_image, vals):
     """Create the config for HVM devices.
     """
-    args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb',
+    args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb', 
'timer_mode',
              'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
              'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
              'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor',
@@ -1228,7 +1233,7 @@ def config_security_check(config, verbos
             if verbose:
                 print "   %s: PERMITTED" % (resource)
 
-        except security.XSMError:
+        except security.ACMError:
             print "   %s: DENIED" % (resource)
             (poltype, res_label, res_policy) = security.get_res_label(resource)
             if not res_label:
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py    Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xm/rmlabel.py    Tue Oct 30 15:34:44 2007 -0600
@@ -50,9 +50,10 @@ def rm_resource_label(resource):
                 server.xenapi.XSPolicy.set_resource_label(resource,"",
                                                           oldlabel)
             else:
-                raise security.ACMError("Resource not labeled")
+                raise security.XSMError("Resource not labeled")
         except Exception, e:
-            print "Could not remove label from resource: %s" % e
+            raise security.XSMError("Could not remove label "
+                                    "from resource: %s" % e)
         return
 
     #build canonical resource name
@@ -128,7 +129,7 @@ def rm_domain_label_xapi(domainname):
         old_lab = server.xenapi.VM.get_security_label(uuid)
         server.xenapi.VM.set_security_label(uuid, "", old_lab)
     except Exception, e:
-        print('Could not remove label from domain: %s' % e)
+        raise security.XSMError('Could not remove label from domain: %s' % e)
 
 def rm_vif_label(vmname, idx):
     if xm_main.serverType != xm_main.SERVER_XEN_API:
@@ -142,16 +143,21 @@ def rm_vif_label(vmname, idx):
         raise OptionError("Bad VIF index.")
     vif_ref = server.xenapi.VIF.get_by_uuid(vif_refs[idx])
     if not vif_ref:
-        print "A VIF with this UUID does not exist."
+        raise security.XSMError("A VIF with this UUID does not exist.")
     try:
         old_lab = server.xenapi.VIF.get_security_label(vif_ref)
-        rc = server.xenapi.VIF.set_security_label(vif_ref, "", old_lab)
-        if int(rc) != 0:
-            print "Could not remove the label from the VIF."
+        if old_lab != "":
+            rc = server.xenapi.VIF.set_security_label(vif_ref, "", old_lab)
+            if int(rc) != 0:
+                raise security.XSMError("Could not remove the label from"
+                                        " the VIF.")
+            else:
+                print "Successfully removed the label from the VIF."
         else:
-            print "Successfully removed the label from the VIF."
+            raise security.XSMError("VIF is not labeled.")
     except Exception, e:
-        print "Could not remove the label the VIF: %s" % str(e)
+        raise security.XSMError("Could not remove the label from the VIF: %s" %
+                                str(e))
 
 
 def main (argv):
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xm/setpolicy.py
--- a/tools/python/xen/xm/setpolicy.py  Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xm/setpolicy.py  Tue Oct 30 15:34:44 2007 -0600
@@ -23,6 +23,7 @@ import struct
 import struct
 import sys
 import string
+import xen.util.xsm.xsm as security
 from xen.util import xsconstants
 from xen.util.acmpolicy import ACMPolicy
 from xen.xm.opts import OptionError
@@ -100,21 +101,22 @@ def setpolicy(policytype, policy_name, f
                                                               flags,
                                                               overwrite)
         except Exception, e:
-            print "An error occurred setting the policy: %s" % str(e)
-            return
+            raise security.XSMError("An error occurred setting the "
+                                    "policy: %s" % str(e))
         xserr = int(policystate['xserr'])
         if xserr != 0:
-            print "An error occurred trying to set the policy: %s" % \
+            txt = "An error occurred trying to set the policy: %s." % \
                   xsconstants.xserr2string(abs(xserr))
             errors = policystate['errors']
             if len(errors) > 0:
-                print "Hypervisor reported errors:"
+                txt += "Hypervisor reported errors:"
                 err = base64.b64decode(errors)
                 i = 0
                 while i + 7 < len(err):
                     code, data = struct.unpack("!ii", errors[i:i+8])
-                    print "(0x%08x, 0x%08x)" % (code, data)
+                    txt += "(0x%08x, 0x%08x)" % (code, data)
                     i += 8
+            raise security.XSMError(txt)
         else:
             print "Successfully set the new policy."
 
diff -r c17bfb091790 -r a07288a84785 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/python/xen/xm/xenapi_create.py      Tue Oct 30 15:34:44 2007 -0600
@@ -818,7 +818,7 @@ class sxp2xml:
 
 
     def extract_platform(self, image, document):
-        platform_keys = ['acpi', 'apic', 'pae', 'vhpt']
+        platform_keys = ['acpi', 'apic', 'pae', 'vhpt', 'timer_mode']
 
         def extract_platform_key(key):
             platform = document.createElement("platform")
diff -r c17bfb091790 -r a07288a84785 tools/xenfb/Makefile
--- a/tools/xenfb/Makefile      Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-XEN_ROOT=../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-CFLAGS  += -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
-CFLAGS  += -I$(XEN_ROOT)/tools/ioemu
-LDFLAGS += -L$(XEN_LIBXC) -L$(XEN_XENSTORE)
-
-.PHONY: all
-all: build
-
-.PHONY: build
-build:
-       $(MAKE) vncfb sdlfb
-
-install: all
-       $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
-       $(INSTALL_PROG) vncfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-vncfb
-       $(INSTALL_PROG) sdlfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-sdlfb
-
-sdlfb: sdlfb.o xenfb.o
-
-sdlfb.o: CFLAGS += $(shell sdl-config --cflags)
-sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl -lxenstore
-
-clean:
-       $(RM) *.o *~ vncfb sdlfb
-
-vncfb: vncfb.o xenfb.o
-vncfb.o: CFLAGS += $(shell libvncserver-config --cflags)
-vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl -lxenstore
-
-sdlfb.o xenfb.o vncfb.o: xenfb.h
diff -r c17bfb091790 -r a07288a84785 tools/xenfb/sdlfb.c
--- a/tools/xenfb/sdlfb.c       Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,342 +0,0 @@
-#include <SDL.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <stdlib.h>
-#include <linux/input.h>
-#include <getopt.h>
-#include <string.h>
-#include "xenfb.h"
-
-struct SDLFBData
-{
-       SDL_Surface *dst;
-       SDL_Surface *src;
-};
-
-/*
- * Map from scancode to Linux input layer keycode.  Scancodes are
- * hardware-specific.  This map assumes a standard AT or PS/2
- * keyboard.
- *
- * Why use scancodes?  We can't use key symbols, because they don't
- * identify keys --- they're what keys are mapped to.  The standard
- * German keymap, for instance, maps both KEY_COMMA and KEY_102ND to
- * SDLK_LESS.
- */
-static int keymap[256] = {
-       [9] = KEY_ESC,
-       [10] = KEY_1,
-       [11] = KEY_2,
-       [12] = KEY_3,
-       [13] = KEY_4,
-       [14] = KEY_5,
-       [15] = KEY_6,
-       [16] = KEY_7,
-       [17] = KEY_8,
-       [18] = KEY_9,
-       [19] = KEY_0,
-       [20] = KEY_MINUS,
-       [21] = KEY_EQUAL,
-       [22] = KEY_BACKSPACE,
-       [23] = KEY_TAB,
-       [24] = KEY_Q,
-       [25] = KEY_W,
-       [26] = KEY_E,
-       [27] = KEY_R,
-       [28] = KEY_T,
-       [29] = KEY_Y,
-       [30] = KEY_U,
-       [31] = KEY_I,
-       [32] = KEY_O,
-       [33] = KEY_P,
-       [34] = KEY_LEFTBRACE,
-       [35] = KEY_RIGHTBRACE,
-       [36] = KEY_ENTER,
-       [37] = KEY_LEFTCTRL,
-       [38] = KEY_A,
-       [39] = KEY_S,
-       [40] = KEY_D,
-       [41] = KEY_F,
-       [42] = KEY_G,
-       [43] = KEY_H,
-       [44] = KEY_J,
-       [45] = KEY_K,
-       [46] = KEY_L,
-       [47] = KEY_SEMICOLON,
-       [48] = KEY_APOSTROPHE,
-       [49] = KEY_GRAVE,
-       [50] = KEY_LEFTSHIFT,
-       [51] = KEY_BACKSLASH,
-       [52] = KEY_Z,
-       [53] = KEY_X,
-       [54] = KEY_C,
-       [55] = KEY_V,
-       [56] = KEY_B,
-       [57] = KEY_N,
-       [58] = KEY_M,
-       [59] = KEY_COMMA,
-       [60] = KEY_DOT,
-       [61] = KEY_SLASH,
-       [62] = KEY_RIGHTSHIFT,
-       [63] = KEY_KPASTERISK,
-       [64] = KEY_LEFTALT,
-       [65] = KEY_SPACE,
-       [66] = KEY_CAPSLOCK,
-       [67] = KEY_F1,
-       [68] = KEY_F2,
-       [69] = KEY_F3,
-       [70] = KEY_F4,
-       [71] = KEY_F5,
-       [72] = KEY_F6,
-       [73] = KEY_F7,
-       [74] = KEY_F8,
-       [75] = KEY_F9,
-       [76] = KEY_F10,
-       [77] = KEY_NUMLOCK,
-       [78] = KEY_SCROLLLOCK,
-       [79] = KEY_KP7,
-       [80] = KEY_KP8,
-       [81] = KEY_KP9,
-       [82] = KEY_KPMINUS,
-       [83] = KEY_KP4,
-       [84] = KEY_KP5,
-       [85] = KEY_KP6,
-       [86] = KEY_KPPLUS,
-       [87] = KEY_KP1,
-       [88] = KEY_KP2,
-       [89] = KEY_KP3,
-       [90] = KEY_KP0,
-       [91] = KEY_KPDOT,
-       [94] = KEY_102ND,       /* FIXME is this correct? */
-       [95] = KEY_F11,
-       [96] = KEY_F12,
-       [108] = KEY_KPENTER,
-       [109] = KEY_RIGHTCTRL,
-       [112] = KEY_KPSLASH,
-       [111] = KEY_SYSRQ,
-       [113] = KEY_RIGHTALT,
-       [97] = KEY_HOME,
-       [98] = KEY_UP,
-       [99] = KEY_PAGEUP,
-       [100] = KEY_LEFT,
-       [102] = KEY_RIGHT,
-       [103] = KEY_END,
-       [104] = KEY_DOWN,
-       [105] = KEY_PAGEDOWN,
-       [106] = KEY_INSERT,
-       [107] = KEY_DELETE,
-       [110] = KEY_PAUSE,
-       [115] = KEY_LEFTMETA,
-       [116] = KEY_RIGHTMETA,
-       [117] = KEY_MENU,
-};
-
-static int btnmap[] = {
-       [SDL_BUTTON_LEFT] = BTN_LEFT,
-       [SDL_BUTTON_MIDDLE] = BTN_MIDDLE,
-       [SDL_BUTTON_RIGHT] = BTN_RIGHT,
-       /* FIXME not 100% sure about these: */
-       [SDL_BUTTON_WHEELUP] = BTN_FORWARD,
-       [SDL_BUTTON_WHEELDOWN] BTN_BACK
-};
-
-static void sdl_update(struct xenfb *xenfb, int x, int y, int width, int 
height)
-{
-       struct SDLFBData *data = xenfb->user_data;
-       SDL_Rect r = { x, y, width, height };
-       SDL_BlitSurface(data->src, &r, data->dst, &r);
-       SDL_UpdateRect(data->dst, x, y, width, height);
-}
-
-static int sdl_on_event(struct xenfb *xenfb, SDL_Event *event)
-{
-       int x, y, ret;
-
-       switch (event->type) {
-       case SDL_KEYDOWN:
-       case SDL_KEYUP:
-               if (keymap[event->key.keysym.scancode] == 0)
-                       break;
-               ret = xenfb_send_key(xenfb,
-                                    event->type == SDL_KEYDOWN,
-                                    keymap[event->key.keysym.scancode]);
-               if (ret < 0)
-                       fprintf(stderr, "Key %d %s lost (%s)\n",
-                               keymap[event->key.keysym.scancode],
-                               event->type == SDL_KEYDOWN ? "down" : "up",
-                               strerror(errno));
-               break;
-       case SDL_MOUSEMOTION:
-               if (xenfb->abs_pointer_wanted) {
-                       SDL_GetMouseState(&x, &y);
-                       ret = xenfb_send_position(xenfb, x, y);
-               } else {
-                       SDL_GetRelativeMouseState(&x, &y);
-                       ret = xenfb_send_motion(xenfb, x, y);
-               }
-               if (ret < 0)
-                       fprintf(stderr, "Pointer to %d,%d lost (%s)\n",
-                               x, y, strerror(errno));
-               break;
-       case SDL_MOUSEBUTTONDOWN:
-       case SDL_MOUSEBUTTONUP:
-               if (event->button.button >= sizeof(btnmap) / sizeof(*btnmap))
-                       break;
-               if (btnmap[event->button.button] == 0)
-                       break;
-               ret = xenfb_send_key(xenfb,
-                                    event->type == SDL_MOUSEBUTTONDOWN,
-                                    btnmap[event->button.button]);
-               if (ret < 0)
-                       fprintf(stderr, "Button %d %s lost (%s)\n",
-                               btnmap[event->button.button] - BTN_MOUSE,
-                               event->type == SDL_MOUSEBUTTONDOWN ? "down" : 
"up",
-                               strerror(errno));
-               break;
-       case SDL_QUIT:
-               return 0;
-       }
-
-       return 1;
-}
-
-static struct option options[] = {
-       { "domid", 1, NULL, 'd' },
-       { "title", 1, NULL, 't' },
-       { NULL }
-};
-
-int main(int argc, char **argv)
-{
-       struct xenfb *xenfb;
-       int domid = -1;
-        char * title = NULL;
-       fd_set readfds;
-       int nfds;
-       struct SDLFBData data;
-       SDL_Rect r;
-       struct timeval tv;
-       SDL_Event event;
-       int do_quit = 0;
-       int opt;
-       char *endp;
-       int retval;
-
-       while ((opt = getopt_long(argc, argv, "d:t:", options,
-                                 NULL)) != -1) {
-               switch (opt) {
-                case 'd':
-                       domid = strtol(optarg, &endp, 10);
-                       if (endp == optarg || *endp) {
-                               fprintf(stderr, "Invalid domain id 
specified\n");
-                               exit(1);
-                       }
-                       break;
-                case 't':
-                       title = strdup(optarg);
-                       break;
-               case '?':
-                       exit(1);
-                }
-        }
-        if (optind != argc) {
-               fprintf(stderr, "Invalid options!\n");
-               exit(1);
-        }
-        if (domid <= 0) {
-               fprintf(stderr, "Domain ID must be specified!\n");
-               exit(1);
-        }
-
-       xenfb = xenfb_new();
-       if (xenfb == NULL) {
-               fprintf(stderr, "Could not create framebuffer (%s)\n",
-                       strerror(errno));
-               exit(1);
-        }
-
-       if (xenfb_attach_dom(xenfb, domid) < 0) {
-               fprintf(stderr, "Could not connect to domain (%s)\n",
-                       strerror(errno));
-               exit(1);
-        }
-
-       if (SDL_Init(SDL_INIT_VIDEO) < 0) {
-               fprintf(stderr, "Could not initialize SDL\n");
-               exit(1);
-       }
-
-       data.dst = SDL_SetVideoMode(xenfb->width, xenfb->height, xenfb->depth,
-                                   SDL_SWSURFACE);
-       if (!data.dst) {
-               fprintf(stderr, "SDL_SetVideoMode failed\n");
-               exit(1);
-       }
-
-       data.src = SDL_CreateRGBSurfaceFrom(xenfb->pixels,
-                                           xenfb->width, xenfb->height,
-                                           xenfb->depth, xenfb->row_stride,
-                                           0xFF0000, 0xFF00, 0xFF, 0);
-
-       if (!data.src) {
-               fprintf(stderr, "SDL_CreateRGBSurfaceFrom failed\n");
-               exit(1);
-       }
-
-        if (title == NULL)
-               title = strdup("xen-sdlfb");
-        SDL_WM_SetCaption(title, title);
-
-       r.x = r.y = 0;
-       r.w = xenfb->width;
-       r.h = xenfb->height;
-       SDL_BlitSurface(data.src, &r, data.dst, &r);
-       SDL_UpdateRect(data.dst, 0, 0, xenfb->width, xenfb->height);
-
-       xenfb->update = sdl_update;
-       xenfb->user_data = &data;
-
-       SDL_ShowCursor(0);
-
-       /*
-        * We need to wait for fds becoming ready or SDL events to
-        * arrive.  We time out the select after 10ms to poll for SDL
-        * events.  Clunky, but works.  Could avoid the clunkiness
-        * with a separate thread.
-        */
-       for (;;) {
-               FD_ZERO(&readfds);
-               nfds = xenfb_select_fds(xenfb, &readfds);
-               tv = (struct timeval){0, 10000};
-
-               if (select(nfds, &readfds, NULL, NULL, &tv) < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       fprintf(stderr,
-                               "Can't select() on event channel (%s)\n",
-                               strerror(errno));
-                       break;
-               }
-
-               while (SDL_PollEvent(&event)) {
-                       if (!sdl_on_event(xenfb, &event))
-                               do_quit = 1;
-               }
-
-                if (do_quit)
-                       break;
-
-               retval = xenfb_poll(xenfb, &readfds);
-               if (retval == -2)
-                   xenfb_teardown(xenfb);
-               if (retval < 0)
-                   break;
-       }
-
-       xenfb_delete(xenfb);
-
-       SDL_Quit();
-
-       return 0;
-}
diff -r c17bfb091790 -r a07288a84785 tools/xenfb/vncfb.c
--- a/tools/xenfb/vncfb.c       Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,522 +0,0 @@
-#define _GNU_SOURCE
-#include <errno.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <rfb/rfb.h>
-#include <rfb/keysym.h>
-#include <linux/input.h>
-#include <xs.h>
-#include "xenfb.h"
-
-/* Grab key translation support routines from qemu directory. */
-#define qemu_mallocz(size) calloc(1, (size))
-static const char *bios_dir = "/usr/share/xen/qemu";
-#include "vnc_keysym.h"
-#include "keymaps.c"
-
-static unsigned char atkbd_set2_keycode[512] = {
-
-         0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
-         0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
-         0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
-         0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
-         0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
-         0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
-         0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
-        82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
-
-         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-       217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
-       173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
-       159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
-       157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
-       226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
-         0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
-       110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
-
-};
-
-static unsigned char atkbd_unxlate_table[128] = {
-
-         0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
-        21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
-        35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
-        50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
-        11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
-       114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
-        71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
-        19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
-
-};
-
-unsigned char keycode_table[512];
-
-static void *kbd_layout;
-uint8_t modifiers_state[256];
-
-static int btnmap[] = {
-       BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
-       BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
-};
-
-static void press_key_shift_down(struct xenfb* xenfb, int down, int scancode)
-{
-       if (down)
-               xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
-
-       if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
-               fprintf(stderr, "Key %d %s lost (%s)\n",
-                       scancode, "down", strerror(errno));
-
-       if (!down)
-               xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
-}
-
-static void press_key_shift_up(struct xenfb* xenfb, int down, int scancode)
-{
-       if (down) {
-               if (modifiers_state[0x2a])
-                       xenfb_send_key(xenfb, 0, keycode_table[0x2a]);
-               if (modifiers_state[0x36])
-                       xenfb_send_key(xenfb, 0, keycode_table[0x36]);
-       }
-
-       if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
-               fprintf(stderr, "Key %d %s lost (%s)\n",
-                       scancode, "down", strerror(errno));
-
-       if (!down) {
-               if (modifiers_state[0x2a])
-                       xenfb_send_key(xenfb, 1, keycode_table[0x2a]);
-               if (modifiers_state[0x36])
-                       xenfb_send_key(xenfb, 1, keycode_table[0x36]);
-       }
-}
-
-static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
-{
-       /*
-        * We need to map to the key's Linux input layer keycode.
-        * Unfortunately, we don't get the key here, only the
-        * rfbKeySym, which is what the key is mapped to.  Mapping
-        * back to the key is impossible in general, even when you
-        * know the keymap.  For instance, the standard German keymap
-        * maps both KEY_COMMA and KEY_102ND to XK_less.  We simply
-        * assume standard US layout.  This sucks.
-        */
-       rfbScreenInfoPtr server = cl->screen;
-       struct xenfb *xenfb = server->screenData;
-       int scancode;
-       int shift = 0;
-       int shift_keys = 0;
-
-       if (keycode >= 'A' && keycode <= 'Z') {
-               keycode += 'a' - 'A';
-               shift = 1;
-       }
-       else {
-               shift = keysymIsShift(kbd_layout, keycode);
-       }
-       shift_keys = modifiers_state[0x2a] | modifiers_state[0x36];     
-
-       scancode = keysym2scancode(kbd_layout, keycode);
-       if (scancode == 0)
-               return;
-
-       switch(scancode) {
-       case 0x2a:                      /* Left Shift */
-       case 0x36:                      /* Right Shift */
-       case 0x1d:                      /* Left CTRL */
-       case 0x9d:                      /* Right CTRL */
-       case 0x38:                      /* Left ALT */
-       case 0xb8:                      /* Right ALT */
-               if (down)
-                       modifiers_state[scancode] = 1;
-               else
-                       modifiers_state[scancode] = 0;
-               xenfb_send_key(xenfb, down, keycode_table[scancode]); 
-               return;
-       case 0x45:                      /* NumLock */
-               if (!down)
-                       modifiers_state[scancode] ^= 1;
-               xenfb_send_key(xenfb, down, keycode_table[scancode]);
-               return;
-       }
-
-       if (keycodeIsKeypad(kbd_layout, scancode)) {
-       /* If the numlock state needs to change then simulate an additional
-          keypress before sending this one.  This will happen if the user
-          toggles numlock away from the VNC window.
-       */
-               if (keysymIsNumlock(kbd_layout, keycode)) {
-                       if (!modifiers_state[0x45]) {
-                               modifiers_state[0x45] = 1;
-                               xenfb_send_key(xenfb, 1, keycode_table[0x45]);
-                               xenfb_send_key(xenfb, 0, keycode_table[0x45]);
-                       }
-               } else {
-                       if (modifiers_state[0x45]) {
-                               modifiers_state[0x45] = 0;
-                               xenfb_send_key(xenfb, 1, keycode_table[0x45]);
-                               xenfb_send_key(xenfb, 0, keycode_table[0x45]);
-                       }
-               }
-       }
-
-       /* If the shift state needs to change then simulate an additional
-          keypress before sending this one.
-       */
-       if (shift && !shift_keys) {
-               press_key_shift_down(xenfb, down, scancode);
-               return;
-       }
-       else if (!shift && shift_keys) {
-               press_key_shift_up(xenfb, down, scancode);
-               return;
-       }
-
-       if (xenfb_send_key(xenfb, down, keycode_table[scancode]) < 0)
-               fprintf(stderr, "Key %d %s lost (%s)\n",
-                       scancode, down ? "down" : "up",
-                       strerror(errno));
-}
-
-static void on_ptr_event(int buttonMask, int x, int y, rfbClientPtr cl)
-{
-       /* initial pointer state: at (0,0), buttons up */
-       static int last_x, last_y, last_button;
-       rfbScreenInfoPtr server = cl->screen;
-       struct xenfb *xenfb = server->screenData;
-       int i, last_down, down, ret;
-
-       for (i = 0; i < 8; i++) {
-               last_down = last_button & (1 << i);
-               down = buttonMask & (1 << i);
-               if (down == last_down)
-                       continue;
-               if (i >= sizeof(btnmap) / sizeof(*btnmap))
-                       break;
-               if (btnmap[i] == 0)
-                       break;
-               if (xenfb_send_key(xenfb, down != 0, btnmap[i]) < 0)
-                       fprintf(stderr, "Button %d %s lost (%s)\n",
-                               i, down ? "down" : "up", strerror(errno));
-       }
-
-       if (x != last_x || y != last_y) {
-               if (xenfb->abs_pointer_wanted) 
-                       ret = xenfb_send_position(xenfb, x, y);
-               else
-                       ret = xenfb_send_motion(xenfb, x - last_x, y - last_y);
-               if (ret < 0)
-                       fprintf(stderr, "Pointer to %d,%d lost (%s)\n",
-                               x, y, strerror(errno));
-       }
-
-       last_button = buttonMask;
-       last_x = x;
-       last_y = y;
-}
-
-static void xenstore_write_vncport(struct xs_handle *xsh, int port, int domid)
-{
-       char *buf, *path;
-       char portstr[10];
-
-       path = xs_get_domain_path(xsh, domid);
-       if (path == NULL) {
-               fprintf(stderr, "Can't get domain path (%s)\n",
-                       strerror(errno));
-               goto out;
-       }
-
-       if (asprintf(&buf, "%s/console/vnc-port", path) == -1) {
-               fprintf(stderr, "Can't make vncport path\n");
-               goto out;
-       }
-
-       if (snprintf(portstr, sizeof(portstr), "%d", port) == -1) {
-               fprintf(stderr, "Can't make vncport value\n");
-               goto out;
-       }
-
-       if (!xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)))
-               fprintf(stderr, "Can't set vncport (%s)\n",
-                       strerror(errno));
-
- out:
-       free(buf);
-}
-
-
-static int xenstore_read_vncpasswd(struct xs_handle *xsh, int domid, char 
*pwbuf, int pwbuflen)
-{
-       char buf[256], *path, *uuid = NULL, *passwd = NULL;
-       unsigned int len, rc = 0;
-
-       if (xsh == NULL) {
-               return -1;
-       }
-
-       path = xs_get_domain_path(xsh, domid);
-       if (path == NULL) {
-               fprintf(stderr, "xs_get_domain_path() error\n");
-               return -1;
-       }
-
-       snprintf(buf, 256, "%s/vm", path);
-       uuid = xs_read(xsh, XBT_NULL, buf, &len);
-       if (uuid == NULL) {
-               fprintf(stderr, "xs_read(): uuid get error\n");
-               free(path);
-               return -1;
-       }
-
-       snprintf(buf, 256, "%s/vncpasswd", uuid);
-       passwd = xs_read(xsh, XBT_NULL, buf, &len);
-       if (passwd == NULL) {
-               free(uuid);
-               free(path);
-               return rc;
-       }
-
-       strncpy(pwbuf, passwd, pwbuflen-1);
-       pwbuf[pwbuflen-1] = '\0';
-
-       fprintf(stderr, "Got a VNC password read from XenStore\n");
-
-       passwd[0] = '\0';
-       snprintf(buf, 256, "%s/vncpasswd", uuid);
-       if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
-               fprintf(stderr, "xs_write() vncpasswd failed\n");
-               rc = -1;
-       }
-
-       free(passwd);
-       free(uuid);
-       free(path);
-
-       return rc;
-}
-
-static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h)
-{
-       rfbScreenInfoPtr server = xenfb->user_data;
-       rfbMarkRectAsModified(server, x, y, x + w, y + h);
-}
-
-static struct option options[] = {
-       { "domid", 1, NULL, 'd' },
-       { "vncport", 1, NULL, 'p' },
-       { "title", 1, NULL, 't' },
-       { "unused", 0, NULL, 'u' },
-       { "listen", 1, NULL, 'l' },
-       { "keymap", 1, NULL, 'k' },
-       { NULL }
-};
-
-int main(int argc, char **argv)
-{
-       rfbScreenInfoPtr server;
-       char *fake_argv[7] = { "vncfb", "-rfbport", "5901", 
-                               "-desktop", "xen-vncfb", 
-                               "-listen", "127.0.0.1" };
-       int fake_argc = sizeof(fake_argv) / sizeof(fake_argv[0]);
-       int domid = -1, port = -1;
-       char *title = NULL;
-       char *listen = NULL;
-       char *keymap = NULL;
-       bool unused = false;
-       int opt;
-       struct xenfb *xenfb;
-       fd_set readfds;
-       int nfds;
-       char portstr[10];
-       char *endp;
-       int r;
-       struct xs_handle *xsh;
-       char vncpasswd[1024];
-       int i;
-
-       vncpasswd[0] = '\0';
-
-       while ((opt = getopt_long(argc, argv, "d:p:t:uk:", options,
-                                 NULL)) != -1) {
-               switch (opt) {
-                case 'd':
-                       errno = 0;
-                       domid = strtol(optarg, &endp, 10);
-                       if (endp == optarg || *endp || errno) {
-                               fprintf(stderr, "Invalid domain id 
specified\n");
-                               exit(1);
-                       }
-                       break;
-                case 'p':
-                       errno = 0;
-                       port = strtol(optarg, &endp, 10);
-                       if (endp == optarg || *endp || errno) {
-                               fprintf(stderr, "Invalid port specified\n");
-                               exit(1);
-                       }
-                       break;
-                case 't':
-                       title = strdup(optarg);
-                       break;
-                case 'u':
-                       unused = true;
-                       break;
-                case 'l':
-                       listen = strdup(optarg);
-                       break;
-                case 'k':
-                       keymap = strdup(optarg);
-                       break;
-               case '?':
-                       exit(1);
-                }
-        }
-        if (optind != argc) {
-               fprintf(stderr, "Invalid options!\n");
-               exit(1);
-        }
-        if (domid <= 0) {
-               fprintf(stderr, "Domain ID must be specified!\n");
-               exit(1);
-        }
-            
-        if (port <= 0)
-               port = 5900 + domid;
-       if (snprintf(portstr, sizeof(portstr), "%d", port) == -1) {
-               fprintf(stderr, "Invalid port specified\n");
-               exit(1);
-        }
-
-       if (keymap == NULL){
-               keymap = "en-us";
-       }
-
-       kbd_layout = init_keyboard_layout(keymap);
-       if( !kbd_layout ){
-               fprintf(stderr, "Invalid keyboard_layout\n");
-               exit(1);
-        }
-
-       for (i = 0; i < 128; i++) {
-               keycode_table[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
-               keycode_table[i | 0x80] = 
-                       atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
-       }
-
-       for (i = 0; i < 256; i++ ) {
-               modifiers_state[i] = 0;
-       }
-
-       fake_argv[2] = portstr;
-
-        if (title != NULL)
-               fake_argv[4] = title;
-
-        if (listen != NULL)
-               fake_argv[6] = listen;
-
-       signal(SIGPIPE, SIG_IGN);
-
-       xenfb = xenfb_new();
-       if (xenfb == NULL) {
-               fprintf(stderr, "Could not create framebuffer (%s)\n",
-                       strerror(errno));
-               exit(1);
-       }
-
-       if (xenfb_attach_dom(xenfb, domid) < 0) {
-               fprintf(stderr, "Could not connect to domain (%s)\n",
-                       strerror(errno));
-               exit(1);
-       }
-
-       xsh = xs_daemon_open();
-       if (xsh == NULL) {
-               fprintf(stderr, "cannot open connection to xenstore\n");
-               exit(1);
-       }
-
-
-       if (xenstore_read_vncpasswd(xsh, domid, vncpasswd,
-                                   sizeof(vncpasswd)/sizeof(char)) < 0) {
-               fprintf(stderr, "cannot read VNC password from xenstore\n");
-               exit(1);
-       }
-         
-
-       server = rfbGetScreen(&fake_argc, fake_argv, 
-                             xenfb->width, xenfb->height,
-                             8, 3, xenfb->depth / 8);
-       if (server == NULL) {
-               fprintf(stderr, "Could not create VNC server\n");
-               exit(1);
-       }
-
-       xenfb->user_data = server;
-       xenfb->update = vnc_update;
-
-        if (unused)
-               server->autoPort = true;
-
-       if (vncpasswd[0]) {
-               char **passwds = malloc(sizeof(char**)*2);
-               if (!passwds) {
-                       fprintf(stderr, "cannot allocate memory (%s)\n",
-                               strerror(errno));
-                       exit(1);
-               }
-               fprintf(stderr, "Registered password\n");
-               passwds[0] = vncpasswd;
-               passwds[1] = NULL;
-
-               server->authPasswdData = passwds;
-               server->passwordCheck = rfbCheckPasswordByList;
-       } else {
-               fprintf(stderr, "Running with no password\n");
-       }
-       server->serverFormat.redShift = 16;
-       server->serverFormat.greenShift = 8;
-       server->serverFormat.blueShift = 0;
-       server->kbdAddEvent = on_kbd_event;
-       server->ptrAddEvent = on_ptr_event;
-       server->frameBuffer = xenfb->pixels;
-       server->screenData = xenfb;
-       server->cursor = NULL;
-       rfbInitServer(server);
-
-       rfbRunEventLoop(server, -1, true);
-
-        xenstore_write_vncport(xsh, server->port, domid);
-
-       for (;;) {
-               FD_ZERO(&readfds);
-               nfds = xenfb_select_fds(xenfb, &readfds);
-
-               if (select(nfds, &readfds, NULL, NULL, NULL) < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       fprintf(stderr,
-                               "Can't select() on event channel (%s)\n",
-                               strerror(errno));
-                       break;
-               }
-
-               r = xenfb_poll(xenfb, &readfds);
-               if (r == -2)
-                   xenfb_teardown(xenfb);
-               if (r < 0)
-                   break;
-       }
-
-       rfbScreenCleanup(server);
-       xenfb_delete(xenfb);
-
-       return 0;
-}
diff -r c17bfb091790 -r a07288a84785 tools/xenfb/xenfb.c
--- a/tools/xenfb/xenfb.c       Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,779 +0,0 @@
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <xenctrl.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/fbif.h>
-#include <xen/io/kbdif.h>
-#include <xen/io/protocols.h>
-#include <sys/select.h>
-#include <stdbool.h>
-#include <xen/event_channel.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <xs.h>
-
-#include "xenfb.h"
-
-// FIXME defend against malicious frontend?
-
-struct xenfb_device {
-       const char *devicetype;
-       char nodename[64];      /* backend xenstore dir */
-       char otherend[64];      /* frontend xenstore dir */
-       int otherend_id;        /* frontend domid */
-       enum xenbus_state state; /* backend state */
-       void *page;             /* shared page */
-       evtchn_port_t port;
-       struct xenfb_private *xenfb;
-};
-
-struct xenfb_private {
-       struct xenfb pub;
-       int evt_xch;            /* event channel driver handle */
-       int xc;                 /* hypervisor interface handle */
-       struct xs_handle *xsh;  /* xs daemon handle */
-       struct xenfb_device fb, kbd;
-       size_t fb_len;          /* size of framebuffer */
-       char protocol[64];      /* frontend protocol */
-};
-
-static void xenfb_detach_dom(struct xenfb_private *);
-
-static char *xenfb_path_in_dom(struct xs_handle *xsh,
-                              char *buf, size_t size,
-                              unsigned domid, const char *fmt, ...)
-{
-       va_list ap;
-       char *domp = xs_get_domain_path(xsh, domid);
-       int n;
-
-        if (domp == NULL)
-               return NULL;
-
-       n = snprintf(buf, size, "%s/", domp);
-       free(domp);
-       if (n >= size)
-               return NULL;
-
-       va_start(ap, fmt);
-       n += vsnprintf(buf + n, size - n, fmt, ap);
-       va_end(ap);
-       if (n >= size)
-               return NULL;
-
-       return buf;
-}
-
-static int xenfb_xs_scanf1(struct xs_handle *xsh,
-                          const char *dir, const char *node,
-                          const char *fmt, void *dest)
-{
-       char buf[1024];
-       char *p;
-       int ret;
-
-       if (snprintf(buf, sizeof(buf), "%s/%s", dir, node) >= sizeof(buf)) {
-               errno = ENOENT;
-               return -1;
-        }
-       p = xs_read(xsh, XBT_NULL, buf, NULL);
-       if (!p) {
-               errno = ENOENT;
-               return -1;
-        }
-       ret = sscanf(p, fmt, dest);
-       free(p);
-       if (ret != 1) {
-               errno = EDOM;
-               return -1;
-        }
-       return ret;
-}
-
-static int xenfb_xs_printf(struct xs_handle *xsh,
-                          const char *dir, const char *node, char *fmt, ...)
-{
-       va_list ap;
-       char key[1024];
-       char val[1024];
-       int n;
-
-       if (snprintf(key, sizeof(key), "%s/%s", dir, node) >= sizeof(key)) {
-               errno = ENOENT;
-               return -1;
-        }
-
-       va_start(ap, fmt);
-       n = vsnprintf(val, sizeof(val), fmt, ap);
-       va_end(ap);
-       if (n >= sizeof(val)) {
-               errno = ENOSPC; /* close enough */
-               return -1;
-       }
-
-       if (!xs_write(xsh, XBT_NULL, key, val, n))
-               return -1;
-       return 0;
-}
-
-static void xenfb_device_init(struct xenfb_device *dev,
-                             const char *type,
-                             struct xenfb_private *xenfb)
-{
-       dev->devicetype = type;
-       dev->otherend_id = -1;
-       dev->port = -1;
-       dev->xenfb = xenfb;
-}
-
-int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
-{
-       struct xenfb_private *xenfb = dev->xenfb;
-
-       dev->otherend_id = domid;
-
-       if (!xenfb_path_in_dom(xenfb->xsh,
-                              dev->otherend, sizeof(dev->otherend),
-                              domid, "device/%s/0", dev->devicetype)) {
-               errno = ENOENT;
-               return -1;
-       }
-       if (!xenfb_path_in_dom(xenfb->xsh,
-                              dev->nodename, sizeof(dev->nodename),
-                              0, "backend/%s/%d/0", dev->devicetype, domid)) {
-               errno = ENOENT;
-               return -1;
-       }
-
-       return 0;
-}
-
-struct xenfb *xenfb_new(void)
-{
-       struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
-       int serrno;
-
-       if (xenfb == NULL)
-               return NULL;
-
-       memset(xenfb, 0, sizeof(*xenfb));
-       xenfb->evt_xch = xenfb->xc = -1;
-       xenfb_device_init(&xenfb->fb, "vfb", xenfb);
-       xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);
-
-       xenfb->evt_xch = xc_evtchn_open();
-       if (xenfb->evt_xch == -1)
-               goto fail;
-
-       xenfb->xc = xc_interface_open();
-       if (xenfb->xc == -1)
-               goto fail;
-
-       xenfb->xsh = xs_daemon_open();
-       if (!xenfb->xsh)
-               goto fail;
-
-       return &xenfb->pub;
-
- fail:
-       serrno = errno;
-       xenfb_delete(&xenfb->pub);
-       errno = serrno;
-       return NULL;
-}
-
-/* Remove the backend area in xenbus since the framebuffer really is
-   going away. */
-void xenfb_teardown(struct xenfb *xenfb_pub)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
-       xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
-       xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
-}
-
-
-void xenfb_delete(struct xenfb *xenfb_pub)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-
-       xenfb_detach_dom(xenfb);
-       if (xenfb->xc >= 0)
-               xc_interface_close(xenfb->xc);
-       if (xenfb->evt_xch >= 0)
-               xc_evtchn_close(xenfb->evt_xch);
-       if (xenfb->xsh)
-               xs_daemon_close(xenfb->xsh);
-       free(xenfb);
-}
-
-static enum xenbus_state xenfb_read_state(struct xs_handle *xsh,
-                                         const char *dir)
-{
-       int ret, state;
-
-       ret = xenfb_xs_scanf1(xsh, dir, "state", "%d", &state);
-       if (ret < 0)
-               return XenbusStateUnknown;
-
-       if ((unsigned)state > XenbusStateClosed)
-               state = XenbusStateUnknown;
-       return state;
-}
-
-static int xenfb_switch_state(struct xenfb_device *dev,
-                             enum xenbus_state state)
-{
-       struct xs_handle *xsh = dev->xenfb->xsh;
-
-       if (xenfb_xs_printf(xsh, dev->nodename, "state", "%d", state) < 0)
-               return -1;
-       dev->state = state;
-       return 0;
-}
-
-static int xenfb_wait_for_state(struct xs_handle *xsh, const char *dir,
-                               unsigned awaited)
-{
-       unsigned state, dummy;
-       char **vec;
-
-       awaited |= 1 << XenbusStateUnknown;
-
-       for (;;) {
-               state = xenfb_read_state(xsh, dir);
-               if ((1 << state) & awaited)
-                       return state;
-
-               vec = xs_read_watch(xsh, &dummy);
-               if (!vec)
-                       return -1;
-               free(vec);
-       }
-}
-
-static int xenfb_wait_for_backend_creation(struct xenfb_device *dev)
-{
-       struct xs_handle *xsh = dev->xenfb->xsh;
-       int state;
-
-       if (!xs_watch(xsh, dev->nodename, ""))
-               return -1;
-       state = xenfb_wait_for_state(xsh, dev->nodename,
-                       (1 << XenbusStateInitialising)
-                       | (1 << XenbusStateClosed)
-#if 1 /* TODO fudging state to permit restarting; to be removed */
-                       | (1 << XenbusStateInitWait)
-                       | (1 << XenbusStateConnected)
-                       | (1 << XenbusStateClosing)
-#endif
-                       );
-       xs_unwatch(xsh, dev->nodename, "");
-
-       switch (state) {
-#if 1
-       case XenbusStateInitWait:
-       case XenbusStateConnected:
-               printf("Fudging state to %d\n", XenbusStateInitialising); /* 
FIXME */
-#endif
-       case XenbusStateInitialising:
-       case XenbusStateClosing:
-       case XenbusStateClosed:
-               break;
-       default:
-               return -1;
-       }
-
-       return 0;
-}
-
-static int xenfb_hotplug(struct xenfb_device *dev)
-{
-       if (xenfb_xs_printf(dev->xenfb->xsh, dev->nodename,
-                           "hotplug-status", "connected"))
-               return -1;
-       return 0;
-}
-
-static int xenfb_wait_for_frontend_initialised(struct xenfb_device *dev)
-{
-       switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
-#if 1 /* TODO fudging state to permit restarting; to be removed */
-                       (1 << XenbusStateInitialised)
-                       | (1 << XenbusStateConnected)
-#else
-                       1 << XenbusStateInitialised,
-#endif
-                       )) {
-#if 1
-       case XenbusStateConnected:
-               printf("Fudging state to %d\n", XenbusStateInitialised); /* 
FIXME */
-#endif
-       case XenbusStateInitialised:
-               break;
-       default:
-               return -1;
-       }
-
-       return 0;
-}
-
-static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
-{
-       uint32_t *src32 = src;
-       uint64_t *src64 = src;
-       int i;
-
-       for (i = 0; i < count; i++)
-               dst[i] = (mode == 32) ? src32[i] : src64[i];
-}
-
-static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
-{
-       struct xenfb_page *page = xenfb->fb.page;
-       int n_fbmfns;
-       int n_fbdirs;
-       unsigned long *pgmfns = NULL;
-       unsigned long *fbmfns = NULL;
-       void *map, *pd;
-       int mode, ret = -1;
-
-       /* default to native */
-       pd = page->pd;
-       mode = sizeof(unsigned long) * 8;
-
-       if (0 == strlen(xenfb->protocol)) {
-               /*
-                * Undefined protocol, some guesswork needed.
-                *
-                * Old frontends which don't set the protocol use
-                * one page directory only, thus pd[1] must be zero.
-                * pd[1] of the 32bit struct layout and the lower
-                * 32 bits of pd[0] of the 64bit struct layout have
-                * the same location, so we can check that ...
-                */
-               uint32_t *ptr32 = NULL;
-               uint32_t *ptr64 = NULL;
-#if defined(__i386__)
-               ptr32 = (void*)page->pd;
-               ptr64 = ((void*)page->pd) + 4;
-#elif defined(__x86_64__)
-               ptr32 = ((void*)page->pd) - 4;
-               ptr64 = (void*)page->pd;
-#endif
-               if (ptr32) {
-                       if (0 == ptr32[1]) {
-                               mode = 32;
-                               pd   = ptr32;
-                       } else {
-                               mode = 64;
-                               pd   = ptr64;
-                       }
-               }
-#if defined(__x86_64__)
-       } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
-               /* 64bit dom0, 32bit domU */
-               mode = 32;
-               pd   = ((void*)page->pd) - 4;
-#elif defined(__i386__)
-       } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
-               /* 32bit dom0, 64bit domU */
-               mode = 64;
-               pd   = ((void*)page->pd) + 4;
-#endif
-       }
-
-       n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
-       n_fbdirs = n_fbmfns * mode / 8;
-       n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
-
-       pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
-       fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
-       if (!pgmfns || !fbmfns)
-               goto out;
-
-       xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
-       map = xc_map_foreign_pages(xenfb->xc, domid,
-                                  PROT_READ, pgmfns, n_fbdirs);
-       if (map == NULL)
-               goto out;
-       xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
-       munmap(map, n_fbdirs * XC_PAGE_SIZE);
-
-       xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
-                               PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
-       if (xenfb->pub.pixels == NULL)
-               goto out;
-
-       ret = 0; /* all is fine */
-
- out:
-       if (pgmfns)
-               free(pgmfns);
-       if (fbmfns)
-               free(fbmfns);
-       return ret;
-}
-
-static int xenfb_bind(struct xenfb_device *dev)
-{
-       struct xenfb_private *xenfb = dev->xenfb;
-       unsigned long mfn;
-       evtchn_port_t evtchn;
-
-       if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu",
-                           &mfn) < 0)
-               return -1;
-       if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u",
-                           &evtchn) < 0)
-               return -1;
-
-       dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch,
-                                              dev->otherend_id, evtchn);
-       if (dev->port == -1)
-               return -1;
-
-       dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id,
-                       XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
-       if (dev->page == NULL)
-               return -1;
-
-       return 0;
-}
-
-static void xenfb_unbind(struct xenfb_device *dev)
-{
-       if (dev->page) {
-               munmap(dev->page, XC_PAGE_SIZE);
-               dev->page = NULL;
-       }
-        if (dev->port >= 0) {
-               xc_evtchn_unbind(dev->xenfb->evt_xch, dev->port);
-               dev->port = -1;
-       }
-}
-
-static int xenfb_wait_for_frontend_connected(struct xenfb_device *dev)
-{
-       switch (xenfb_wait_for_state(dev->xenfb->xsh, dev->otherend,
-                                    1 << XenbusStateConnected)) {
-       case XenbusStateConnected:
-               break;
-       default:
-               return -1;
-       }
-
-       return 0;
-}
-
-static void xenfb_dev_fatal(struct xenfb_device *dev, int err,
-                           const char *fmt, ...)
-{
-       struct xs_handle *xsh = dev->xenfb->xsh;
-       va_list ap;
-       char errdir[80];
-       char buf[1024];
-       int n;
-
-       fprintf(stderr, "%s ", dev->nodename); /* somewhat crude */
-       va_start(ap, fmt);
-       vfprintf(stderr, fmt, ap);
-       va_end(ap);
-       if (err)
-               fprintf(stderr, " (%s)", strerror(err));
-       putc('\n', stderr);
-
-       if (!xenfb_path_in_dom(xsh, errdir, sizeof(errdir), 0,
-                              "error/%s", dev->nodename))
-               goto out;       /* FIXME complain */
-
-       va_start(ap, fmt);
-       n = snprintf(buf, sizeof(buf), "%d ", err);
-       snprintf(buf + n, sizeof(buf) - n, fmt, ap);
-       va_end(ap);
-
-       if (xenfb_xs_printf(xsh, buf, "error", "%s", buf) < 0)
-               goto out;       /* FIXME complain */
-
- out:
-       xenfb_switch_state(dev, XenbusStateClosing);
-}
-
-int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       struct xs_handle *xsh = xenfb->xsh;
-       int val, serrno;
-       struct xenfb_page *fb_page;
-
-       xenfb_detach_dom(xenfb);
-
-       xenfb_device_set_domain(&xenfb->fb, domid);
-       xenfb_device_set_domain(&xenfb->kbd, domid);
-
-       if (xenfb_wait_for_backend_creation(&xenfb->fb) < 0)
-               goto error;
-       if (xenfb_wait_for_backend_creation(&xenfb->kbd) < 0)
-               goto error;
-
-       if (xenfb_xs_printf(xsh, xenfb->kbd.nodename, "feature-abs-pointer", 
"1"))
-               goto error;
-       if (xenfb_switch_state(&xenfb->fb, XenbusStateInitWait))
-               goto error;
-       if (xenfb_switch_state(&xenfb->kbd, XenbusStateInitWait))
-               goto error;
-
-       if (xenfb_hotplug(&xenfb->fb) < 0)
-               goto error;
-       if (xenfb_hotplug(&xenfb->kbd) < 0)
-               goto error;
-
-       if (!xs_watch(xsh, xenfb->fb.otherend, ""))
-               goto error;
-       if (!xs_watch(xsh, xenfb->kbd.otherend, ""))
-               goto error;
-
-       if (xenfb_wait_for_frontend_initialised(&xenfb->fb) < 0)
-               goto error;
-       if (xenfb_wait_for_frontend_initialised(&xenfb->kbd) < 0)
-               goto error;
-
-       if (xenfb_bind(&xenfb->fb) < 0)
-               goto error;
-       if (xenfb_bind(&xenfb->kbd) < 0)
-               goto error;
-
-       if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "feature-update",
-                           "%d", &val) < 0)
-               val = 0;
-       if (!val) {
-               errno = ENOTSUP;
-               goto error;
-       }
-       if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
-                           xenfb->protocol) < 0)
-               xenfb->protocol[0] = '\0';
-       xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
-
-       /* TODO check for permitted ranges */
-       fb_page = xenfb->fb.page;
-       xenfb->pub.depth = fb_page->depth;
-       xenfb->pub.width = fb_page->width;
-       xenfb->pub.height = fb_page->height;
-       /* TODO check for consistency with the above */
-       xenfb->fb_len = fb_page->mem_length;
-       xenfb->pub.row_stride = fb_page->line_length;
-
-       if (xenfb_map_fb(xenfb, domid) < 0)
-               goto error;
-
-       if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
-               goto error;
-       if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected))
-               goto error;
-
-       if (xenfb_wait_for_frontend_connected(&xenfb->kbd) < 0)
-               goto error;
-       if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
-                           "%d", &val) < 0)
-               val = 0;
-       xenfb->pub.abs_pointer_wanted = val;
-
-       return 0;
-
- error:
-       serrno = errno;
-       xenfb_detach_dom(xenfb);
-       xenfb_dev_fatal(&xenfb->fb, serrno, "on fire");
-       xenfb_dev_fatal(&xenfb->kbd, serrno, "on fire");
-        errno = serrno;
-        return -1;
-}
-
-static void xenfb_detach_dom(struct xenfb_private *xenfb)
-{
-       xenfb_unbind(&xenfb->fb);
-       xenfb_unbind(&xenfb->kbd);
-       if (xenfb->pub.pixels) {
-               munmap(xenfb->pub.pixels, xenfb->fb_len);
-               xenfb->pub.pixels = NULL;
-       }
-}
-
-static void xenfb_on_fb_event(struct xenfb_private *xenfb)
-{
-       uint32_t prod, cons;
-       struct xenfb_page *page = xenfb->fb.page;
-
-       prod = page->out_prod;
-       if (prod == page->out_cons)
-               return;
-       rmb();                  /* ensure we see ring contents up to prod */
-       for (cons = page->out_cons; cons != prod; cons++) {
-               union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
-
-               switch (event->type) {
-               case XENFB_TYPE_UPDATE:
-                    if (xenfb->pub.update)
-                       xenfb->pub.update(&xenfb->pub,
-                                         event->update.x, event->update.y,
-                                         event->update.width, 
event->update.height);
-                    break;
-               }
-       }
-       mb();                   /* ensure we're done with ring contents */
-       page->out_cons = cons;
-       xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
-}
-
-static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
-{
-       struct xenkbd_page *page = xenfb->kbd.page;
-
-       /* We don't understand any keyboard events, so just ignore them. */
-       if (page->out_prod == page->out_cons)
-               return;
-       page->out_cons = page->out_prod;
-       xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-static int xenfb_on_state_change(struct xenfb_device *dev)
-{
-       enum xenbus_state state;
-
-       state = xenfb_read_state(dev->xenfb->xsh, dev->otherend);
-
-       switch (state) {
-       case XenbusStateUnknown:
-               /* There was an error reading the frontend state.  The
-                  domain has probably gone away; in any case, there's
-                  not much point in us continuing. */
-               return -1;
-       case XenbusStateInitialising:
-       case XenbusStateInitWait:
-       case XenbusStateInitialised:
-       case XenbusStateConnected:
-               break;
-       case XenbusStateClosing:
-               xenfb_unbind(dev);
-               xenfb_switch_state(dev, state);
-               break;
-       case XenbusStateClosed:
-               xenfb_switch_state(dev, state);
-       }
-       return 0;
-}
-
-/* Returns 0 normally, -1 on error, or -2 if the domain went away. */
-int xenfb_poll(struct xenfb *xenfb_pub, fd_set *readfds)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       evtchn_port_t port;
-       unsigned dummy;
-       char **vec;
-       int r;
-
-       if (FD_ISSET(xc_evtchn_fd(xenfb->evt_xch), readfds)) {
-               port = xc_evtchn_pending(xenfb->evt_xch);
-               if (port == -1)
-                       return -1;
-
-               if (port == xenfb->fb.port)
-                       xenfb_on_fb_event(xenfb);
-               else if (port == xenfb->kbd.port)
-                       xenfb_on_kbd_event(xenfb);
-
-               if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1)
-                       return -1;
-       }
-
-       if (FD_ISSET(xs_fileno(xenfb->xsh), readfds)) {
-               vec = xs_read_watch(xenfb->xsh, &dummy);
-               free(vec);
-               r = xenfb_on_state_change(&xenfb->fb);
-               if (r == 0)
-                       r = xenfb_on_state_change(&xenfb->kbd);
-               if (r == -1)
-                       return -2;
-       }
-
-       return 0;
-}
-
-int xenfb_select_fds(struct xenfb *xenfb_pub, fd_set *readfds)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       int fd1 = xc_evtchn_fd(xenfb->evt_xch);
-       int fd2 = xs_fileno(xenfb->xsh);
-
-       FD_SET(fd1, readfds);
-       FD_SET(fd2, readfds);
-       return fd1 > fd2 ? fd1 + 1 : fd2 + 1;
-}
-
-static int xenfb_kbd_event(struct xenfb_private *xenfb,
-                          union xenkbd_in_event *event)
-{
-       uint32_t prod;
-       struct xenkbd_page *page = xenfb->kbd.page;
-
-       if (xenfb->kbd.state != XenbusStateConnected)
-               return 0;
-
-       prod = page->in_prod;
-       if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
-               errno = EAGAIN;
-               return -1;
-       }
-
-       mb();                   /* ensure ring space available */
-       XENKBD_IN_RING_REF(page, prod) = *event;
-       wmb();                  /* ensure ring contents visible */
-       page->in_prod = prod + 1;
-       return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
-}
-
-int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       union xenkbd_in_event event;
-
-       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-       event.type = XENKBD_TYPE_KEY;
-       event.key.pressed = down ? 1 : 0;
-       event.key.keycode = keycode;
-
-       return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       union xenkbd_in_event event;
-
-       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-       event.type = XENKBD_TYPE_MOTION;
-       event.motion.rel_x = rel_x;
-       event.motion.rel_y = rel_y;
-
-       return xenfb_kbd_event(xenfb, &event);
-}
-
-int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
-{
-       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
-       union xenkbd_in_event event;
-
-       memset(&event, 0, XENKBD_IN_EVENT_SIZE);
-       event.type = XENKBD_TYPE_POS;
-       event.pos.abs_x = abs_x;
-       event.pos.abs_y = abs_y;
-
-       return xenfb_kbd_event(xenfb, &event);
-}
diff -r c17bfb091790 -r a07288a84785 tools/xenfb/xenfb.h
--- a/tools/xenfb/xenfb.h       Tue Oct 30 11:33:55 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#ifndef _XENFB_H_
-#define _XENFB_H_
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-struct xenfb
-{
-       void *pixels;
-
-       int row_stride;
-       int depth;
-       int width;
-       int height;
-       int abs_pointer_wanted;
-
-       void *user_data;
-
-       void (*update)(struct xenfb *xenfb, int x, int y, int width, int 
height);
-};
-
-struct xenfb *xenfb_new(void);
-void xenfb_delete(struct xenfb *xenfb);
-void xenfb_teardown(struct xenfb *xenfb);
-
-int xenfb_attach_dom(struct xenfb *xenfb, int domid);
-
-int xenfb_select_fds(struct xenfb *xenfb, fd_set *readfds);
-int xenfb_poll(struct xenfb *xenfb, fd_set *readfds);
-
-int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode);
-int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y);
-int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y);
-
-#endif
diff -r c17bfb091790 -r a07288a84785 tools/xenstore/xenstored_watch.c
--- a/tools/xenstore/xenstored_watch.c  Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/xenstore/xenstored_watch.c  Tue Oct 30 15:34:44 2007 -0600
@@ -59,7 +59,16 @@ static void add_event(struct connection 
        if (!check_event_node(name)) {
                /* Can this conn load node, or see that it doesn't exist? */
                struct node *node = get_node(conn, name, XS_PERM_READ);
-               if (!node && errno != ENOENT)
+               /*
+                * XXX We allow EACCES here because otherwise a non-dom0
+                * backend driver cannot watch for disappearance of a frontend
+                * xenstore directory. When the directory disappears, we
+                * revert to permissions of the parent directory for that path,
+                * which will typically disallow access for the backend.
+                * But this breaks device-channel teardown!
+                * Really we should fix this better...
+                */
+               if (!node && errno != ENOENT && errno != EACCES)
                        return;
        }
 
diff -r c17bfb091790 -r a07288a84785 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/xentrace/xentrace.c Tue Oct 30 15:34:44 2007 -0600
@@ -394,7 +394,7 @@ int monitor_tbufs(int outfd)
             }
 
             mb(); /* read buffer, then update cons. */
-            meta[i]->cons = meta[i]->prod;
+            meta[i]->cons = prod;
         }
 
         nanosleep(&opts.poll_sleep, NULL);
diff -r c17bfb091790 -r a07288a84785 tools/xm-test/lib/XmTestLib/XenAPIDomain.py
--- a/tools/xm-test/lib/XmTestLib/XenAPIDomain.py       Tue Oct 30 11:33:55 
2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py       Tue Oct 30 15:34:44 
2007 -0600
@@ -38,7 +38,8 @@ class XenAPIConfig:
                                         'memory_dynamic_max' ],
                            'kernel' : 'PV_kernel',
                            'ramdisk': 'PV_ramdisk',
-                           'root'   : 'PV_args'}
+                           'root'   : 'PV_args',
+                           'extra'  : 'PV_args' }
         if isACMEnabled():
             #A default so every VM can start with ACM enabled
             self.opts["security_label"] = "ACM:xm-test:red"
@@ -47,6 +48,8 @@ class XenAPIConfig:
         """Set an option in the config"""
         if name == "memory":
             value <<= 20
+        if name == "root":
+            value = "root=" + value
         if name in self.opttrlate.keys():
             _name = self.opttrlate[name]
         else:
@@ -56,7 +59,11 @@ class XenAPIConfig:
             for _n in _name:
                 self.opts[_n] = value
         else:
-            self.opts[_name] = value
+            if not self.opts.get(_name) or \
+               not _name in [ "PV_args" ]:
+                self.opts[_name] = value
+            else:
+                self.opts[_name] += " " + value
 
     def getOpt(self, name):
         """Return the value of a config option"""
diff -r c17bfb091790 -r a07288a84785 
tools/xm-test/tests/security-acm/08_security-acm_xapi.py
--- a/tools/xm-test/tests/security-acm/08_security-acm_xapi.py  Tue Oct 30 
11:33:55 2007 -0600
+++ b/tools/xm-test/tests/security-acm/08_security-acm_xapi.py  Tue Oct 30 
15:34:44 2007 -0600
@@ -18,6 +18,9 @@ vm_label_green  = xsconstants.ACM_POLICY
 vm_label_green  = xsconstants.ACM_POLICY_ID + ":xm-test:green"
 vdi_label_red   = xsconstants.ACM_POLICY_ID + ":xm-test:red"
 vdi_label_green = xsconstants.ACM_POLICY_ID + ":xm-test:green"
+
+vm_label_unlabeled = xsconstants.ACM_POLICY_ID + ":xm-test:" + \
+                     acmpolicy.ACM_LABEL_UNLABELED
 
 vdi_file = "/dev/ram0"
 vdi_path = "phy:" + vdi_file
@@ -105,7 +108,7 @@ if int(res) != 0:
     FAIL("Should be able to unlabel the domain while it's halted.")
 
 res = session.xenapi.VM.get_security_label(vm_uuid)
-if res != "":
+if res != vm_label_unlabeled:
     FAIL("Unexpected VM security label after removal: %s" % res)
 
 res = session.xenapi.VM.set_security_label(vm_uuid, vm_label_red, res)
diff -r c17bfb091790 -r a07288a84785 tools/xm-test/tests/vtpm/09_vtpm-xapi.py
--- a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py  Tue Oct 30 11:33:55 2007 -0600
+++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py  Tue Oct 30 15:34:44 2007 -0600
@@ -17,7 +17,7 @@ import commands
 import commands
 import os
 
-VTPM_RECORD_KEYS = [ 'backend', 'VM', 'uuid' ]
+VTPM_RECORD_KEYS = [ 'backend', 'VM', 'uuid', 'other_config' ]
 
 try:
     # XmTestAPIDomain tries to establish a connection to XenD
diff -r c17bfb091790 -r a07288a84785 unmodified_drivers/linux-2.6/README
--- a/unmodified_drivers/linux-2.6/README       Tue Oct 30 11:33:55 2007 -0600
+++ b/unmodified_drivers/linux-2.6/README       Tue Oct 30 15:34:44 2007 -0600
@@ -1,12 +1,12 @@ To build:
 To build:
 
 1. ./mkbuildtree
-   NB. You can override paths to Xen sources and XenLinux sources via
-       the XEN and XL environment variable.
+   NB. You can override paths to Xen sources and a (stub) XenLinux
+       build tree via the XEN and XL environment variable.
 
-2. make -C /path/to/kernel/source M=$PWD modules
-   NB. The kernel sources here are your native kernel build tree, not
-       the XenLinux sources referred to in step 1.
+2. make -C /path/to/kernel/build M=$PWD modules
+   NB. This is your native kernel build tree (or a distro provided
+       stub), not the XenLinux sources referred to in step 1.
 
 You get four modules, xen-platform-pci.ko, xenbus.ko, xen-vbd.ko, and
 xen-vnif.ko.  Load xen-platform-pci first, then xenbus, and then
diff -r c17bfb091790 -r a07288a84785 
unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h
--- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Tue Oct 
30 11:33:55 2007 -0600
+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Tue Oct 
30 15:34:44 2007 -0600
@@ -125,4 +125,12 @@ extern char *kasprintf(gfp_t gfp, const 
 #define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
 #endif
 
+#if defined(_LINUX_INTERRUPT_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+typedef irqreturn_t (*irq_handler_t)(int, void *, struct pt_regs *);
 #endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+#define setup_xen_features xen_setup_features
+#endif
+
+#endif
diff -r c17bfb091790 -r a07288a84785 unmodified_drivers/linux-2.6/overrides.mk
--- a/unmodified_drivers/linux-2.6/overrides.mk Tue Oct 30 11:33:55 2007 -0600
+++ b/unmodified_drivers/linux-2.6/overrides.mk Tue Oct 30 15:34:44 2007 -0600
@@ -11,4 +11,4 @@ ifeq ($(ARCH),ia64)
   EXTRA_CFLAGS += -DCONFIG_VMX_GUEST
 endif
 
-EXTRA_CFLAGS += -include $(srctree)/include/linux/autoconf.h
+EXTRA_CFLAGS += -include $(objtree)/include/linux/autoconf.h
diff -r c17bfb091790 -r a07288a84785 
unmodified_drivers/linux-2.6/platform-pci/evtchn.c
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c        Tue Oct 30 
11:33:55 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c        Tue Oct 30 
15:34:44 2007 -0600
@@ -28,7 +28,6 @@
  * IN THE SOFTWARE.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
@@ -48,7 +47,7 @@ void *shared_info_area;
 
 static struct {
        spinlock_t lock;
-       irqreturn_t(*handler) (int, void *, struct pt_regs *);
+       irq_handler_t handler;
        void *dev_id;
        int evtchn;
        int close:1; /* close on unbind_from_irqhandler()? */
@@ -146,7 +145,7 @@ EXPORT_SYMBOL(unmask_evtchn);
 
 int bind_listening_port_to_irqhandler(
        unsigned int remote_domain,
-       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       irq_handler_t handler,
        unsigned long irqflags,
        const char *devname,
        void *dev_id)
@@ -187,7 +186,7 @@ EXPORT_SYMBOL(bind_listening_port_to_irq
 
 int bind_caller_port_to_irqhandler(
        unsigned int caller_port,
-       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       irq_handler_t handler,
        unsigned long irqflags,
        const char *devname,
        void *dev_id)
@@ -254,13 +253,18 @@ void notify_remote_via_irq(int irq)
 }
 EXPORT_SYMBOL(notify_remote_via_irq);
 
-static irqreturn_t evtchn_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs)
+static irqreturn_t evtchn_interrupt(int irq, void *dev_id
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+                                   , struct pt_regs *regs
+#else
+# define handler(irq, dev_id, regs) handler(irq, dev_id)
+#endif
+                                   )
 {
        unsigned int l1i, port;
        /* XXX: All events are bound to vcpu0 but irq may be redirected. */
        int cpu = 0; /*smp_processor_id();*/
-       irqreturn_t(*handler) (int, void *, struct pt_regs *);
+       irq_handler_t handler;
        shared_info_t *s = shared_info_area;
        vcpu_info_t *v = &s->vcpu_info[cpu];
        unsigned long l1, l2;
@@ -331,6 +335,10 @@ int xen_irq_init(struct pci_dev *pdev)
                spin_lock_init(&irq_evtchn[irq].lock);
 
        return request_irq(pdev->irq, evtchn_interrupt,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
                           SA_SHIRQ | SA_SAMPLE_RANDOM | SA_INTERRUPT,
+#else
+                          IRQF_SHARED | IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
+#endif
                           "xen-platform-pci", pdev);
 }
diff -r c17bfb091790 -r a07288a84785 
unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c
--- a/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Tue Oct 
30 11:33:55 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Tue Oct 
30 15:34:44 2007 -0600
@@ -1,4 +1,3 @@
-#include <linux/config.h>
 #include <linux/cpumask.h>
 #include <linux/preempt.h>
 #include <xen/evtchn.h>
diff -r c17bfb091790 -r a07288a84785 
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Tue Oct 30 
11:33:55 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Tue Oct 30 
15:34:44 2007 -0600
@@ -367,7 +367,11 @@ static int __init platform_pci_module_in
 {
        int rc;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
        rc = pci_module_init(&platform_driver);
+#else
+       rc = pci_register_driver(&platform_driver);
+#endif
        if (rc) {
                printk(KERN_INFO DRV_NAME
                       ": No platform pci device model found\n");
diff -r c17bfb091790 -r a07288a84785 xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c  Tue Oct 30 11:33:55 2007 -0600
+++ b/xen/arch/ia64/vmx/mmio.c  Tue Oct 30 15:34:44 2007 -0600
@@ -55,53 +55,68 @@ static int hvm_buffered_io_intercept(ior
 static int hvm_buffered_io_intercept(ioreq_t *p)
 {
     struct vcpu *v = current;
-    spinlock_t  *buffered_io_lock;
-    buffered_iopage_t *buffered_iopage =
+    buffered_iopage_t *pg =
         (buffered_iopage_t *)(v->domain->arch.hvm_domain.buffered_io_va);
-    unsigned long tmp_write_pointer = 0;
+    buf_ioreq_t bp;
     int i;
 
+    /* Ensure buffered_iopage fits in a page */
+    BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE);
+
     /* ignore READ ioreq_t! */
-    if ( p->dir == IOREQ_READ )
-        return 0;
-
-    for ( i = 0; i < HVM_BUFFERED_IO_RANGE_NR; i++ ) {
-        if ( p->addr >= hvm_buffered_io_ranges[i]->start_addr &&
-             p->addr + p->size - 1 < hvm_buffered_io_ranges[i]->start_addr +
-                                     hvm_buffered_io_ranges[i]->length )
+    if (p->dir == IOREQ_READ)
+        return 0;
+
+    for (i = 0; i < HVM_BUFFERED_IO_RANGE_NR; i++) {
+        if (p->addr >= hvm_buffered_io_ranges[i]->start_addr &&
+            p->addr + p->size - 1 < hvm_buffered_io_ranges[i]->start_addr +
+                                    hvm_buffered_io_ranges[i]->length)
             break;
     }
 
-    if ( i == HVM_BUFFERED_IO_RANGE_NR )
-        return 0;
-
-    buffered_io_lock = &v->domain->arch.hvm_domain.buffered_io_lock;
-    spin_lock(buffered_io_lock);
-
-    if ( buffered_iopage->write_pointer - buffered_iopage->read_pointer ==
-         (unsigned long)IOREQ_BUFFER_SLOT_NUM ) {
+    if (i == HVM_BUFFERED_IO_RANGE_NR)
+        return 0;
+
+    bp.type = p->type;
+    bp.dir = p->dir;
+    switch (p->size) {
+    case 1:
+        bp.size = 0;
+        break;
+    case 2:
+        bp.size = 1;
+        break;
+    default:
+       /* Could use quad word semantics, but it only appears
+        * to be useful for timeoffset data. */
+        return 0;
+    }
+    bp.data = (uint16_t)p->data;
+    bp.addr = (uint32_t)p->addr;
+
+    spin_lock(&v->domain->arch.hvm_domain.buffered_io_lock);
+
+    if (pg->write_pointer - pg->read_pointer == IOREQ_BUFFER_SLOT_NUM) {
         /* the queue is full.
          * send the iopacket through the normal path.
          * NOTE: The arithimetic operation could handle the situation for
          * write_pointer overflow.
          */
-        spin_unlock(buffered_io_lock);
-        return 0;
-    }
-
-    tmp_write_pointer = buffered_iopage->write_pointer % IOREQ_BUFFER_SLOT_NUM;
-
-    memcpy(&buffered_iopage->ioreq[tmp_write_pointer], p, sizeof(ioreq_t));
-
-    /*make the ioreq_t visible before write_pointer*/
+        spin_unlock(&v->domain->arch.hvm_domain.buffered_io_lock);
+        return 0;
+    }
+
+    memcpy(&pg->buf_ioreq[pg->write_pointer % IOREQ_BUFFER_SLOT_NUM],
+           &bp, sizeof(bp));
+
+    /* Make the ioreq_t visible before write_pointer */
     wmb();
-    buffered_iopage->write_pointer++;
-
-    spin_unlock(buffered_io_lock);
+    pg->write_pointer++;
+
+    spin_unlock(&v->domain->arch.hvm_domain.buffered_io_lock);
 
     return 1;
 }
-
 
 static void low_mmio_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir)
 {
@@ -110,32 +125,36 @@ static void low_mmio_access(VCPU *vcpu, 

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


 


Rackspace

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