WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg (staging)
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 09 Nov 2007 04:20:22 -0800
Delivery-date: Fri, 09 Nov 2007 04:22:00 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

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