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-ppc-devel

[XenPPC] [xenppc-unstable] [POWERPC] merge with xen-unstable f7d65fb7299

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [xenppc-unstable] [POWERPC] merge with xen-unstable f7d65fb7299b
From: Xen patchbot-xenppc-unstable <patchbot-xenppc-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 11 Oct 2006 20:16:36 +0000
Delivery-date: Wed, 11 Oct 2006 13:33:37 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID b53c343b47ae930248f5db194b72d390e4143ccd
# Parent  e7cb3aefc233e24c6fa2803bc591b8442b833b6d
# Parent  f7d65fb7299b95b8b6d3a44134a9f2af211393c6
[POWERPC] merge with xen-unstable f7d65fb7299b
---
 tools/debugger/pdb/Domain.ml                               |   61 
 tools/debugger/pdb/Domain.mli                              |   39 
 tools/debugger/pdb/Intel.ml                                |   66 
 tools/debugger/pdb/Makefile                                |   57 
 tools/debugger/pdb/OCamlMakefile                           | 1149 -------------
 tools/debugger/pdb/PDB.ml                                  |  342 ---
 tools/debugger/pdb/Process.ml                              |   79 
 tools/debugger/pdb/Process.mli                             |   41 
 tools/debugger/pdb/Util.ml                                 |  165 -
 tools/debugger/pdb/Xen_domain.ml                           |   43 
 tools/debugger/pdb/Xen_domain.mli                          |   25 
 tools/debugger/pdb/debugger.ml                             |  372 ----
 tools/debugger/pdb/evtchn.ml                               |   40 
 tools/debugger/pdb/evtchn.mli                              |   19 
 tools/debugger/pdb/linux-2.6-module/Makefile               |   21 
 tools/debugger/pdb/linux-2.6-module/debug.c                |  851 ---------
 tools/debugger/pdb/linux-2.6-module/module.c               |  337 ---
 tools/debugger/pdb/linux-2.6-module/pdb_debug.h            |   47 
 tools/debugger/pdb/linux-2.6-module/pdb_module.h           |  142 -
 tools/debugger/pdb/linux-2.6-patches/Makefile              |   11 
 tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch      |   18 
 tools/debugger/pdb/linux-2.6-patches/kdebug.patch          |   10 
 tools/debugger/pdb/linux-2.6-patches/makefile.patch        |   10 
 tools/debugger/pdb/linux-2.6-patches/ptrace.patch          |   10 
 tools/debugger/pdb/linux-2.6-patches/traps.patch           |   19 
 tools/debugger/pdb/pdb_caml_domain.c                       |  527 -----
 tools/debugger/pdb/pdb_caml_evtchn.c                       |  186 --
 tools/debugger/pdb/pdb_caml_process.c                      |  587 ------
 tools/debugger/pdb/pdb_caml_xc.c                           |  170 -
 tools/debugger/pdb/pdb_caml_xcs.c                          |  307 ---
 tools/debugger/pdb/pdb_caml_xen.h                          |   39 
 tools/debugger/pdb/pdb_xen.c                               |   75 
 tools/debugger/pdb/readme                                  |   96 -
 tools/debugger/pdb/server.ml                               |  241 --
 tools/debugger/pdb/xcs.ml                                  |   85 
 tools/debugger/pdb/xcs.mli                                 |   13 
 tools/python/xen/xm/sysrq.py                               |   32 
 xen/arch/x86/hvm/svm/instrlen.c                            |  479 -----
 .hgignore                                                  |    3 
 buildconfigs/linux-defconfig_xen0_ia64                     |    1 
 buildconfigs/linux-defconfig_xenU_ia64                     |    1 
 buildconfigs/linux-defconfig_xen_ia64                      |    1 
 buildconfigs/linux-defconfig_xen_x86_32                    |    1 
 buildconfigs/linux-defconfig_xen_x86_64                    |    1 
 docs/man/xm.pod.1                                          |    4 
 docs/src/user.tex                                          |    2 
 extras/mini-os/arch/x86/setup.c                            |  108 +
 extras/mini-os/include/x86/os.h                            |    5 
 extras/mini-os/kernel.c                                    |   67 
 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c          |   21 
 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c            |    8 
 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c      |    1 
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c        |   24 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c         |  142 -
 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c         |   51 
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c       |   10 
 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c           |  394 +---
 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c           |    1 
 linux-2.6-xen-sparse/drivers/xen/core/skbuff.c             |    7 
 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c           |    3 
 linux-2.6-xen-sparse/drivers/xen/netback/interface.c       |   29 
 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c        |   64 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c         |   93 -
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c          |   22 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c       |  116 +
 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c         |  167 +
 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h          |    8 
 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c       |   19 
 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c         |   14 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c     |   14 
 linux-2.6-xen-sparse/include/xen/balloon.h                 |   20 
 linux-2.6-xen-sparse/include/xen/public/evtchn.h           |    3 
 linux-2.6-xen-sparse/mm/memory.c                           |    5 
 patches/linux-2.6.16.29/pci-mmconfig-fix-from-2.6.17.patch |  143 +
 patches/linux-2.6.16.29/series                             |    1 
 tools/blktap/drivers/Makefile                              |    5 
 tools/blktap/drivers/blktapctrl.c                          |   38 
 tools/blktap/drivers/tapdisk.c                             |    9 
 tools/blktap/lib/blktaplib.h                               |    7 
 tools/blktap/lib/xenbus.c                                  |  191 +-
 tools/blktap/lib/xs_api.c                                  |  103 -
 tools/blktap/lib/xs_api.h                                  |    2 
 tools/examples/block                                       |    1 
 tools/examples/init.d/xendomains                           |    8 
 tools/examples/locking.sh                                  |    2 
 tools/examples/xen-backend.rules                           |    1 
 tools/examples/xend-config.sxp                             |    5 
 tools/examples/xmexample.hvm                               |    5 
 tools/firmware/hvmloader/hvmloader.c                       |    6 
 tools/firmware/hvmloader/smbios.c                          |  148 -
 tools/firmware/vmxassist/machine.h                         |    1 
 tools/firmware/vmxassist/vm86.c                            |  100 -
 tools/ioemu/hw/serial.c                                    |   68 
 tools/ioemu/hw/vga.c                                       |   13 
 tools/ioemu/hw/xen_platform.c                              |    6 
 tools/ioemu/patches/domain-timeoffset                      |    8 
 tools/ioemu/patches/fix-vga-scanning-code-overflow         |   37 
 tools/ioemu/patches/qemu-bootorder                         |   18 
 tools/ioemu/patches/qemu-daemonize                         |    4 
 tools/ioemu/patches/qemu-pci                               |   23 
 tools/ioemu/patches/qemu-target-i386-dm                    |   18 
 tools/ioemu/patches/series                                 |    4 
 tools/ioemu/patches/vnc-access-monitor-vt                  |    4 
 tools/ioemu/patches/vnc-backoff-screen-scan                |  227 ++
 tools/ioemu/patches/vnc-cleanup                            |   42 
 tools/ioemu/patches/vnc-display-find-unused                |   14 
 tools/ioemu/patches/vnc-fixes                              |   57 
 tools/ioemu/patches/vnc-start-vncviewer                    |    9 
 tools/ioemu/patches/vnc-title-domain-name                  |    6 
 tools/ioemu/patches/xen-platform-device                    |   12 
 tools/ioemu/patches/xen-support-buffered-ioreqs            |    8 
 tools/ioemu/patches/xenstore-block-device-config           |   47 
 tools/ioemu/patches/xenstore-write-vnc-port                |   10 
 tools/ioemu/usb-linux.c                                    |    4 
 tools/ioemu/vl.c                                           |   43 
 tools/ioemu/vl.h                                           |    5 
 tools/ioemu/vnc.c                                          |  299 ++-
 tools/libxc/xc_linux.c                                     |   82 
 tools/libxc/xc_load_elf.c                                  |    2 
 tools/libxc/xc_ptrace.c                                    |   20 
 tools/libxc/xenctrl.h                                      |   10 
 tools/misc/mbootpack/Makefile                              |   17 
 tools/misc/mbootpack/buildimage.c                          |   19 
 tools/misc/mbootpack/mbootpack.c                           |   20 
 tools/misc/miniterm/miniterm.c                             |   25 
 tools/pygrub/Makefile                                      |    2 
 tools/pygrub/src/fsys/ext2/__init__.py                     |    2 
 tools/pygrub/src/fsys/reiser/__init__.py                   |    1 
 tools/pygrub/src/pygrub                                    |   20 
 tools/python/xen/util/blkif.py                             |    8 
 tools/python/xen/xend/XendBootloader.py                    |    3 
 tools/python/xen/xend/XendCheckpoint.py                    |    4 
 tools/python/xen/xend/XendDomain.py                        |   29 
 tools/python/xen/xend/XendDomainInfo.py                    |   36 
 tools/python/xen/xend/XendRoot.py                          |    6 
 tools/python/xen/xend/image.py                             |   12 
 tools/python/xen/xend/server/DevController.py              |    2 
 tools/python/xen/xend/server/SrvDomain.py                  |    2 
 tools/python/xen/xm/addlabel.py                            |  101 -
 tools/python/xen/xm/cfgbootpolicy.py                       |   96 -
 tools/python/xen/xm/console.py                             |    2 
 tools/python/xen/xm/create.py                              |   92 -
 tools/python/xen/xm/dry-run.py                             |   56 
 tools/python/xen/xm/dumppolicy.py                          |   31 
 tools/python/xen/xm/getlabel.py                            |   61 
 tools/python/xen/xm/labels.py                              |   77 
 tools/python/xen/xm/loadpolicy.py                          |   34 
 tools/python/xen/xm/main.py                                |  727 ++++----
 tools/python/xen/xm/makepolicy.py                          |   25 
 tools/python/xen/xm/migrate.py                             |   16 
 tools/python/xen/xm/opts.py                                |   92 -
 tools/python/xen/xm/resources.py                           |   44 
 tools/python/xen/xm/rmlabel.py                             |   62 
 tools/python/xen/xm/shutdown.py                            |    1 
 tools/vnet/doc/man/vn.pod.1                                |    4 
 tools/vnet/libxutil/Makefile                               |    2 
 tools/vnet/libxutil/hash_table.c                           |   13 
 tools/vnet/libxutil/hash_table.h                           |    1 
 tools/vnet/vnet-module/Makefile.ver                        |   27 
 tools/vnet/vnet-module/esp.c                               |   16 
 tools/vnet/vnet-module/etherip.c                           |   43 
 tools/vnet/vnet-module/tunnel.c                            |    7 
 tools/vnet/vnet-module/tunnel.h                            |    8 
 tools/vnet/vnet-module/varp.c                              |    9 
 tools/vnet/vnet-module/varp_socket.c                       |   76 
 tools/vnet/vnet-module/vif.c                               |    1 
 tools/vnet/vnet-module/vnet.c                              |   13 
 tools/vnet/vnet-module/vnet_dev.c                          |   12 
 tools/vnet/vnet-module/vnet_eval.c                         |    2 
 tools/vnet/vnet-module/vnet_forward.c                      |    1 
 tools/vnet/vnetd/Makefile                                  |    4 
 tools/vnet/vnetd/vnetd.c                                   |   34 
 tools/xm-test/tests/vtpm/vtpm_utils.py                     |    6 
 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c   |    6 
 xen/Makefile                                               |   22 
 xen/arch/ia64/Makefile                                     |   15 
 xen/arch/ia64/xen/domain.c                                 |    6 
 xen/arch/ia64/xen/xensetup.c                               |   10 
 xen/arch/powerpc/Makefile                                  |    3 
 xen/arch/powerpc/setup.c                                   |    3 
 xen/arch/x86/Makefile                                      |   24 
 xen/arch/x86/Rules.mk                                      |    2 
 xen/arch/x86/acpi/boot.c                                   |   81 
 xen/arch/x86/apic.c                                        |   95 -
 xen/arch/x86/boot/x86_32.S                                 |   26 
 xen/arch/x86/boot/x86_64.S                                 |   49 
 xen/arch/x86/domain.c                                      |   11 
 xen/arch/x86/hvm/Makefile                                  |    1 
 xen/arch/x86/hvm/hvm.c                                     |  158 +
 xen/arch/x86/hvm/i8259.c                                   |  122 -
 xen/arch/x86/hvm/instrlen.c                                |  450 +++++
 xen/arch/x86/hvm/intercept.c                               |   16 
 xen/arch/x86/hvm/io.c                                      |    7 
 xen/arch/x86/hvm/platform.c                                |  103 -
 xen/arch/x86/hvm/svm/Makefile                              |    1 
 xen/arch/x86/hvm/svm/emulate.c                             |    6 
 xen/arch/x86/hvm/svm/intr.c                                |   12 
 xen/arch/x86/hvm/svm/svm.c                                 |  241 +-
 xen/arch/x86/hvm/svm/x86_32/exits.S                        |    3 
 xen/arch/x86/hvm/svm/x86_64/exits.S                        |    1 
 xen/arch/x86/hvm/vioapic.c                                 |   22 
 xen/arch/x86/hvm/vlapic.c                                  |    4 
 xen/arch/x86/hvm/vmx/io.c                                  |   22 
 xen/arch/x86/hvm/vmx/vmcs.c                                |  135 +
 xen/arch/x86/hvm/vmx/vmx.c                                 |  471 ++---
 xen/arch/x86/hvm/vmx/x86_32/exits.S                        |    3 
 xen/arch/x86/hvm/vmx/x86_64/exits.S                        |    1 
 xen/arch/x86/io_apic.c                                     |    8 
 xen/arch/x86/irq.c                                         |   12 
 xen/arch/x86/microcode.c                                   |   11 
 xen/arch/x86/mm.c                                          |  245 +-
 xen/arch/x86/mm/shadow/common.c                            |  188 --
 xen/arch/x86/mm/shadow/multi.c                             |  451 +++--
 xen/arch/x86/mm/shadow/multi.h                             |    7 
 xen/arch/x86/mm/shadow/private.h                           |   49 
 xen/arch/x86/mm/shadow/types.h                             |   31 
 xen/arch/x86/mpparse.c                                     |   61 
 xen/arch/x86/platform_hypercall.c                          |   16 
 xen/arch/x86/setup.c                                       |   10 
 xen/arch/x86/smp.c                                         |    2 
 xen/arch/x86/smpboot.c                                     |    2 
 xen/arch/x86/traps.c                                       |    2 
 xen/arch/x86/x86_32/asm-offsets.c                          |    1 
 xen/arch/x86/x86_32/entry.S                                |   20 
 xen/arch/x86/x86_64/asm-offsets.c                          |    1 
 xen/arch/x86/x86_64/entry.S                                |    2 
 xen/arch/x86/x86_emulate.c                                 |   37 
 xen/common/domain.c                                        |    6 
 xen/common/domctl.c                                        |   43 
 xen/common/elf.c                                           |    2 
 xen/common/gdbstub.c                                       |   83 
 xen/common/grant_table.c                                   |    2 
 xen/common/sched_credit.c                                  |   43 
 xen/common/sched_sedf.c                                    |   15 
 xen/common/schedule.c                                      |   76 
 xen/common/shutdown.c                                      |    3 
 xen/common/symbols-dummy.c                                 |   16 
 xen/common/symbols.c                                       |   13 
 xen/drivers/acpi/tables.c                                  |  473 ++---
 xen/drivers/char/console.c                                 |   36 
 xen/include/asm-x86/apicdef.h                              |    1 
 xen/include/asm-x86/debugger.h                             |   44 
 xen/include/asm-x86/domain.h                               |    2 
 xen/include/asm-x86/guest_access.h                         |   20 
 xen/include/asm-x86/hvm/hvm.h                              |   25 
 xen/include/asm-x86/hvm/io.h                               |    1 
 xen/include/asm-x86/hvm/support.h                          |   22 
 xen/include/asm-x86/hvm/svm/emulate.h                      |   32 
 xen/include/asm-x86/hvm/vioapic.h                          |    2 
 xen/include/asm-x86/hvm/vmx/vmcs.h                         |   27 
 xen/include/asm-x86/hvm/vmx/vmx.h                          |  157 -
 xen/include/asm-x86/hvm/vpic.h                             |    8 
 xen/include/asm-x86/io_apic.h                              |    1 
 xen/include/asm-x86/mm.h                                   |   24 
 xen/include/asm-x86/multicall.h                            |    2 
 xen/include/asm-x86/shadow.h                               |  101 +
 xen/include/public/io/ring.h                               |    2 
 xen/include/xen/compiler.h                                 |    2 
 xen/include/xen/console.h                                  |    9 
 xen/include/xen/gdbstub.h                                  |    3 
 xen/include/xen/keyhandler.h                               |    3 
 xen/include/xen/sched-if.h                                 |    2 
 xen/include/xen/sched.h                                    |   19 
 263 files changed, 6064 insertions(+), 10665 deletions(-)

diff -r e7cb3aefc233 -r b53c343b47ae .hgignore
--- a/.hgignore Wed Oct 11 13:01:31 2006 -0400
+++ b/.hgignore Wed Oct 11 13:04:07 2006 -0400
@@ -139,12 +139,15 @@
 ^tools/security/secpol_tool$
 ^tools/security/xen/.*$
 ^tools/tests/test_x86_emulator$
+^tools/vnet/Make.local$
+^tools/vnet/build/.*$
 ^tools/vnet/gc$
 ^tools/vnet/gc.*/.*$
 ^tools/vnet/vnet-module/.*\.ko$
 ^tools/vnet/vnet-module/\..*\.cmd$
 ^tools/vnet/vnet-module/\.tmp_versions/.*$
 ^tools/vnet/vnet-module/vnet_module\.mod\..*$
+^tools/vnet/vnetd/vnetd$
 ^tools/vtpm/tpm_emulator-.*\.tar\.gz$
 ^tools/vtpm/tpm_emulator/.*$
 ^tools/vtpm/vtpm/.*$
diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Wed Oct 11 13:01:31 2006 -0400
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Wed Oct 11 13:04:07 2006 -0400
@@ -1040,6 +1040,7 @@ CONFIG_SND_ATIIXP=y
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
 CONFIG_SND_FM801=y
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
 CONFIG_SND_FM801_TEA575X=y
 # CONFIG_SND_HDA_INTEL is not set
 # CONFIG_SND_HDSP is not set
diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64    Wed Oct 11 13:01:31 2006 -0400
+++ b/buildconfigs/linux-defconfig_xenU_ia64    Wed Oct 11 13:04:07 2006 -0400
@@ -939,6 +939,7 @@ CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
 CONFIG_SND_FM801=y
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
 CONFIG_SND_FM801_TEA575X=y
 # CONFIG_SND_HDA_INTEL is not set
 # CONFIG_SND_HDSP is not set
diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Wed Oct 11 13:01:31 2006 -0400
+++ b/buildconfigs/linux-defconfig_xen_ia64     Wed Oct 11 13:04:07 2006 -0400
@@ -1046,6 +1046,7 @@ CONFIG_SND_ATIIXP=y
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
 CONFIG_SND_FM801=y
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
 CONFIG_SND_FM801_TEA575X=y
 # CONFIG_SND_HDA_INTEL is not set
 # CONFIG_SND_HDSP is not set
diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Wed Oct 11 13:01:31 2006 -0400
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Wed Oct 11 13:04:07 2006 -0400
@@ -2377,6 +2377,7 @@ CONFIG_SND_ES1938=m
 CONFIG_SND_ES1938=m
 CONFIG_SND_ES1968=m
 CONFIG_SND_FM801=m
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
 CONFIG_SND_FM801_TEA575X=m
 CONFIG_SND_HDA_INTEL=m
 CONFIG_SND_HDSP=m
diff -r e7cb3aefc233 -r b53c343b47ae buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Wed Oct 11 13:01:31 2006 -0400
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Wed Oct 11 13:04:07 2006 -0400
@@ -2237,6 +2237,7 @@ CONFIG_SND_ES1938=m
 CONFIG_SND_ES1938=m
 CONFIG_SND_ES1968=m
 CONFIG_SND_FM801=m
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
 CONFIG_SND_FM801_TEA575X=m
 CONFIG_SND_HDA_INTEL=m
 CONFIG_SND_HDSP=m
diff -r e7cb3aefc233 -r b53c343b47ae docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Wed Oct 11 13:01:31 2006 -0400
+++ b/docs/man/xm.pod.1 Wed Oct 11 13:04:07 2006 -0400
@@ -393,7 +393,9 @@ specified, VCPU information for all doma
 
 =item B<vcpu-pin> I<domain-id> I<vcpu> I<cpus>
 
-Pins the the VCPU to only run on the specific CPUs.  
+Pins the the VCPU to only run on the specific CPUs.  The keyword
+I<all> can be used to apply the I<cpus> list to all VCPUs in the
+domain.
 
 Normally VCPUs can float between available CPUs whenever Xen deems a
 different run state is appropriate.  Pinning can be used to restrict
diff -r e7cb3aefc233 -r b53c343b47ae docs/src/user.tex
--- a/docs/src/user.tex Wed Oct 11 13:01:31 2006 -0400
+++ b/docs/src/user.tex Wed Oct 11 13:04:07 2006 -0400
@@ -3208,6 +3208,8 @@ editing \path{grub.conf}.
   respectively; if no suffix is specified, the parameter defaults to
   kilobytes. In previous versions of Xen, suffixes were not supported
   and the value is always interpreted as kilobytes.
+\item [ dom0\_vcpus\_pin ] Pins domain 0 VCPUs on their respective
+  physical CPUS (default=false).
 \item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
   pages (default 0).  
 \item [ sched=xxx ] Select the CPU scheduler Xen should use.  The
diff -r e7cb3aefc233 -r b53c343b47ae extras/mini-os/include/x86/os.h
--- a/extras/mini-os/include/x86/os.h   Wed Oct 11 13:01:31 2006 -0400
+++ b/extras/mini-os/include/x86/os.h   Wed Oct 11 13:04:07 2006 -0400
@@ -60,6 +60,11 @@ extern shared_info_t *HYPERVISOR_shared_
 extern shared_info_t *HYPERVISOR_shared_info;
 
 void trap_init(void);
+
+void arch_init(start_info_t *si);
+void arch_print_info(void);
+
+
 
 
 
diff -r e7cb3aefc233 -r b53c343b47ae extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Wed Oct 11 13:01:31 2006 -0400
+++ b/extras/mini-os/kernel.c   Wed Oct 11 13:04:07 2006 -0400
@@ -38,49 +38,6 @@
 #include <gnttab.h>
 #include <xen/features.h>
 #include <xen/version.h>
-
-/*
- * Shared page for communicating with the hypervisor.
- * Events flags go here, for example.
- */
-shared_info_t *HYPERVISOR_shared_info;
-
-/*
- * This structure contains start-of-day info, such as pagetable base pointer,
- * address of the shared_info structure, and things like that.
- */
-union start_info_union start_info_union;
-
-/*
- * Just allocate the kernel stack here. SS:ESP is set up to point here
- * in head.S.
- */
-char stack[8192];
-
-
-/* Assembler interface fns in entry.S. */
-void hypervisor_callback(void);
-void failsafe_callback(void);
-
-extern char shared_info[PAGE_SIZE];
-
-#if !defined(CONFIG_X86_PAE)
-#define __pte(x) ((pte_t) { (x) } )
-#else
-#define __pte(x) ({ unsigned long long _x = (x);        \
-    ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
-#endif
-
-static shared_info_t *map_shared_info(unsigned long pa)
-{
-    if ( HYPERVISOR_update_va_mapping(
-        (unsigned long)shared_info, __pte(pa | 7), UVMF_INVLPG) )
-    {
-        printk("Failed to map shared_info!!\n");
-        do_exit();
-    }
-    return (shared_info_t *)shared_info;
-}
 
 
 u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
@@ -126,27 +83,8 @@ void start_kernel(start_info_t *si)
 
     (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
 
-    /* Copy the start_info struct to a globally-accessible area. */
-    /* WARN: don't do printk before here, it uses information from
-       shared_info. Use xprintk instead. */
-    memcpy(&start_info, si, sizeof(*si));
-    
-    /* set up minimal memory infos */
-    phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
+    arch_init(si);
 
-    /* Grab the shared_info pointer and put it in a safe place. */
-    HYPERVISOR_shared_info = map_shared_info(start_info.shared_info);
-
-    /* Set up event and failsafe callback addresses. */
-#ifdef __i386__
-    HYPERVISOR_set_callbacks(
-        __KERNEL_CS, (unsigned long)hypervisor_callback,
-        __KERNEL_CS, (unsigned long)failsafe_callback);
-#else
-    HYPERVISOR_set_callbacks(
-        (unsigned long)hypervisor_callback,
-        (unsigned long)failsafe_callback, 0);
-#endif
     trap_init();
 
     /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
@@ -163,7 +101,8 @@ void start_kernel(start_info_t *si)
     printk("  flags:      0x%x\n",  (unsigned int)si->flags);
     printk("  cmd_line:   %s\n",  
            si->cmd_line ? (const char *)si->cmd_line : "NULL");
-    printk("  stack:      %p-%p\n", stack, stack + 8192);
+
+    arch_print_info();
 
     setup_xen_features();
 
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Wed Oct 11 13:04:07 
2006 -0400
@@ -156,6 +156,9 @@ EXPORT_SYMBOL(ist_info);
 EXPORT_SYMBOL(ist_info);
 #endif
 struct e820map e820;
+#ifdef CONFIG_XEN
+struct e820map machine_e820;
+#endif
 
 extern void early_cpu_init(void);
 extern void generic_apic_probe(char *);
@@ -1451,7 +1454,6 @@ static void __init register_memory(void)
 static void __init register_memory(void)
 {
 #ifdef CONFIG_XEN
-       struct e820entry *machine_e820;
        struct xen_memory_map memmap;
 #endif
        int           i;
@@ -1461,14 +1463,14 @@ static void __init register_memory(void)
                return;
 
 #ifdef CONFIG_XEN
-       machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
-
        memmap.nr_entries = E820MAX;
-       set_xen_guest_handle(memmap.buffer, machine_e820);
-
-       BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
-
-       legacy_init_iomem_resources(machine_e820, memmap.nr_entries,
+       set_xen_guest_handle(memmap.buffer, machine_e820.map);
+
+       if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
+               BUG();
+       machine_e820.nr_map = memmap.nr_entries;
+
+       legacy_init_iomem_resources(machine_e820.map, machine_e820.nr_map,
                                    &code_resource, &data_resource);
 #else
        if (efi_enabled)
@@ -1486,8 +1488,7 @@ static void __init register_memory(void)
                request_resource(&ioport_resource, &standard_io_resources[i]);
 
 #ifdef CONFIG_XEN
-       e820_setup_gap(machine_e820, memmap.nr_entries);
-       free_bootmem(__pa(machine_e820), PAGE_SIZE);
+       e820_setup_gap(machine_e820.map, machine_e820.nr_map);
 #else
        e820_setup_gap(e820.map, e820.nr_map);
 #endif
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Wed Oct 11 13:04:07 
2006 -0400
@@ -28,6 +28,8 @@ static int direct_remap_area_pte_fn(pte_
                                    void *data)
 {
        mmu_update_t **v = (mmu_update_t **)data;
+
+       BUG_ON(!pte_none(*pte));
 
        (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
                     PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
@@ -110,11 +112,13 @@ int direct_remap_pfn_range(struct vm_are
                           pgprot_t prot,
                           domid_t  domid)
 {
-       /* Same as remap_pfn_range(). */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return remap_pfn_range(vma, address, mfn, size, prot);
 
        if (domid == DOMID_SELF)
                return -EINVAL;
+
+       vma->vm_flags |= VM_IO | VM_RESERVED;
 
        vma->vm_mm->context.has_foreign_mappings = 1;
 
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Wed Oct 11 
13:04:07 2006 -0400
@@ -350,7 +350,6 @@ static inline void set_32bit_tls(struct 
        struct user_desc ud = { 
                .base_addr = addr,
                .limit = 0xfffff,
-               .contents = (3 << 3), /* user */
                .seg_32bit = 1,
                .limit_in_pages = 1,
                .useable = 1,
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Wed Oct 11 
13:04:07 2006 -0400
@@ -144,6 +144,9 @@ struct sys_desc_table_struct {
 
 struct edid_info edid_info;
 struct e820map e820;
+#ifdef CONFIG_XEN
+struct e820map machine_e820;
+#endif
 
 extern int root_mountflags;
 
@@ -626,7 +629,6 @@ void __init setup_arch(char **cmdline_p)
 void __init setup_arch(char **cmdline_p)
 {
        unsigned long kernel_end;
-       struct e820entry *machine_e820;
        struct xen_memory_map memmap;
 
 #ifdef CONFIG_XEN
@@ -919,14 +921,14 @@ void __init setup_arch(char **cmdline_p)
        probe_roms();
 #ifdef CONFIG_XEN
        if (is_initial_xendomain()) {
-               machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
-
                memmap.nr_entries = E820MAX;
-               set_xen_guest_handle(memmap.buffer, machine_e820);
-
-               BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, 
&memmap));
-
-               e820_reserve_resources(machine_e820, memmap.nr_entries);
+               set_xen_guest_handle(memmap.buffer, machine_e820.map);
+
+               if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
+                       BUG();
+               machine_e820.nr_map = memmap.nr_entries;
+
+               e820_reserve_resources(machine_e820.map, machine_e820.nr_map);
        }
 #else
        e820_reserve_resources(e820.map, e820.nr_map);
@@ -942,10 +944,8 @@ void __init setup_arch(char **cmdline_p)
        }
 
 #ifdef CONFIG_XEN
-       if (is_initial_xendomain()) {
-               e820_setup_gap(machine_e820, memmap.nr_entries);
-               free_bootmem(__pa(machine_e820), PAGE_SIZE);
-       }
+       if (is_initial_xendomain())
+               e820_setup_gap(machine_e820.map, machine_e820.nr_map);
 #else
        e820_setup_gap(e820.map, e820.nr_map);
 #endif
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Wed Oct 11 
13:04:07 2006 -0400
@@ -534,74 +534,86 @@ static int dealloc_pte_fn(
        return 0;
 }
 
-struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
-{
-       unsigned long vstart, flags;
-       unsigned int  order = get_order(nr_pages * PAGE_SIZE);
-       int ret;
-       unsigned long i;
-       struct page *page;
-
-       vstart = __get_free_pages(GFP_KERNEL, order);
-       if (vstart == 0)
+struct page **alloc_empty_pages_and_pagevec(int nr_pages)
+{
+       unsigned long vaddr, flags;
+       struct page *page, **pagevec;
+       int i, ret;
+
+       pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL);
+       if (pagevec == NULL)
                return NULL;
 
-       scrub_pages(vstart, 1 << order);
-
+       for (i = 0; i < nr_pages; i++) {
+               page = pagevec[i] = alloc_page(GFP_KERNEL);
+               if (page == NULL)
+                       goto err;
+
+               vaddr = (unsigned long)page_address(page);
+
+               scrub_pages(vaddr, 1);
+
+               balloon_lock(flags);
+
+               if (xen_feature(XENFEAT_auto_translated_physmap)) {
+                       unsigned long gmfn = page_to_pfn(page);
+                       struct xen_memory_reservation reservation = {
+                               .nr_extents   = 1,
+                               .extent_order = 0,
+                               .domid        = DOMID_SELF
+                       };
+                       set_xen_guest_handle(reservation.extent_start, &gmfn);
+                       ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                                  &reservation);
+                       if (ret == 1)
+                               ret = 0; /* success */
+               } else {
+                       ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
+                                                 dealloc_pte_fn, NULL);
+               }
+
+               if (ret != 0) {
+                       balloon_unlock(flags);
+                       __free_page(page);
+                       goto err;
+               }
+
+               totalram_pages = --current_pages;
+
+               balloon_unlock(flags);
+       }
+
+ out:
+       schedule_work(&balloon_worker);
+       flush_tlb_all();
+       return pagevec;
+
+ err:
        balloon_lock(flags);
-       if (xen_feature(XENFEAT_auto_translated_physmap)) {
-               unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT;
-               struct xen_memory_reservation reservation = {
-                       .nr_extents   = 1,
-                       .extent_order = order,
-                       .domid        = DOMID_SELF
-               };
-               set_xen_guest_handle(reservation.extent_start, &gmfn);
-               ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-                                          &reservation);
-               if (ret == -ENOSYS)
-                       goto err;
-               BUG_ON(ret != 1);
-       } else {
-               ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
-                                         dealloc_pte_fn, NULL);
-               if (ret == -ENOSYS)
-                       goto err;
-               BUG_ON(ret);
-       }
-       current_pages -= 1UL << order;
-       totalram_pages = current_pages;
+       while (--i >= 0)
+               balloon_append(pagevec[i]);
        balloon_unlock(flags);
-
-       schedule_work(&balloon_worker);
-
-       flush_tlb_all();
-
-       page = virt_to_page(vstart);
-
-       for (i = 0; i < (1UL << order); i++)
-               set_page_count(page + i, 1);
-
-       return page;
-
- err:
-       free_pages(vstart, order);
+       kfree(pagevec);
+       pagevec = NULL;
+       goto out;
+}
+
+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
+{
+       unsigned long flags;
+       int i;
+
+       if (pagevec == NULL)
+               return;
+
+       balloon_lock(flags);
+       for (i = 0; i < nr_pages; i++) {
+               BUG_ON(page_count(pagevec[i]) != 1);
+               balloon_append(pagevec[i]);
+       }
        balloon_unlock(flags);
-       return NULL;
-}
-
-void balloon_dealloc_empty_page_range(
-       struct page *page, unsigned long nr_pages)
-{
-       unsigned long i, flags;
-       unsigned int  order = get_order(nr_pages * PAGE_SIZE);
-
-       balloon_lock(flags);
-       for (i = 0; i < (1UL << order); i++) {
-               BUG_ON(page_count(page + i) != 1);
-               balloon_append(page + i);
-       }
-       balloon_unlock(flags);
+
+       kfree(pagevec);
 
        schedule_work(&balloon_worker);
 }
@@ -619,8 +631,8 @@ void balloon_release_driver_page(struct 
 }
 
 EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
-EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
-EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
+EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec);
+EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec);
 EXPORT_SYMBOL_GPL(balloon_release_driver_page);
 
 MODULE_LICENSE("Dual BSD/GPL");
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Wed Oct 11 
13:04:07 2006 -0400
@@ -55,8 +55,6 @@ static int blkif_reqs = 64;
 static int blkif_reqs = 64;
 module_param_named(reqs, blkif_reqs, int, 0);
 MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
-
-static int mmap_pages;
 
 /* Run-time switchable: /sys/module/blkback/parameters/ */
 static unsigned int log_stats = 0;
@@ -87,8 +85,7 @@ static DECLARE_WAIT_QUEUE_HEAD(pending_f
 
 #define BLKBACK_INVALID_HANDLE (~0)
 
-static unsigned long mmap_vstart;
-static unsigned long *pending_vaddrs;
+static struct page **pending_pages;
 static grant_handle_t *pending_grant_handles;
 
 static inline int vaddr_pagenr(pending_req_t *req, int seg)
@@ -98,7 +95,8 @@ static inline int vaddr_pagenr(pending_r
 
 static inline unsigned long vaddr(pending_req_t *req, int seg)
 {
-       return pending_vaddrs[vaddr_pagenr(req, seg)];
+       unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]);
+       return (unsigned long)pfn_to_kaddr(pfn);
 }
 
 #define pending_handle(_req, _seg) \
@@ -506,52 +504,43 @@ static void make_response(blkif_t *blkif
 
 static int __init blkif_init(void)
 {
-       struct page *page;
-       int i;
+       int i, mmap_pages;
 
        if (!is_running_on_xen())
                return -ENODEV;
 
-       mmap_pages            = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
-
-       page = balloon_alloc_empty_page_range(mmap_pages);
-       if (page == NULL)
-               return -ENOMEM;
-       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+       mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
        pending_reqs          = kmalloc(sizeof(pending_reqs[0]) *
                                        blkif_reqs, GFP_KERNEL);
        pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
                                        mmap_pages, GFP_KERNEL);
-       pending_vaddrs        = kmalloc(sizeof(pending_vaddrs[0]) *
-                                       mmap_pages, GFP_KERNEL);
-       if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) {
-               kfree(pending_reqs);
-               kfree(pending_grant_handles);
-               kfree(pending_vaddrs);
-               printk("%s: out of memory\n", __FUNCTION__);
-               return -ENOMEM;
-       }
+       pending_pages         = alloc_empty_pages_and_pagevec(mmap_pages);
+
+       if (!pending_reqs || !pending_grant_handles || !pending_pages)
+               goto out_of_memory;
+
+       for (i = 0; i < mmap_pages; i++)
+               pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
 
        blkif_interface_init();
-       
-       printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
-              __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
-       BUG_ON(mmap_vstart == 0);
-       for (i = 0; i < mmap_pages; i++) {
-               pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT);
-               pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
-       }
 
        memset(pending_reqs, 0, sizeof(pending_reqs));
        INIT_LIST_HEAD(&pending_free);
 
        for (i = 0; i < blkif_reqs; i++)
                list_add_tail(&pending_reqs[i].free_list, &pending_free);
-    
+
        blkif_xenbus_init();
 
        return 0;
+
+ out_of_memory:
+       kfree(pending_reqs);
+       kfree(pending_grant_handles);
+       free_empty_pages_and_pagevec(pending_pages, mmap_pages);
+       printk("%s: out of memory\n", __FUNCTION__);
+       return -ENOMEM;
 }
 
 module_init(blkif_init);
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Wed Oct 11 
13:04:07 2006 -0400
@@ -273,7 +273,7 @@ static void backend_changed(struct xenbu
                        xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
 
                down(&bd->bd_sem);
-               if (info->users > 0 && system_state == SYSTEM_RUNNING)
+               if (info->users > 0)
                        xenbus_dev_error(dev, -EBUSY,
                                         "Device in use; refusing to close");
                else
@@ -355,8 +355,10 @@ static void blkfront_closing(struct xenb
        blk_stop_queue(info->rq);
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
+       spin_unlock_irqrestore(&blkif_io_lock, flags);
+
+       /* Flush gnttab callback work. Must be done with no locks held. */
        flush_scheduled_work();
-       spin_unlock_irqrestore(&blkif_io_lock, flags);
 
        xlvbd_del(info);
 
@@ -714,8 +716,10 @@ static void blkif_free(struct blkfront_i
                blk_stop_queue(info->rq);
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
+       spin_unlock_irq(&blkif_io_lock);
+
+       /* Flush gnttab callback work. Must be done with no locks held. */
        flush_scheduled_work();
-       spin_unlock_irq(&blkif_io_lock);
 
        /* Free resources associated with old device channel. */
        if (info->ring_ref != GRANT_INVALID_REF) {
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Wed Oct 11 13:04:07 
2006 -0400
@@ -44,7 +44,6 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/miscdevice.h>
 #include <linux/errno.h>
 #include <linux/major.h>
 #include <linux/gfp.h>
@@ -54,6 +53,30 @@
 
 #define MAX_TAP_DEV 100     /*the maximum number of tapdisk ring devices    */
 #define MAX_DEV_NAME 100    /*the max tapdisk ring device name e.g. blktap0 */
+
+
+struct class *xen_class;
+EXPORT_SYMBOL_GPL(xen_class);
+
+/*
+ * Setup the xen class.  This should probably go in another file, but
+ * since blktap is the only user of it so far, it gets to keep it.
+ */
+int setup_xen_class(void)
+{
+       int ret;
+
+       if (xen_class)
+               return 0;
+
+       xen_class = class_create(THIS_MODULE, "xen");
+       if ((ret = IS_ERR(xen_class))) {
+               xen_class = NULL;
+               return ret;
+       }
+
+       return 0;
+}
 
 /*
  * The maximum number of requests that can be outstanding at any time
@@ -100,19 +123,14 @@ typedef struct tap_blkif {
        unsigned long *idx_map;       /*Record the user ring id to kern 
                                        [req id, idx] tuple                  */
        blkif_t *blkif;               /*Associate blkif with tapdev          */
+       int sysfs_set;                /*Set if it has a class device.        */
 } tap_blkif_t;
-
-/*Private data struct associated with the inode*/
-typedef struct private_info {
-       int idx;
-} private_info_t;
 
 /*Data struct handed back to userspace for tapdisk device to VBD mapping*/
 typedef struct domid_translate {
        unsigned short domid;
        unsigned short busid;
 } domid_translate_t ;
-
 
 static domid_translate_t  translate_domid[MAX_TAP_DEV];
 static tap_blkif_t *tapfds[MAX_TAP_DEV];
@@ -168,16 +186,18 @@ static inline unsigned int RTN_PEND_IDX(
 
 #define BLKBACK_INVALID_HANDLE (~0)
 
-typedef struct mmap_page {
-       unsigned long start;
-       struct page *mpage;
-} mmap_page_t;
-
-static mmap_page_t mmap_start[MAX_DYNAMIC_MEM];
+static struct page **foreign_pages[MAX_DYNAMIC_MEM];
+static inline unsigned long idx_to_kaddr(
+       unsigned int mmap_idx, unsigned int req_idx, unsigned int sg_idx)
+{
+       unsigned int arr_idx = req_idx*BLKIF_MAX_SEGMENTS_PER_REQUEST + sg_idx;
+       unsigned long pfn = page_to_pfn(foreign_pages[mmap_idx][arr_idx]);
+       return (unsigned long)pfn_to_kaddr(pfn);
+}
+
 static unsigned short mmap_alloc = 0;
 static unsigned short mmap_lock = 0;
 static unsigned short mmap_inuse = 0;
-static unsigned long *pending_addrs[MAX_DYNAMIC_MEM];
 
 /******************************************************************
  * GRANT HANDLES
@@ -200,14 +220,12 @@ static struct grant_handle_pair
     + (_i)])
 
 
-static int blktap_read_ufe_ring(int idx); /*local prototypes*/
-
-#define BLKTAP_MINOR 0  /*/dev/xen/blktap resides at device number
-                         major=254, minor numbers begin at 0            */ 
-#define BLKTAP_DEV_MAJOR 254         /* TODO: Make major number dynamic  *
-                                      * and create devices in the kernel *
-                                     */
+static int blktap_read_ufe_ring(tap_blkif_t *info); /*local prototypes*/
+
+#define BLKTAP_MINOR 0  /*/dev/xen/blktap has a dynamic major */
 #define BLKTAP_DEV_DIR  "/dev/xen"
+
+static int blktap_major;
 
 /* blktap IOCTLs: */
 #define BLKTAP_IOCTL_KICK_FE         1
@@ -264,7 +282,8 @@ static inline int GET_NEXT_REQ(unsigned 
 {
        int i;
        for (i = 0; i < MAX_PENDING_REQS; i++)
-               if (idx_map[i] == INVALID_REQ) return i;
+               if (idx_map[i] == INVALID_REQ)
+                       return i;
 
        return INVALID_REQ;
 }
@@ -311,8 +330,6 @@ static int blktap_ioctl(struct inode *in
                         unsigned int cmd, unsigned long arg);
 static unsigned int blktap_poll(struct file *file, poll_table *wait);
 
-struct miscdevice *set_misc(int minor, char *name, int dev);
-
 static struct file_operations blktap_fops = {
        .owner   = THIS_MODULE,
        .poll    = blktap_poll,
@@ -344,6 +361,16 @@ static int get_next_free_dev(void)
        
 done:
        spin_unlock_irqrestore(&pending_free_lock, flags);
+
+       /*
+        * We are protected by having the dev_pending set.
+        */
+       if (!tapfds[i]->sysfs_set && xen_class) {
+               class_device_create(xen_class, NULL,
+                                   MKDEV(blktap_major, ret), NULL,
+                                   "blktap%d", ret);
+               tapfds[i]->sysfs_set = 1;
+       }
        return ret;
 }
 
@@ -369,9 +396,8 @@ void signal_tapdisk(int idx)
        info = tapfds[idx];
        if ( (idx > 0) && (idx < MAX_TAP_DEV) && (info->pid > 0) ) {
                ptask = find_task_by_pid(info->pid);
-               if (ptask) { 
+               if (ptask)
                        info->status = CLEANSHUTDOWN;
-               }
        }
        info->blkif = NULL;
        return;
@@ -382,7 +408,6 @@ static int blktap_open(struct inode *ino
        blkif_sring_t *sring;
        int idx = iminor(inode) - BLKTAP_MINOR;
        tap_blkif_t *info;
-       private_info_t *prv;
        int i;
        
        if (tapfds[idx] == NULL) {
@@ -410,9 +435,7 @@ static int blktap_open(struct inode *ino
        SHARED_RING_INIT(sring);
        FRONT_RING_INIT(&info->ufe_ring, sring, PAGE_SIZE);
        
-       prv = kzalloc(sizeof(private_info_t),GFP_KERNEL);
-       prv->idx = idx;
-       filp->private_data = prv;
+       filp->private_data = info;
        info->vma = NULL;
 
        info->idx_map = kmalloc(sizeof(unsigned long) * MAX_PENDING_REQS, 
@@ -433,17 +456,16 @@ static int blktap_open(struct inode *ino
 
 static int blktap_release(struct inode *inode, struct file *filp)
 {
-       int idx = iminor(inode) - BLKTAP_MINOR;
-       tap_blkif_t *info;
-       
-       if (tapfds[idx] == NULL) {
+       tap_blkif_t *info = filp->private_data;
+       
+       /* can this ever happen? - sdr */
+       if (!info) {
                WPRINTK("Trying to free device that doesn't exist "
-                      "[/dev/xen/blktap%d]\n",idx);
-               return -1;
-       }
-       info = tapfds[idx];
+                      "[/dev/xen/blktap%d]\n",iminor(inode) - BLKTAP_MINOR);
+               return -EBADF;
+       }
        info->dev_inuse = 0;
-       DPRINTK("Freeing device [/dev/xen/blktap%d]\n",idx);
+       DPRINTK("Freeing device [/dev/xen/blktap%d]\n",info->minor);
 
        /* Free the ring page. */
        ClearPageReserved(virt_to_page(info->ufe_ring.sring));
@@ -457,8 +479,6 @@ static int blktap_release(struct inode *
                info->vma = NULL;
        }
        
-       if (filp->private_data) kfree(filp->private_data);
-
        if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) {
                kthread_stop(info->blkif->xenblkd);
                info->blkif->xenblkd = NULL;
@@ -491,16 +511,12 @@ static int blktap_mmap(struct file *filp
        int size;
        struct page **map;
        int i;
-       private_info_t *prv;
-       tap_blkif_t *info;
-
-       /*Retrieve the dev info*/
-       prv = (private_info_t *)filp->private_data;
-       if (prv == NULL) {
+       tap_blkif_t *info = filp->private_data;
+
+       if (info == NULL) {
                WPRINTK("blktap: mmap, retrieving idx failed\n");
                return -ENOMEM;
        }
-       info = tapfds[prv->idx];
        
        vma->vm_flags |= VM_RESERVED;
        vma->vm_ops = &blktap_vm_ops;
@@ -556,20 +572,17 @@ static int blktap_ioctl(struct inode *in
 static int blktap_ioctl(struct inode *inode, struct file *filp,
                         unsigned int cmd, unsigned long arg)
 {
-       int idx = iminor(inode) - BLKTAP_MINOR;
+       tap_blkif_t *info = filp->private_data;
+
        switch(cmd) {
        case BLKTAP_IOCTL_KICK_FE: 
        {
                /* There are fe messages to process. */
-               return blktap_read_ufe_ring(idx);
+               return blktap_read_ufe_ring(info);
        }
        case BLKTAP_IOCTL_SETMODE:
        {
-               tap_blkif_t *info = tapfds[idx];
-               
-               if ( (idx > 0) && (idx < MAX_TAP_DEV) 
-                    && (tapfds[idx] != NULL) ) 
-               {
+               if (info) {
                        if (BLKTAP_MODE_VALID(arg)) {
                                info->mode = arg;
                                /* XXX: may need to flush rings here. */
@@ -582,11 +595,7 @@ static int blktap_ioctl(struct inode *in
        }
        case BLKTAP_IOCTL_PRINT_IDXS:
         {
-               tap_blkif_t *info = tapfds[idx];
-               
-               if ( (idx > 0) && (idx < MAX_TAP_DEV) 
-                    && (tapfds[idx] != NULL) ) 
-               {
+               if (info) {
                        printk("User Rings: \n-----------\n");
                        printk("UF: rsp_cons: %2d, req_prod_prv: %2d "
                                "| req_prod: %2d, rsp_prod: %2d\n",
@@ -599,11 +608,7 @@ static int blktap_ioctl(struct inode *in
         }
        case BLKTAP_IOCTL_SENDPID:
        {
-               tap_blkif_t *info = tapfds[idx];
-               
-               if ( (idx > 0) && (idx < MAX_TAP_DEV) 
-                    && (tapfds[idx] != NULL) ) 
-               {
+               if (info) {
                        info->pid = (pid_t)arg;
                        DPRINTK("blktap: pid received %d\n", 
                               info->pid);
@@ -631,26 +636,38 @@ static int blktap_ioctl(struct inode *in
        case BLKTAP_IOCTL_FREEINTF:
        {
                unsigned long dev = arg;
-               tap_blkif_t *info = NULL;
-
-               if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev];
-
+               unsigned long flags;
+
+               /* Looking at another device */
+               info = NULL;
+
+               if ( (dev > 0) && (dev < MAX_TAP_DEV) )
+                       info = tapfds[dev];
+
+               spin_lock_irqsave(&pending_free_lock, flags);
                if ( (info != NULL) && (info->dev_pending) )
                        info->dev_pending = 0;
+               spin_unlock_irqrestore(&pending_free_lock, flags);
+
                return 0;
        }
        case BLKTAP_IOCTL_MINOR:
        {
                unsigned long dev = arg;
-               tap_blkif_t *info = NULL;
+
+               /* Looking at another device */
+               info = NULL;
                
-               if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev];
+               if ( (dev > 0) && (dev < MAX_TAP_DEV) )
+                       info = tapfds[dev];
                
-               if (info != NULL) return info->minor;
-               else return -1;
+               if (info != NULL)
+                       return info->minor;
+               else
+                       return -1;
        }
        case BLKTAP_IOCTL_MAJOR:
-               return BLKTAP_DEV_MAJOR;
+               return blktap_major;
 
        case BLKTAP_QUERY_ALLOC_REQS:
        {
@@ -662,25 +679,21 @@ static int blktap_ioctl(struct inode *in
        return -ENOIOCTLCMD;
 }
 
-static unsigned int blktap_poll(struct file *file, poll_table *wait)
-{
-       private_info_t *prv;
-       tap_blkif_t *info;
-       
-       /*Retrieve the dev info*/
-       prv = (private_info_t *)file->private_data;
-       if (prv == NULL) {
+static unsigned int blktap_poll(struct file *filp, poll_table *wait)
+{
+       tap_blkif_t *info = filp->private_data;
+       
+       if (!info) {
                WPRINTK(" poll, retrieving idx failed\n");
                return 0;
        }
-       
-       if (prv->idx == 0) return 0;
-       
-       info = tapfds[prv->idx];
-       
-       poll_wait(file, &info->wait, wait);
+
+       /* do not work on the control device */
+       if (!info->minor)
+               return 0;
+
+       poll_wait(filp, &info->wait, wait);
        if (info->ufe_ring.req_prod_pvt != info->ufe_ring.sring->req_prod) {
-               flush_tlb_all();
                RING_PUSH_REQUESTS(&info->ufe_ring);
                return POLLIN | POLLRDNORM;
        }
@@ -691,11 +704,14 @@ void blktap_kick_user(int idx)
 {
        tap_blkif_t *info;
 
-       if (idx == 0) return;
+       if (idx == 0)
+               return;
        
        info = tapfds[idx];
        
-       if (info != NULL) wake_up_interruptible(&info->wait);
+       if (info != NULL)
+               wake_up_interruptible(&info->wait);
+
        return;
 }
 
@@ -712,66 +728,21 @@ static int req_increase(void)
 static int req_increase(void)
 {
        int i, j;
-       struct page *page;
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&pending_free_lock, flags);
-
-       ret = -EINVAL;
+
        if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
-               goto done;
-
-#ifdef __ia64__
-       extern unsigned long alloc_empty_foreign_map_page_range(
-               unsigned long pages);
-       mmap_start[mmap_alloc].start = (unsigned long)
-               alloc_empty_foreign_map_page_range(mmap_pages);
-#else /* ! ia64 */
-       page = balloon_alloc_empty_page_range(mmap_pages);
-       ret = -ENOMEM;
-       if (page == NULL) {
-               printk("%s balloon_alloc_empty_page_range gave NULL\n", 
__FUNCTION__);
-               goto done;
-       }
-
-       /* Pin all of the pages. */
-       for (i=0; i<mmap_pages; i++)
-               get_page(&page[i]);
-
-       mmap_start[mmap_alloc].start = 
-               (unsigned long)pfn_to_kaddr(page_to_pfn(page));
-       mmap_start[mmap_alloc].mpage = page;
-
-#endif
-
-       pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t) *
-                                       blkif_reqs, GFP_KERNEL);
-       pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
-                                       mmap_pages, GFP_KERNEL);
-
-       ret = -ENOMEM;
-       if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
-               kfree(pending_reqs[mmap_alloc]);
-               kfree(pending_addrs[mmap_alloc]);
-               WPRINTK("%s: out of memory\n", __FUNCTION__);
-               ret = -ENOMEM;
-               goto done;
-       }
-
-       ret = 0;
-
-       DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
-               __FUNCTION__, blkif_reqs, mmap_pages, 
-              mmap_start[mmap_alloc].start);
-
-       BUG_ON(mmap_start[mmap_alloc].start == 0);
-
-       for (i = 0; i < mmap_pages; i++) 
-               pending_addrs[mmap_alloc][i] = 
-                       mmap_start[mmap_alloc].start + (i << PAGE_SHIFT);
-
-       for (i = 0; i < MAX_PENDING_REQS ; i++) {
+               return -EINVAL;
+
+       pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t)
+                                           * blkif_reqs, GFP_KERNEL);
+       foreign_pages[mmap_alloc] = alloc_empty_pages_and_pagevec(mmap_pages);
+
+       if (!pending_reqs[mmap_alloc] || !foreign_pages[mmap_alloc])
+               goto out_of_memory;
+
+       DPRINTK("%s: reqs=%d, pages=%d\n",
+               __FUNCTION__, blkif_reqs, mmap_pages);
+
+       for (i = 0; i < MAX_PENDING_REQS; i++) {
                list_add_tail(&pending_reqs[mmap_alloc][i].free_list, 
                              &pending_free);
                pending_reqs[mmap_alloc][i].mem_idx = mmap_alloc;
@@ -782,65 +753,28 @@ static int req_increase(void)
 
        mmap_alloc++;
        DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
- done:
-       spin_unlock_irqrestore(&pending_free_lock, flags);
-       return ret;
+       return 0;
+
+ out_of_memory:
+       free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
+       kfree(pending_reqs[mmap_alloc]);
+       WPRINTK("%s: out of memory\n", __FUNCTION__);
+       return -ENOMEM;
 }
 
 static void mmap_req_del(int mmap)
 {
-       int i;
-       struct page *page;
-
-       /*Spinlock already acquired*/
+       BUG_ON(!spin_is_locked(&pending_free_lock));
+
        kfree(pending_reqs[mmap]);
-       kfree(pending_addrs[mmap]);
-
-#ifdef __ia64__
-       /*Not sure what goes here yet!*/
-#else
-
-       /* Unpin all of the pages. */
-       page = mmap_start[mmap].mpage;
-       for (i=0; i<mmap_pages; i++)
-               put_page(&page[i]);
-
-       balloon_dealloc_empty_page_range(mmap_start[mmap].mpage, mmap_pages);
-#endif
+       pending_reqs[mmap] = NULL;
+
+       free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
+       foreign_pages[mmap] = NULL;
 
        mmap_lock = 0;
        DPRINTK("# MMAPs decreased to %d\n",mmap_alloc);
        mmap_alloc--;
-}
-
-/*N.B. Currently unused - will be accessed via sysfs*/
-static void req_decrease(void)
-{
-       pending_req_t *req;
-       int i;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pending_free_lock, flags);
-
-       DPRINTK("Req decrease called.\n");
-       if (mmap_lock || mmap_alloc == 1) 
-               goto done;
-
-       mmap_lock = 1;
-       mmap_inuse = MAX_PENDING_REQS;
-       
-        /*Go through reqs and remove any that aren't in use*/
-       for (i = 0; i < MAX_PENDING_REQS ; i++) {
-               req = &pending_reqs[mmap_alloc-1][i];
-               if (req->inuse == 0) {
-                       list_del(&req->free_list);
-                       mmap_inuse--;
-               }
-       }
-       if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1);
- done:
-       spin_unlock_irqrestore(&pending_free_lock, flags);
-       return;
 }
 
 static pending_req_t* alloc_req(void)
@@ -907,7 +841,7 @@ static void fast_flush_area(pending_req_
        mmap_idx = req->mem_idx;
 
        for (i = 0; i < req->nr_pages; i++) {
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i);
+               kvaddr = idx_to_kaddr(mmap_idx, k_idx, i);
                uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i);
 
                khandle = &pending_handle(mmap_idx, k_idx, i);
@@ -916,7 +850,7 @@ static void fast_flush_area(pending_req_
                        continue;
                }
                gnttab_set_unmap_op(&unmap[invcount], 
-                       MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i), 
+                                   idx_to_kaddr(mmap_idx, k_idx, i), 
                                    GNTMAP_host_map, khandle->kernel);
                invcount++;
 
@@ -1002,7 +936,7 @@ int tap_blkif_schedule(void *arg)
  * COMPLETION CALLBACK -- Called by user level ioctl()
  */
 
-static int blktap_read_ufe_ring(int idx)
+static int blktap_read_ufe_ring(tap_blkif_t *info)
 {
        /* This is called to read responses from the UFE ring. */
        RING_IDX i, j, rp;
@@ -1010,12 +944,9 @@ static int blktap_read_ufe_ring(int idx)
        blkif_t *blkif=NULL;
        int pending_idx, usr_idx, mmap_idx;
        pending_req_t *pending_req;
-       tap_blkif_t *info;
-       
-       info = tapfds[idx];
-       if (info == NULL) {
+       
+       if (!info)
                return 0;
-       }
 
        /* We currently only forward packets in INTERCEPT_FE mode. */
        if (!(info->mode & BLKTAP_MODE_INTERCEPT_FE))
@@ -1053,9 +984,8 @@ static int blktap_read_ufe_ring(int idx)
                        struct page *pg;
                        int offset;
 
-                       uvaddr  = MMAP_VADDR(info->user_vstart, usr_idx, j);
-                       kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                           pending_idx, j);
+                       uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, j);
+                       kvaddr = idx_to_kaddr(mmap_idx, pending_idx, j);
 
                        pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                        ClearPageReserved(pg);
@@ -1063,7 +993,7 @@ static int blktap_read_ufe_ring(int idx)
                                >> PAGE_SHIFT;
                        map[offset] = NULL;
                }
-               fast_flush_area(pending_req, pending_idx, usr_idx, idx);
+               fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
                make_response(blkif, pending_req->id, resp->operation,
                              resp->status);
                info->idx_map[usr_idx] = INVALID_REQ;
@@ -1237,8 +1167,7 @@ static void dispatch_rw_block_io(blkif_t
                uint32_t flags;
 
                uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                   pending_idx, i);
+               kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
                page = virt_to_page(kvaddr);
 
                sector = req->sector_number + (8*i);
@@ -1290,8 +1219,7 @@ static void dispatch_rw_block_io(blkif_t
                struct page *pg;
 
                uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                   pending_idx, i/2);
+               kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
 
                if (unlikely(map[i].status != 0)) {
                        WPRINTK("invalid kernel buffer -- "
@@ -1321,8 +1249,7 @@ static void dispatch_rw_block_io(blkif_t
                unsigned long kvaddr;
                struct page *pg;
 
-               kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
-                                   pending_idx, i);
+               kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
                pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                SetPageReserved(pg);
        }
@@ -1416,7 +1343,8 @@ static int __init blkif_init(void)
        /*Create the blktap devices, but do not map memory or waitqueue*/
        for(i = 0; i < MAX_TAP_DEV; i++) translate_domid[i].domid = 0xFFFF;
 
-       ret = register_chrdev(BLKTAP_DEV_MAJOR,"blktap",&blktap_fops);
+       /* Dynamically allocate a major for this device */
+       ret = register_chrdev(0, "blktap", &blktap_fops);
        blktap_dir = devfs_mk_dir(NULL, "xen", 0, NULL);
 
        if ( (ret < 0)||(blktap_dir < 0) ) {
@@ -1424,22 +1352,44 @@ static int __init blkif_init(void)
                return -ENOMEM;
        }       
        
+       blktap_major = ret;
+
        for(i = 0; i < MAX_TAP_DEV; i++ ) {
                info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL);
-               if(tapfds[i] == NULL) return -ENOMEM;
+               if(tapfds[i] == NULL)
+                       return -ENOMEM;
                info->minor = i;
                info->pid = 0;
                info->blkif = NULL;
 
-               ret = devfs_mk_cdev(MKDEV(BLKTAP_DEV_MAJOR, i),
+               ret = devfs_mk_cdev(MKDEV(blktap_major, i),
                        S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i);
 
-               if(ret != 0) return -ENOMEM;
+               if(ret != 0)
+                       return -ENOMEM;
                info->dev_pending = info->dev_inuse = 0;
 
                DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i);
        }
        
+       /* Make sure the xen class exists */
+       if (!setup_xen_class()) {
+               /*
+                * This will allow udev to create the blktap ctrl device.
+                * We only want to create blktap0 first.  We don't want
+                * to flood the sysfs system with needless blktap devices.
+                * We only create the device when a request of a new device is
+                * made.
+                */
+               class_device_create(xen_class, NULL,
+                                   MKDEV(blktap_major, 0), NULL,
+                                   "blktap0");
+               tapfds[0]->sysfs_set = 1;
+       } else {
+               /* this is bad, but not fatal */
+               WPRINTK("blktap: sysfs xen_class not created\n");
+       }
+
        DPRINTK("Blktap device successfully created\n");
 
        return 0;
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Wed Oct 11 13:04:07 
2006 -0400
@@ -273,7 +273,6 @@ static void tap_frontend_changed(struct 
                        kthread_stop(be->blkif->xenblkd);
                        be->blkif->xenblkd = NULL;
                }
-               tap_blkif_unmap(be->blkif);
                xenbus_switch_state(dev, XenbusStateClosing);
                break;
 
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/core/skbuff.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c    Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/core/skbuff.c    Wed Oct 11 13:04:07 
2006 -0400
@@ -18,7 +18,12 @@
 /*static*/ kmem_cache_t *skbuff_cachep;
 EXPORT_SYMBOL(skbuff_cachep);
 
-#define MAX_SKBUFF_ORDER 4
+/* Allow up to 64kB or page-sized packets (whichever is greater). */
+#if PAGE_SHIFT < 16
+#define MAX_SKBUFF_ORDER (16 - PAGE_SHIFT)
+#else
+#define MAX_SKBUFF_ORDER 0
+#endif
 static kmem_cache_t *skbuff_order_cachep[MAX_SKBUFF_ORDER + 1];
 
 static struct {
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Wed Oct 11 13:04:07 
2006 -0400
@@ -419,10 +419,9 @@ static struct file_operations evtchn_fop
 };
 
 static struct miscdevice evtchn_miscdev = {
-       .minor        = EVTCHN_MINOR,
+       .minor        = MISC_DYNAMIC_MINOR,
        .name         = "evtchn",
        .fops         = &evtchn_fops,
-       .devfs_name   = "misc/evtchn",
 };
 
 static int __init evtchn_init(void)
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Wed Oct 11 
13:04:07 2006 -0400
@@ -34,6 +34,24 @@
 #include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 
+/*
+ * Module parameter 'queue_length':
+ * 
+ * Enables queuing in the network stack when a client has run out of receive
+ * descriptors. Although this feature can improve receive bandwidth by avoiding
+ * packet loss, it can also result in packets sitting in the 'tx_queue' for
+ * unbounded time. This is bad if those packets hold onto foreign resources.
+ * For example, consider a packet that holds onto resources belonging to the
+ * guest for which it is queued (e.g., packet received on vif1.0, destined for
+ * vif1.1 which is not activated in the guest): in this situation the guest
+ * will never be destroyed, unless vif1.1 is taken down (which flushes the
+ * 'tx_queue').
+ * 
+ * Only set this parameter to non-zero value if you know what you are doing!
+ */
+static unsigned long netbk_queue_length = 0;
+module_param_named(queue_length, netbk_queue_length, ulong, 0);
+
 static void __netif_up(netif_t *netif)
 {
        enable_irq(netif->irq);
@@ -44,6 +62,7 @@ static void __netif_down(netif_t *netif)
 {
        disable_irq(netif->irq);
        netif_deschedule_work(netif);
+       del_timer_sync(&netif->credit_timeout);
 }
 
 static int net_open(struct net_device *dev)
@@ -134,6 +153,7 @@ netif_t *netif_alloc(domid_t domid, unsi
        netif->credit_bytes = netif->remaining_credit = ~0UL;
        netif->credit_usec  = 0UL;
        init_timer(&netif->credit_timeout);
+       netif->credit_timeout.expires = jiffies;
 
        dev->hard_start_xmit = netif_be_start_xmit;
        dev->get_stats       = netif_be_get_stats;
@@ -144,11 +164,10 @@ netif_t *netif_alloc(domid_t domid, unsi
 
        SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
 
-       /*
-        * Reduce default TX queuelen so that each guest interface only
-        * allows it to eat around 6.4MB of host memory.
-        */
-       dev->tx_queue_len = 100;
+       dev->tx_queue_len = netbk_queue_length;
+       if (dev->tx_queue_len != 0)
+               printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero "
+                      "queue length (%lu)!\n", dev->name, dev->tx_queue_len);
 
        for (i = 0; i < ETH_ALEN; i++)
                if (be_mac[i] != 0)
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Wed Oct 11 
13:04:07 2006 -0400
@@ -53,8 +53,10 @@
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 #include <net/dst.h>
-
-static int nloopbacks = 8;
+#include <net/xfrm.h>          /* secpath_reset() */
+#include <asm/hypervisor.h>    /* is_initial_xendomain() */
+
+static int nloopbacks = -1;
 module_param(nloopbacks, int, 0);
 MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create");
 
@@ -77,9 +79,59 @@ static int loopback_close(struct net_dev
        return 0;
 }
 
+#ifdef CONFIG_X86
+static int is_foreign(unsigned long pfn)
+{
+       /* NB. Play it safe for auto-translation mode. */
+       return (xen_feature(XENFEAT_auto_translated_physmap) ||
+               (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT));
+}
+#else
+/* How to detect a foreign mapping? Play it safe. */
+#define is_foreign(pfn)        (1)
+#endif
+
+static int skb_remove_foreign_references(struct sk_buff *skb)
+{
+       struct page *page;
+       unsigned long pfn;
+       int i, off;
+       char *vaddr;
+
+       BUG_ON(skb_shinfo(skb)->frag_list);
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page);
+               if (!is_foreign(pfn))
+                       continue;
+               
+               page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
+               if (unlikely(!page))
+                       return 0;
+
+               vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
+               off = skb_shinfo(skb)->frags[i].page_offset;
+               memcpy(page_address(page) + off,
+                      vaddr + off,
+                      skb_shinfo(skb)->frags[i].size);
+               kunmap_skb_frag(vaddr);
+
+               put_page(skb_shinfo(skb)->frags[i].page);
+               skb_shinfo(skb)->frags[i].page = page;
+       }
+
+       return 1;
+}
+
 static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_private *np = netdev_priv(dev);
+
+       if (!skb_remove_foreign_references(skb)) {
+               np->stats.tx_dropped++;
+               dev_kfree_skb(skb);
+               return 0;
+       }
 
        dst_release(skb->dst);
        skb->dst = NULL;
@@ -110,6 +162,11 @@ static int loopback_start_xmit(struct sk
        skb->protocol = eth_type_trans(skb, dev);
        skb->dev      = dev;
        dev->last_rx  = jiffies;
+
+       /* Flush netfilter context: rx'ed skbuffs not expected to have any. */
+       nf_reset(skb);
+       secpath_reset(skb);
+
        netif_rx(skb);
 
        return 0;
@@ -239,6 +296,9 @@ static int __init loopback_init(void)
 {
        int i, err = 0;
 
+       if (nloopbacks == -1)
+               nloopbacks = is_initial_xendomain() ? 4 : 0;
+
        for (i = 0; i < nloopbacks; i++)
                if ((err = make_loopback(i)) != 0)
                        break;
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Oct 11 
13:04:07 2006 -0400
@@ -70,10 +70,11 @@ static struct timer_list net_timer;
 
 static struct sk_buff_head rx_queue;
 
-static unsigned long mmap_vstart;
-#define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
-
-static void *rx_mmap_area;
+static struct page **mmap_pages;
+static inline unsigned long idx_to_kaddr(unsigned int idx)
+{
+       return (unsigned long)pfn_to_kaddr(page_to_pfn(mmap_pages[idx]));
+}
 
 #define PKT_PROT_LEN 64
 
@@ -217,7 +218,7 @@ static struct sk_buff *netbk_copy_skb(st
                copy = len >= PAGE_SIZE ? PAGE_SIZE : len;
                zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO;
 
-               page = alloc_page(GFP_ATOMIC | zero);
+               page = alloc_page(GFP_ATOMIC | __GFP_NOWARN | zero);
                if (unlikely(!page))
                        goto err_free;
 
@@ -792,10 +793,27 @@ void netif_deschedule_work(netif_t *neti
 }
 
 
+static void tx_add_credit(netif_t *netif)
+{
+       unsigned long max_burst;
+
+       /*
+        * Allow a burst big enough to transmit a jumbo packet of up to 128kB.
+        * Otherwise the interface can seize up due to insufficient credit.
+        */
+       max_burst = RING_GET_REQUEST(&netif->tx, netif->tx.req_cons)->size;
+       max_burst = min(max_burst, 131072UL);
+       max_burst = max(max_burst, netif->credit_bytes);
+
+       netif->remaining_credit = min(netif->remaining_credit +
+                                     netif->credit_bytes,
+                                     max_burst);
+}
+
 static void tx_credit_callback(unsigned long data)
 {
        netif_t *netif = (netif_t *)data;
-       netif->remaining_credit = netif->credit_bytes;
+       tx_add_credit(netif);
        netif_schedule_work(netif);
 }
 
@@ -819,7 +837,7 @@ inline static void net_tx_action_dealloc
        gop = tx_unmap_ops;
        while (dc != dp) {
                pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
-               gnttab_set_unmap_op(gop, MMAP_VADDR(pending_idx),
+               gnttab_set_unmap_op(gop, idx_to_kaddr(pending_idx),
                                    GNTMAP_host_map,
                                    grant_tx_handle[pending_idx]);
                gop++;
@@ -907,7 +925,7 @@ static gnttab_map_grant_ref_t *netbk_get
                txp = RING_GET_REQUEST(&netif->tx, cons++);
                pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
 
-               gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx),
+               gnttab_set_map_op(mop++, idx_to_kaddr(pending_idx),
                                  GNTMAP_host_map | GNTMAP_readonly,
                                  txp->gref, netif->domid);
 
@@ -940,7 +958,7 @@ static int netbk_tx_check_mop(struct sk_
                netif_put(netif);
        } else {
                set_phys_to_machine(
-                       __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
+                       __pa(idx_to_kaddr(pending_idx)) >> PAGE_SHIFT,
                        FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
                grant_tx_handle[pending_idx] = mop->handle;
        }
@@ -957,7 +975,7 @@ static int netbk_tx_check_mop(struct sk_
                newerr = (++mop)->status;
                if (likely(!newerr)) {
                        set_phys_to_machine(
-                               __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT,
+                               __pa(idx_to_kaddr(pending_idx))>>PAGE_SHIFT,
                                FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
                        grant_tx_handle[pending_idx] = mop->handle;
                        /* Had a previous error? Invalidate this fragment. */
@@ -1005,7 +1023,7 @@ static void netbk_fill_frags(struct sk_b
 
                pending_idx = (unsigned long)frag->page;
                txp = &pending_tx_info[pending_idx].req;
-               frag->page = virt_to_page(MMAP_VADDR(pending_idx));
+               frag->page = virt_to_page(idx_to_kaddr(pending_idx));
                frag->size = txp->size;
                frag->page_offset = txp->offset;
 
@@ -1101,6 +1119,7 @@ static void net_tx_action(unsigned long 
                i = netif->tx.req_cons;
                rmb(); /* Ensure that we see the request before we copy it. */
                memcpy(&txreq, RING_GET_REQUEST(&netif->tx, i), sizeof(txreq));
+
                /* Credit-based scheduling. */
                if (txreq.size > netif->remaining_credit) {
                        unsigned long now = jiffies;
@@ -1109,25 +1128,27 @@ static void net_tx_action(unsigned long 
                                msecs_to_jiffies(netif->credit_usec / 1000);
 
                        /* Timer could already be pending in rare cases. */
-                       if (timer_pending(&netif->credit_timeout))
-                               break;
+                       if (timer_pending(&netif->credit_timeout)) {
+                               netif_put(netif);
+                               continue;
+                       }
 
                        /* Passed the point where we can replenish credit? */
                        if (time_after_eq(now, next_credit)) {
                                netif->credit_timeout.expires = now;
-                               netif->remaining_credit = netif->credit_bytes;
+                               tx_add_credit(netif);
                        }
 
                        /* Still too big to send right now? Set a callback. */
                        if (txreq.size > netif->remaining_credit) {
-                               netif->remaining_credit = 0;
                                netif->credit_timeout.data     =
                                        (unsigned long)netif;
                                netif->credit_timeout.function =
                                        tx_credit_callback;
                                __mod_timer(&netif->credit_timeout,
                                            next_credit);
-                               break;
+                               netif_put(netif);
+                               continue;
                        }
                }
                netif->remaining_credit -= txreq.size;
@@ -1201,7 +1222,7 @@ static void net_tx_action(unsigned long 
                        }
                }
 
-               gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
+               gnttab_set_map_op(mop, idx_to_kaddr(pending_idx),
                                  GNTMAP_host_map | GNTMAP_readonly,
                                  txreq.gref, netif->domid);
                mop++;
@@ -1260,8 +1281,8 @@ static void net_tx_action(unsigned long 
                }
 
                data_len = skb->len;
-               memcpy(skb->data, 
-                      (void *)(MMAP_VADDR(pending_idx)|txp->offset),
+               memcpy(skb->data,
+                      (void *)(idx_to_kaddr(pending_idx)|txp->offset),
                       data_len);
                if (data_len < txp->size) {
                        /* Append the packet payload as a fragment. */
@@ -1315,18 +1336,10 @@ static void netif_idx_release(u16 pendin
 
 static void netif_page_release(struct page *page)
 {
-       u16 pending_idx = page - virt_to_page(mmap_vstart);
-
        /* Ready for next use. */
        set_page_count(page, 1);
 
-       netif_idx_release(pending_idx);
-}
-
-static void netif_rx_page_release(struct page *page)
-{
-       /* Ready for next use. */
-       set_page_count(page, 1);
+       netif_idx_release(page->index);
 }
 
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
@@ -1446,27 +1459,17 @@ static int __init netback_init(void)
        init_timer(&net_timer);
        net_timer.data = 0;
        net_timer.function = net_alarm;
-    
-       page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
-       if (page == NULL)
+
+       mmap_pages = alloc_empty_pages_and_pagevec(MAX_PENDING_REQS);
+       if (mmap_pages == NULL) {
+               printk("%s: out of memory\n", __FUNCTION__);
                return -ENOMEM;
-
-       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+       }
 
        for (i = 0; i < MAX_PENDING_REQS; i++) {
-               page = virt_to_page(MMAP_VADDR(i));
-               set_page_count(page, 1);
+               page = mmap_pages[i];
                SetPageForeign(page, netif_page_release);
-       }
-
-       page = balloon_alloc_empty_page_range(NET_RX_RING_SIZE);
-       BUG_ON(page == NULL);
-       rx_mmap_area = pfn_to_kaddr(page_to_pfn(page));
-
-       for (i = 0; i < NET_RX_RING_SIZE; i++) {
-               page = virt_to_page(rx_mmap_area + (i * PAGE_SIZE));
-               set_page_count(page, 1);
-               SetPageForeign(page, netif_rx_page_release);
+               page->index = i;
        }
 
        pending_cons = 0;
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Oct 11 13:04:07 
2006 -0400
@@ -366,6 +366,10 @@ static void connect(struct backend_info 
        be->netif->remaining_credit = be->netif->credit_bytes;
 
        xenbus_switch_state(dev, XenbusStateConnected);
+
+       /* May not get a kick from the frontend, so start the tx_queue now. */
+       if (!netbk_can_queue(be->netif->dev))
+               netif_start_queue(be->netif->dev);
 }
 
 
@@ -403,14 +407,16 @@ static int connect_rings(struct backend_
        }
        be->netif->copying_receiver = !!rx_copy;
 
-       if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-notify", "%d",
-                        &val) < 0)
-               val = 0;
-       if (val)
-               be->netif->can_queue = 1;
-       else
-               /* Must be non-zero for pfifo_fast to work. */
-               be->netif->dev->tx_queue_len = 1;
+       if (be->netif->dev->tx_queue_len != 0) {
+               if (xenbus_scanf(XBT_NIL, dev->otherend,
+                                "feature-rx-notify", "%d", &val) < 0)
+                       val = 0;
+               if (val)
+                       be->netif->can_queue = 1;
+               else
+                       /* Must be non-zero for pfifo_fast to work. */
+                       be->netif->dev->tx_queue_len = 1;
+       }
 
        if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0)
                val = 0;
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Oct 11 
13:04:07 2006 -0400
@@ -47,6 +47,7 @@
 #include <linux/in.h>
 #include <linux/if_ether.h>
 #include <linux/io.h>
+#include <linux/moduleparam.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
@@ -63,20 +64,64 @@
 #include <xen/interface/grant_table.h>
 #include <xen/gnttab.h>
 
+/*
+ * Mutually-exclusive module options to select receive data path:
+ *  rx_copy : Packets are copied by network backend into local memory
+ *  rx_flip : Page containing packet data is transferred to our ownership
+ * For fully-virtualised guests there is no option - copying must be used.
+ * For paravirtualised guests, flipping is the default.
+ */
+#ifdef CONFIG_XEN
+static int MODPARM_rx_copy = 0;
+module_param_named(rx_copy, MODPARM_rx_copy, bool, 0);
+MODULE_PARM_DESC(rx_copy, "Copy packets from network card (rather than flip)");
+static int MODPARM_rx_flip = 0;
+module_param_named(rx_flip, MODPARM_rx_flip, bool, 0);
+MODULE_PARM_DESC(rx_flip, "Flip packets from network card (rather than copy)");
+#else
+static const int MODPARM_rx_copy = 1;
+static const int MODPARM_rx_flip = 0;
+#endif
+
 #define RX_COPY_THRESHOLD 256
 
 /* If we don't have GSO, fake things up so that we never try to use it. */
-#ifndef NETIF_F_GSO
-#define netif_needs_gso(dev, skb)      0
-#define dev_disable_gso_features(dev)  ((void)0)
-#else
+#if defined(NETIF_F_GSO)
 #define HAVE_GSO                       1
+#define HAVE_TSO                       1 /* TSO is a subset of GSO */
 static inline void dev_disable_gso_features(struct net_device *dev)
 {
        /* Turn off all GSO bits except ROBUST. */
        dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1;
        dev->features |= NETIF_F_GSO_ROBUST;
 }
+#elif defined(NETIF_F_TSO)
+#define HAVE_TSO                       1
+#define gso_size tso_size
+#define gso_segs tso_segs
+static inline void dev_disable_gso_features(struct net_device *dev)
+{
+       /* Turn off all TSO bits. */
+       dev->features &= ~NETIF_F_TSO;
+}
+static inline int skb_is_gso(const struct sk_buff *skb)
+{
+        return skb_shinfo(skb)->tso_size;
+}
+static inline int skb_gso_ok(struct sk_buff *skb, int features)
+{
+        return (features & NETIF_F_TSO);
+}
+
+static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
+{
+        return skb_is_gso(skb) &&
+               (!skb_gso_ok(skb, dev->features) ||
+                unlikely(skb->ip_summed != CHECKSUM_HW));
+}
+#else
+#define netif_needs_gso(dev, skb)      0
+#define dev_disable_gso_features(dev)  ((void)0)
 #endif
 
 #define GRANT_INVALID_REF      0
@@ -120,7 +165,7 @@ struct netfront_info {
        grant_ref_t gref_tx_head;
        grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
        grant_ref_t gref_rx_head;
-       grant_ref_t grant_rx_ref[NET_TX_RING_SIZE];
+       grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
 
        struct xenbus_device *xbdev;
        int tx_ring_ref;
@@ -229,8 +274,7 @@ static int __devinit netfront_probe(stru
        int err;
        struct net_device *netdev;
        struct netfront_info *info;
-       unsigned int handle;
-       unsigned feature_rx_copy;
+       unsigned int handle, feature_rx_copy, feature_rx_flip, use_copy;
 
        err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle);
        if (err != 1) {
@@ -238,22 +282,24 @@ static int __devinit netfront_probe(stru
                return err;
        }
 
-#ifndef CONFIG_XEN
        err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-copy", "%u",
                           &feature_rx_copy);
-       if (err != 1) {
-               xenbus_dev_fatal(dev, err, "reading feature-rx-copy");
-               return err;
-       }
-       if (!feature_rx_copy) {
-               xenbus_dev_fatal(dev, 0, "need a copy-capable backend");
-               return -EINVAL;
-       }
-#else
-       feature_rx_copy = 0;
-#endif
-
-       netdev = create_netdev(handle, feature_rx_copy, dev);
+       if (err != 1)
+               feature_rx_copy = 0;
+       err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-flip", "%u",
+                          &feature_rx_flip);
+       if (err != 1)
+               feature_rx_flip = 1;
+
+       /*
+        * Copy packets on receive path if:
+        *  (a) This was requested by user, and the backend supports it; or
+        *  (b) Flipping was requested, but this is unsupported by the backend.
+        */
+       use_copy = (MODPARM_rx_copy && feature_rx_copy) ||
+               (MODPARM_rx_flip && !feature_rx_flip);
+
+       netdev = create_netdev(handle, use_copy, dev);
        if (IS_ERR(netdev)) {
                err = PTR_ERR(netdev);
                xenbus_dev_fatal(dev, err, "creating netdev");
@@ -270,6 +316,9 @@ static int __devinit netfront_probe(stru
        err = open_netdev(info);
        if (err)
                goto fail_open;
+
+       IPRINTK("Created netdev %s with %sing receive path.\n",
+               netdev->name, info->copying_receiver ? "copy" : "flipp");
 
        return 0;
 
@@ -385,7 +434,7 @@ again:
                goto abort_transaction;
        }
 
-#ifdef HAVE_GSO
+#ifdef HAVE_TSO
        err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1);
        if (err) {
                message = "writing feature-gso-tcpv4";
@@ -742,7 +791,7 @@ no_skb:
                } else {
                        gnttab_grant_foreign_access_ref(ref,
                                                        np->xbdev->otherend_id,
-                                                       pfn,
+                                                       pfn_to_mfn(pfn),
                                                        0);
                }
 
@@ -917,7 +966,7 @@ static int network_start_xmit(struct sk_
                tx->flags |= NETTXF_data_validated;
 #endif
 
-#ifdef HAVE_GSO
+#ifdef HAVE_TSO
        if (skb_shinfo(skb)->gso_size) {
                struct netif_extra_info *gso = (struct netif_extra_info *)
                        RING_GET_REQUEST(&np->tx, ++i);
@@ -1205,12 +1254,14 @@ static int xennet_set_skb_gso(struct sk_
                return -EINVAL;
        }
 
+#ifdef HAVE_TSO
+       skb_shinfo(skb)->gso_size = gso->u.gso.size;
 #ifdef HAVE_GSO
-       skb_shinfo(skb)->gso_size = gso->u.gso.size;
        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
 
        /* Header must be checked, and gso_segs computed. */
        skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+#endif
        skb_shinfo(skb)->gso_segs = 0;
 
        return 0;
@@ -1561,7 +1612,7 @@ static int xennet_set_sg(struct net_devi
 
 static int xennet_set_tso(struct net_device *dev, u32 data)
 {
-#ifdef HAVE_GSO
+#ifdef HAVE_TSO
        if (data) {
                struct netfront_info *np = netdev_priv(dev);
                int val;
@@ -1632,7 +1683,8 @@ static void network_connect(struct net_d
                } else {
                        gnttab_grant_foreign_access_ref(
                                ref, np->xbdev->otherend_id,
-                               page_to_pfn(skb_shinfo(skb)->frags->page),
+                               pfn_to_mfn(page_to_pfn(skb_shinfo(skb)->
+                                                      frags->page)),
                                0);
                }
                req->gref = ref;
@@ -2053,6 +2105,16 @@ static int __init netif_init(void)
        if (!is_running_on_xen())
                return -ENODEV;
 
+#ifdef CONFIG_XEN
+       if (MODPARM_rx_flip && MODPARM_rx_copy) {
+               WPRINTK("Cannot specify both rx_copy and rx_flip.\n");
+               return -EINVAL;
+       }
+
+       if (!MODPARM_rx_flip && !MODPARM_rx_copy)
+               MODPARM_rx_flip = 1; /* Default is to flip. */
+#endif
+
        if (is_initial_xendomain())
                return 0;
 
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Wed Oct 11 
13:04:07 2006 -0400
@@ -100,10 +100,12 @@ static int privcmd_ioctl(struct inode *i
        break;
 
        case IOCTL_PRIVCMD_MMAP: {
-#define PRIVCMD_MMAP_SZ 32
                privcmd_mmap_t mmapcmd;
-               privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ];
+               privcmd_mmap_entry_t msg;
                privcmd_mmap_entry_t __user *p;
+               struct mm_struct *mm = current->mm;
+               struct vm_area_struct *vma;
+               unsigned long va;
                int i, rc;
 
                if (!is_initial_xendomain())
@@ -113,47 +115,62 @@ static int privcmd_ioctl(struct inode *i
                        return -EFAULT;
 
                p = mmapcmd.entry;
-
-               for (i = 0; i < mmapcmd.num;
-                    i += PRIVCMD_MMAP_SZ, p += PRIVCMD_MMAP_SZ) {
-                       int j, n = ((mmapcmd.num-i)>PRIVCMD_MMAP_SZ)?
-                               PRIVCMD_MMAP_SZ:(mmapcmd.num-i);
-
-                       if (copy_from_user(&msg, p,
-                                          n*sizeof(privcmd_mmap_entry_t)))
-                               return -EFAULT;
-     
-                       for (j = 0; j < n; j++) {
-                               struct vm_area_struct *vma = 
-                                       find_vma( current->mm, msg[j].va );
-
-                               if (!vma)
-                                       return -EINVAL;
-
-                               if (msg[j].va > PAGE_OFFSET)
-                                       return -EINVAL;
-
-                               if ((msg[j].va + (msg[j].npages << PAGE_SHIFT))
-                                   > vma->vm_end )
-                                       return -EINVAL;
-
-                               if ((rc = direct_remap_pfn_range(
-                                       vma,
-                                       msg[j].va&PAGE_MASK, 
-                                       msg[j].mfn, 
-                                       msg[j].npages<<PAGE_SHIFT, 
-                                       vma->vm_page_prot,
-                                       mmapcmd.dom)) < 0)
-                                       return rc;
-                       }
-               }
-               ret = 0;
+               if (copy_from_user(&msg, p, sizeof(msg)))
+                       return -EFAULT;
+
+               down_read(&mm->mmap_sem);
+
+               vma = find_vma(mm, msg.va);
+               rc = -EINVAL;
+               if (!vma || (msg.va != vma->vm_start) || vma->vm_private_data)
+                       goto mmap_out;
+
+               /* Mapping is a one-shot operation per vma. */
+               vma->vm_private_data = (void *)1;
+
+               va = vma->vm_start;
+
+               for (i = 0; i < mmapcmd.num; i++) {
+                       rc = -EFAULT;
+                       if (copy_from_user(&msg, p, sizeof(msg)))
+                               goto mmap_out;
+
+                       /* Do not allow range to wrap the address space. */
+                       rc = -EINVAL;
+                       if ((msg.npages > (INT_MAX >> PAGE_SHIFT)) ||
+                           ((unsigned long)(msg.npages << PAGE_SHIFT) >= -va))
+                               goto mmap_out;
+
+                       /* Range chunks must be contiguous in va space. */
+                       if ((msg.va != va) ||
+                           ((msg.va+(msg.npages<<PAGE_SHIFT)) > vma->vm_end))
+                               goto mmap_out;
+
+                       if ((rc = direct_remap_pfn_range(
+                               vma,
+                               msg.va & PAGE_MASK, 
+                               msg.mfn, 
+                               msg.npages << PAGE_SHIFT, 
+                               vma->vm_page_prot,
+                               mmapcmd.dom)) < 0)
+                               goto mmap_out;
+
+                       p++;
+                       va += msg.npages << PAGE_SHIFT;
+               }
+
+               rc = 0;
+
+       mmap_out:
+               up_read(&mm->mmap_sem);
+               ret = rc;
        }
        break;
 
        case IOCTL_PRIVCMD_MMAPBATCH: {
                privcmd_mmapbatch_t m;
-               struct vm_area_struct *vma = NULL;
+               struct mm_struct *mm = current->mm;
+               struct vm_area_struct *vma;
                xen_pfn_t __user *p;
                unsigned long addr, mfn;
                int i;
@@ -161,37 +178,33 @@ static int privcmd_ioctl(struct inode *i
                if (!is_initial_xendomain())
                        return -EPERM;
 
-               if (copy_from_user(&m, udata, sizeof(m))) {
-                       ret = -EFAULT;
-                       goto batch_err;
-               }
-
-               if (m.dom == DOMID_SELF) {
-                       ret = -EINVAL;
-                       goto batch_err;
-               }
-
-               vma = find_vma(current->mm, m.addr);
-               if (!vma) {
-                       ret = -EINVAL;
-                       goto batch_err;
-               }
-
-               if (m.addr > PAGE_OFFSET) {
-                       ret = -EFAULT;
-                       goto batch_err;
-               }
-
-               if ((m.addr + (m.num<<PAGE_SHIFT)) > vma->vm_end) {
-                       ret = -EFAULT;
-                       goto batch_err;
-               }
+               if (copy_from_user(&m, udata, sizeof(m)))
+                       return -EFAULT;
+
+               if ((m.num <= 0) || (m.num > (INT_MAX >> PAGE_SHIFT)))
+                       return -EINVAL;
+
+               down_read(&mm->mmap_sem);
+
+               vma = find_vma(mm, m.addr);
+               if (!vma ||
+                   (m.addr != vma->vm_start) ||
+                   ((m.addr + (m.num<<PAGE_SHIFT)) != vma->vm_end) ||
+                   vma->vm_private_data) {
+                       up_read(&mm->mmap_sem);
+                       return -EINVAL;
+               }
+
+               /* Mapping is a one-shot operation per vma. */
+               vma->vm_private_data = (void *)1;
 
                p = m.arr;
                addr = m.addr;
                for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
-                       if (get_user(mfn, p))
+                       if (get_user(mfn, p)) {
+                               up_read(&mm->mmap_sem);
                                return -EFAULT;
+                       }
 
                        ret = direct_remap_pfn_range(vma, addr & PAGE_MASK,
                                                     mfn, PAGE_SIZE,
@@ -200,15 +213,8 @@ static int privcmd_ioctl(struct inode *i
                                put_user(0xF0000000 | mfn, p);
                }
 
+               up_read(&mm->mmap_sem);
                ret = 0;
-               break;
-
-       batch_err:
-               printk("batch_err ret=%d vma=%p addr=%lx "
-                      "num=%d arr=%p %lx-%lx\n", 
-                      ret, vma, (unsigned long)m.addr, m.num, m.arr,
-                      vma ? vma->vm_start : 0, vma ? vma->vm_end : 0);
-               break;
        }
        break;
 
@@ -221,10 +227,27 @@ static int privcmd_ioctl(struct inode *i
 }
 
 #ifndef HAVE_ARCH_PRIVCMD_MMAP
+static struct page *privcmd_nopage(struct vm_area_struct *vma,
+                                  unsigned long address,
+                                  int *type)
+{
+       return NOPAGE_SIGBUS;
+}
+
+static struct vm_operations_struct privcmd_vm_ops = {
+       .nopage = privcmd_nopage
+};
+
 static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
 {
+       /* Unsupported for auto-translate guests. */
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return -ENOSYS;
+
        /* DONTCOPY is essential for Xen as copy_page_range is broken. */
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+       vma->vm_ops = &privcmd_vm_ops;
+       vma->vm_private_data = NULL;
 
        return 0;
 }
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Oct 11 13:04:07 
2006 -0400
@@ -46,11 +46,10 @@ typedef struct tpmif_st {
        atomic_t refcnt;
 
        struct backend_info *bi;
-       unsigned long mmap_vstart;
 
        grant_handle_t shmem_handle;
        grant_ref_t shmem_ref;
-       struct page *pagerange;
+       struct page **mmap_pages;
 
        char devname[20];
 } tpmif_t;
@@ -80,6 +79,9 @@ int vtpm_release_packets(tpmif_t * tpmif
 
 extern int num_frontends;
 
-#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
+static inline unsigned long idx_to_kaddr(tpmif_t *t, unsigned int idx)
+{
+       return (unsigned long)pfn_to_kaddr(page_to_pfn(t->mmap_pages[idx]));
+}
 
 #endif /* __TPMIF__BACKEND__COMMON_H__ */
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Wed Oct 11 
13:04:07 2006 -0400
@@ -25,8 +25,8 @@ static tpmif_t *alloc_tpmif(domid_t domi
        tpmif_t *tpmif;
 
        tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
-       if (!tpmif)
-               return ERR_PTR(-ENOMEM);
+       if (tpmif == NULL)
+               goto out_of_memory;
 
        memset(tpmif, 0, sizeof (*tpmif));
        tpmif->domid = domid;
@@ -35,22 +35,27 @@ static tpmif_t *alloc_tpmif(domid_t domi
        snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
        atomic_set(&tpmif->refcnt, 1);
 
-       tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
-       BUG_ON(tpmif->pagerange == NULL);
-       tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(
-                                           page_to_pfn(tpmif->pagerange));
+       tpmif->mmap_pages = alloc_empty_pages_and_pagevec(TPMIF_TX_RING_SIZE);
+       if (tpmif->mmap_pages == NULL)
+               goto out_of_memory;
 
        list_add(&tpmif->tpmif_list, &tpmif_list);
        num_frontends++;
 
        return tpmif;
+
+ out_of_memory:
+       if (tpmif != NULL)
+               kmem_cache_free(tpmif_cachep, tpmif);
+       printk("%s: out of memory\n", __FUNCTION__);
+       return ERR_PTR(-ENOMEM);
 }
 
 static void free_tpmif(tpmif_t * tpmif)
 {
        num_frontends--;
        list_del(&tpmif->tpmif_list);
-       balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE);
+       free_empty_pages_and_pagevec(tpmif->mmap_pages, TPMIF_TX_RING_SIZE);
        kmem_cache_free(tpmif_cachep, tpmif);
 }
 
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Wed Oct 11 
13:04:07 2006 -0400
@@ -253,7 +253,7 @@ int _packet_write(struct packet *pak,
                        return 0;
                }
 
-               gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
                if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
@@ -270,7 +270,7 @@ int _packet_write(struct packet *pak,
 
                tocopy = min_t(size_t, size - offset, PAGE_SIZE);
 
-               if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) |
+               if (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) |
                                              (tx->addr & ~PAGE_MASK)),
                                     &data[offset], tocopy, isuserbuffer)) {
                        tpmif_put(tpmif);
@@ -278,7 +278,7 @@ int _packet_write(struct packet *pak,
                }
                tx->size = tocopy;
 
-               gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
                                    GNTMAP_host_map, handle);
 
                if (unlikely
@@ -391,7 +391,7 @@ static int packet_read_shmem(struct pack
 
                tx = &tpmif->tx->ring[i].req;
 
-               gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
                                  GNTMAP_host_map, tx->ref, tpmif->domid);
 
                if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
@@ -414,10 +414,10 @@ static int packet_read_shmem(struct pack
                }
 
                DPRINTK("Copying from mapped memory at %08lx\n",
-                       (unsigned long)(MMAP_VADDR(tpmif, i) |
+                       (unsigned long)(idx_to_kaddr(tpmif, i) |
                                        (tx->addr & ~PAGE_MASK)));
 
-               src = (void *)(MMAP_VADDR(tpmif, i) |
+               src = (void *)(idx_to_kaddr(tpmif, i) |
                               ((tx->addr & ~PAGE_MASK) + pg_offset));
                if (copy_to_buffer(&buffer[offset],
                                   src, to_copy, isuserbuffer)) {
@@ -428,7 +428,7 @@ static int packet_read_shmem(struct pack
                        tpmif->domid, buffer[offset], buffer[offset + 1],
                        buffer[offset + 2], buffer[offset + 3]);
 
-               gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
+               gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
                                    GNTMAP_host_map, handle);
 
                if (unlikely
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Wed Oct 11 
13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Wed Oct 11 
13:04:07 2006 -0400
@@ -322,6 +322,20 @@ static void otherend_changed(struct xenb
        DPRINTK("state is %d (%s), %s, %s", state, xenbus_strstate(state),
                dev->otherend_watch.node, vec[XS_WATCH_PATH]);
 
+       /*
+        * Ignore xenbus transitions during shutdown. This prevents us doing
+        * work that can fail e.g., when the rootfs is gone.
+        */
+       if (system_state > SYSTEM_RUNNING) {
+               struct xen_bus_type *bus = bus;
+               bus = container_of(dev->dev.bus, struct xen_bus_type, bus);
+               /* If we're frontend, drive the state machine to Closed. */
+               /* This should cause the backend to release our resources. */
+               if ((bus == &xenbus_frontend) && (state == XenbusStateClosing))
+                       xenbus_frontend_closed(dev);
+               return;
+       }
+
        if (drv->otherend_changed)
                drv->otherend_changed(dev, state);
 }
diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/include/xen/balloon.h
--- a/linux-2.6-xen-sparse/include/xen/balloon.h        Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/include/xen/balloon.h        Wed Oct 11 13:04:07 
2006 -0400
@@ -38,23 +38,13 @@
  * Inform the balloon driver that it should allow some slop for device-driver
  * memory activities.
  */
-void
-balloon_update_driver_allowance(
-       long delta);
+void balloon_update_driver_allowance(long delta);
 
-/* Allocate an empty low-memory page range. */
-struct page *
-balloon_alloc_empty_page_range(
-       unsigned long nr_pages);
+/* Allocate/free a set of empty pages in low memory (i.e., no RAM mapped). */
+struct page **alloc_empty_pages_and_pagevec(int nr_pages);
+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages);
 
-/* Deallocate an empty page range, adding to the balloon. */
-void
-balloon_dealloc_empty_page_range(
-       struct page *page, unsigned long nr_pages);
-
-void
-balloon_release_driver_page(
-       struct page *page);
+void balloon_release_driver_page(struct page *page);
 
 /*
  * Prevent the balloon driver from changing the memory reservation during
diff -r e7cb3aefc233 -r b53c343b47ae 
linux-2.6-xen-sparse/include/xen/public/evtchn.h
--- a/linux-2.6-xen-sparse/include/xen/public/evtchn.h  Wed Oct 11 13:01:31 
2006 -0400
+++ b/linux-2.6-xen-sparse/include/xen/public/evtchn.h  Wed Oct 11 13:04:07 
2006 -0400
@@ -32,9 +32,6 @@
 
 #ifndef __LINUX_PUBLIC_EVTCHN_H__
 #define __LINUX_PUBLIC_EVTCHN_H__
-
-/* /dev/xen/evtchn resides at device number major=10, minor=201 */
-#define EVTCHN_MINOR 201
 
 /*
  * Bind a fresh port to VIRQ @virq.
diff -r e7cb3aefc233 -r b53c343b47ae linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c  Wed Oct 11 13:01:31 2006 -0400
+++ b/linux-2.6-xen-sparse/mm/memory.c  Wed Oct 11 13:04:07 2006 -0400
@@ -390,7 +390,7 @@ struct page *vm_normal_page(struct vm_ar
 
        if (vma->vm_flags & VM_PFNMAP) {
                unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT;
-               if ((pfn == vma->vm_pgoff + off) || !pfn_valid(pfn))
+               if (pfn == vma->vm_pgoff + off)
                        return NULL;
                if (!is_cow_mapping(vma->vm_flags))
                        return NULL;
@@ -405,7 +405,8 @@ struct page *vm_normal_page(struct vm_ar
         * Remove this test eventually!
         */
        if (unlikely(!pfn_valid(pfn))) {
-               print_bad_pte(vma, pte, addr);
+               if (!(vma->vm_flags & VM_RESERVED))
+                       print_bad_pte(vma, pte, addr);
                return NULL;
        }
 
diff -r e7cb3aefc233 -r b53c343b47ae patches/linux-2.6.16.29/series
--- a/patches/linux-2.6.16.29/series    Wed Oct 11 13:01:31 2006 -0400
+++ b/patches/linux-2.6.16.29/series    Wed Oct 11 13:04:07 2006 -0400
@@ -10,6 +10,7 @@ net-gso-2-checksum-fix.patch
 net-gso-2-checksum-fix.patch
 net-gso-3-fix-errorcheck.patch
 net-gso-4-kill-warnon.patch
+pci-mmconfig-fix-from-2.6.17.patch
 pmd-shared.patch
 rcu_needs_cpu.patch
 rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch
diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/drivers/Makefile
--- a/tools/blktap/drivers/Makefile     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/blktap/drivers/Makefile     Wed Oct 11 13:04:07 2006 -0400
@@ -10,11 +10,8 @@ INSTALL_DIR  = /usr/sbin
 INSTALL_DIR  = /usr/sbin
 LIBAIO_DIR   = ../../libaio/src
 
-CFLAGS   += -fPIC
-CFLAGS   += -Wall
 CFLAGS   += -Werror
 CFLAGS   += -Wno-unused
-CFLAGS   += -g3
 CFLAGS   += -fno-strict-aliasing
 CFLAGS   += -I $(XEN_LIBXC) -I $(LIBAIO_DIR)
 CFLAGS   += $(INCLUDES) -I. -I../../xenstore 
@@ -28,7 +25,7 @@ THREADLIB := -lpthread -lz
 THREADLIB := -lpthread -lz
 LIBS      := -L. -L.. -L../lib
 LIBS      += -L$(XEN_LIBXC)
-LIBS      += -lblktap
+LIBS      += -lblktap -lxenctrl
 LIBS      += -lcrypto
 LIBS      += -lz
 LIBS      += -L$(XEN_XENSTORE) -lxenstore
diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/blktap/drivers/blktapctrl.c Wed Oct 11 13:04:07 2006 -0400
@@ -67,15 +67,12 @@ int max_timeout = MAX_TIMEOUT;
 int max_timeout = MAX_TIMEOUT;
 int ctlfd = 0;
 
+int blktap_major;
+
 static int open_ctrl_socket(char *devname);
 static int write_msg(int fd, int msgtype, void *ptr, void *ptr2);
 static int read_msg(int fd, int msgtype, void *ptr);
 static driver_list_entry_t *active_disks[MAX_DISK_TYPES];
-
-void sig_handler(int sig)
-{
-       run = 0;        
-}
 
 static void init_driver_list(void)
 {
@@ -108,7 +105,18 @@ static void make_blktap_dev(char *devnam
                if (mknod(devname, S_IFCHR|0600,
                        makedev(major, minor)) == 0)
                        DPRINTF("Created %s device\n",devname);
-       } else DPRINTF("%s device already exists\n",devname);
+       } else {
+               DPRINTF("%s device already exists\n",devname);
+               /* it already exists, but is it the same major number */
+               if (((st.st_rdev>>8) & 0xff) != major) {
+                       DPRINTF("%s has old major %d\n",
+                               devname,
+                               (unsigned int)((st.st_rdev >> 8) & 0xff));
+                       /* only try again if we succed in deleting it */
+                       if (!unlink(devname))
+                               make_blktap_dev(devname, major, minor);
+               }
+       }
 }
 
 static int get_new_dev(int *major, int *minor, blkif_t *blkif)
@@ -644,14 +652,18 @@ int main(int argc, char *argv[])
        register_new_devmap_hook(map_new_blktapctrl);
        register_new_unmap_hook(unmap_blktapctrl);
 
-       /*Attach to blktap0 */  
+       /* Attach to blktap0 */
        asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME);
-       make_blktap_dev(devname,254,0);
+       if ((ret = xc_find_device_number("blktap0")) < 0)
+               goto open_failed;
+       blktap_major = major(ret);
+       make_blktap_dev(devname,blktap_major,0);
        ctlfd = open(devname, O_RDWR);
        if (ctlfd == -1) {
                DPRINTF("blktap0 open failed\n");
                goto open_failed;
        }
+
 
  retry:
        /* Set up store connection and watch. */
@@ -666,15 +678,11 @@ int main(int argc, char *argv[])
                 } else goto open_failed;
        }
        
-       ret = add_blockdevice_probe_watch(h, "Domain-0");
+       ret = setup_probe_watch(h);
        if (ret != 0) {
                DPRINTF("Failed adding device probewatch\n");
-                if (count < MAX_ATTEMPTS) {
-                        count++;
-                        sleep(2);
-                        xs_daemon_close(h);
-                        goto retry;
-                } else goto open_failed;
+               xs_daemon_close(h);
+               goto open_failed;
        }
 
        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/blktap/drivers/tapdisk.c    Wed Oct 11 13:04:07 2006 -0400
@@ -271,7 +271,6 @@ static int read_msg(char *buf)
        int length, len, msglen, tap_fd, *io_fd;
        char *ptr, *path;
        image_t *img;
-       struct timeval timeout;
        msg_hdr_t *msg;
        msg_newdev_t *msg_dev;
        msg_pid_t *msg_pid;
@@ -579,8 +578,7 @@ int main(int argc, char *argv[])
 {
        int len, msglen, ret;
        char *p, *buf;
-       fd_set readfds, writefds;
-       struct timeval timeout;
+       fd_set readfds, writefds;       
        fd_list_entry_t *ptr;
        struct tap_disk *drv;
        struct td_state *s;
@@ -622,12 +620,9 @@ int main(int argc, char *argv[])
                /*Set all tap fds*/
                LOCAL_FD_SET(&readfds);
 
-               timeout.tv_sec = 0; 
-               timeout.tv_usec = 1000; 
-
                /*Wait for incoming messages*/
                ret = select(maxfds + 1, &readfds, (fd_set *) 0, 
-                            (fd_set *) 0, &timeout);
+                            (fd_set *) 0, NULL);
 
                if (ret > 0) 
                {
diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/blktap/lib/blktaplib.h      Wed Oct 11 13:04:07 2006 -0400
@@ -80,8 +80,9 @@ static inline int BLKTAP_MODE_VALID(unsi
 #define MAX_PENDING_REQS 64
 #define BLKTAP_DEV_DIR   "/dev/xen"
 #define BLKTAP_DEV_NAME  "blktap"
-#define BLKTAP_DEV_MAJOR 254
 #define BLKTAP_DEV_MINOR 0
+
+extern int blktap_major;
 
 #define BLKTAP_RING_PAGES       1 /* Front */
 #define BLKTAP_MMAP_REGION_SIZE (BLKTAP_RING_PAGES + MMAP_PAGES)
@@ -192,8 +193,8 @@ typedef struct msg_pid {
 #define CTLMSG_PID_RSP     10
 
 /* xenstore/xenbus: */
-extern int add_blockdevice_probe_watch(struct xs_handle *h, 
-                                       const char *domname);
+#define DOMNAME "Domain-0"
+int setup_probe_watch(struct xs_handle *h);
 int xs_fire_next_watch(struct xs_handle *h);
 
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/xenbus.c
--- a/tools/blktap/lib/xenbus.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/blktap/lib/xenbus.c Wed Oct 11 13:04:07 2006 -0400
@@ -166,60 +166,58 @@ static void ueblktap_setup(struct xs_han
                goto fail;
        }
 
-        deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL);
-        if (!deverr) {
-                DPRINTF("pdev set to %ld\n",pdev);
-                if (be->pdev && be->pdev != pdev) {
-                        DPRINTF("changing physical-device not supported");
-                        goto fail;
-                }
-                be->pdev = pdev;
-        }
-
-        /*Check to see if device is to be opened read-only*/
-        asprintf(&path, "%s/%s", bepath, "read-only");
-        if (xs_exists(h, path))
-                be->readonly = 1;
-
-        if (be->blkif == NULL) {
-
-                /* Front end dir is a number, which is used as the handle. */
-                p = strrchr(be->frontpath, '/') + 1;
-                handle = strtoul(p, NULL, 0);
-
-                be->blkif = alloc_blkif(be->frontend_id);
-       
-                if (be->blkif == NULL)
-                        goto fail;
+       deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL);
+       if (!deverr) {
+               DPRINTF("pdev set to %ld\n",pdev);
+               if (be->pdev && be->pdev != pdev) {
+                       DPRINTF("changing physical-device not supported");
+                       goto fail;
+               }
+               be->pdev = pdev;
+       }
+
+       /* Check to see if device is to be opened read-only. */
+       asprintf(&path, "%s/%s", bepath, "read-only");
+       if (xs_exists(h, path))
+               be->readonly = 1;
+
+       if (be->blkif == NULL) {
+               /* Front end dir is a number, which is used as the handle. */
+               p = strrchr(be->frontpath, '/') + 1;
+               handle = strtoul(p, NULL, 0);
+
+               be->blkif = alloc_blkif(be->frontend_id);
+               if (be->blkif == NULL)
+                       goto fail;
 
                be->blkif->be_id = get_be_id(bepath);
                
-                /*Insert device specific info*/
-                blk = malloc(sizeof(blkif_info_t));
+               /* Insert device specific info, */
+               blk = malloc(sizeof(blkif_info_t));
                if (!blk) {
                        DPRINTF("Out of memory - blkif_info_t\n");
                        goto fail;
                }
-                er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL);
-                if (er)
-                        goto fail;
-                be->blkif->info = blk;
+               er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL);
+               if (er)
+                       goto fail;
+               be->blkif->info = blk;
                
-                if (deverr) {
-                        /*Dev number was not available, try to set manually*/
-                        pdev = convert_dev_name_to_num(blk->params);
-                        be->pdev = pdev;
-                }
-
-                er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
-
-                if (er != 0) {
-                        DPRINTF("Unable to open device %s\n",blk->params);
-                       goto fail;
-               }
-
-                DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath);
-        }      
+               if (deverr) {
+                       /*Dev number was not available, try to set manually*/
+                       pdev = convert_dev_name_to_num(blk->params);
+                       be->pdev = pdev;
+               }
+
+               er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
+               if (er != 0) {
+                       DPRINTF("Unable to open device %s\n",blk->params);
+                       goto fail;
+               }
+
+               DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath);
+       }
+
        /* Supply the information about the device to xenstore */
        er = xs_printf(h, be->backpath, "sectors", "%lu",
                        be->blkif->ops->get_size(be->blkif));
@@ -283,10 +281,10 @@ static void ueblktap_probe(struct xs_han
         *asserts that xenstore structure is always 7 levels deep
         *e.g. /local/domain/0/backend/vbd/1/2049
         */
-        len = strsep_len(bepath, '/', 7);
-        if (len < 0) 
-               goto free_be;     
-        bepath[len] = '\0';
+       len = strsep_len(bepath, '/', 7);
+       if (len < 0) 
+               goto free_be;
+       bepath[len] = '\0';
        
        be = malloc(sizeof(*be));
        if (!be) {
@@ -318,22 +316,21 @@ static void ueblktap_probe(struct xs_han
                if ( (be != NULL) && (be->blkif != NULL) ) 
                        backend_remove(h, be);
                else goto free_be;
-               if (bepath)
+               if (bepath)
                        free(bepath);
                return;
        }
        
-        /* Are we already tracking this device? */
-        if (be_exists_be(bepath)) {
+       /* Are we already tracking this device? */
+       if (be_exists_be(bepath))
                goto free_be;
-       }
        
        be->backpath = bepath;
-               be->frontpath = frontend;
-       
-        list_add(&be->list, &belist);
-       
-        DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath);
+       be->frontpath = frontend;
+       
+       list_add(&be->list, &belist);
+       
+       DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath);
        DPRINTF("\tFRONTEND (%s),(%ld)\n", frontend,be->frontend_id);
        
        ueblktap_setup(h, bepath);      
@@ -342,11 +339,10 @@ static void ueblktap_probe(struct xs_han
  free_be:
        if (frontend)
                free(frontend);
-        if (bepath)
+       if (bepath)
                free(bepath);
        if (be) 
                free(be);
-       return;
 }
 
 /**
@@ -356,16 +352,10 @@ static void ueblktap_probe(struct xs_han
  *are created, we initalise the state and attach a disk.
  */
 
-int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
-{
-       char *domid, *path;
+int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid)
+{
+       char *path;
        struct xenbus_watch *vbd_watch;
-       int er;
-       
-       domid = get_dom_domid(h, domname);
-
-       DPRINTF("%s: %s\n", 
-               domname, (domid != NULL) ? domid : "[ not found! ]");
        
        asprintf(&path, "/local/domain/%s/backend/tap", domid);
        if (path == NULL) 
@@ -378,10 +368,67 @@ int add_blockdevice_probe_watch(struct x
        }       
        vbd_watch->node     = path;
        vbd_watch->callback = ueblktap_probe;
-       er = register_xenbus_watch(h, vbd_watch);
-       if (er == 0) {
+       if (register_xenbus_watch(h, vbd_watch) != 0) {
                DPRINTF("ERROR: adding vbd probe watch %s\n", path);
                return -EINVAL;
        }
        return 0;
 }
+
+/* Asynch callback to check for /local/domain/<DOMID>/name */
+void check_dom(struct xs_handle *h, struct xenbus_watch *w, 
+              const char *bepath_im)
+{
+       char *domid;
+
+       domid = get_dom_domid(h);
+       if (domid == NULL)
+               return;
+
+       add_blockdevice_probe_watch(h, domid);
+       free(domid);
+       unregister_xenbus_watch(h, w);
+}
+
+/* We must wait for xend to register /local/domain/<DOMID> */
+int watch_for_domid(struct xs_handle *h)
+{
+       struct xenbus_watch *domid_watch;
+       char *path = NULL;
+
+       asprintf(&path, "/local/domain");
+       if (path == NULL) 
+               return -ENOMEM;
+
+       domid_watch = malloc(sizeof(struct xenbus_watch));
+       if (domid_watch == NULL) {
+               DPRINTF("ERROR: unable to malloc domid_watch [%s]\n", path);
+               return -EINVAL;
+       }       
+
+       domid_watch->node     = path;
+       domid_watch->callback = check_dom;
+
+       if (register_xenbus_watch(h, domid_watch) != 0) {
+               DPRINTF("ERROR: adding vbd probe watch %s\n", path);
+               return -EINVAL;
+       }
+
+       DPRINTF("Set async watch for /local/domain\n");
+
+       return 0;
+}
+
+int setup_probe_watch(struct xs_handle *h)
+{
+       char *domid;
+       int ret;
+       
+       domid = get_dom_domid(h);
+       if (domid == NULL)
+               return watch_for_domid(h);
+
+       ret = add_blockdevice_probe_watch(h, domid);
+       free(domid);
+       return ret;
+}
diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/xs_api.c
--- a/tools/blktap/lib/xs_api.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/blktap/lib/xs_api.c Wed Oct 11 13:04:07 2006 -0400
@@ -106,7 +106,7 @@ again:
        if (!xs_transaction_end(xs, xth, ret)) {
                if (ret == 0 && errno == EAGAIN)
                        goto again;
-                else
+               else
                        ret = errno;
        }
 
@@ -118,25 +118,25 @@ int xs_printf(struct xs_handle *h, const
 int xs_printf(struct xs_handle *h, const char *dir, const char *node, 
              const char *fmt, ...)
 {
-        char *buf, *path;
-        va_list ap;
-        int ret;
-       
-        va_start(ap, fmt);
-        ret = vasprintf(&buf, fmt, ap);
-        va_end(ap);
-       
-        asprintf(&path, "%s/%s", dir, node);
-       
-        if ( (path == NULL) || (buf == NULL) )
+       char *buf, *path;
+       va_list ap;
+       int ret;
+       
+       va_start(ap, fmt);
+       ret = vasprintf(&buf, fmt, ap);
+       va_end(ap);
+       
+       asprintf(&path, "%s/%s", dir, node);
+       
+       if ((path == NULL) || (buf == NULL))
                return 0;
 
-        ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1);
-       
-        free(buf);
-        free(path);
-       
-        return ret;
+       ret = xs_write(h, XBT_NULL, path, buf, strlen(buf)+1);
+       
+       free(buf);
+       free(path);
+       
+       return ret;
 }
 
 
@@ -165,7 +165,7 @@ int xs_exists(struct xs_handle *h, const
  * This assumes that the domain name we are looking for is unique. 
  * Name parameter Domain-0 
  */
-char *get_dom_domid(struct xs_handle *h, const char *name)
+char *get_dom_domid(struct xs_handle *h)
 {
        char **e, *val, *domid = NULL;
        unsigned int num, len;
@@ -179,7 +179,9 @@ char *get_dom_domid(struct xs_handle *h,
        }
        
        e = xs_directory(h, xth, "/local/domain", &num);
-       
+       if (e == NULL)
+               return NULL;
+
        for (i = 0; (i < num) && (domid == NULL); i++) {
                asprintf(&path, "/local/domain/%s/name", e[i]);
                val = xs_read(h, xth, path, &len);
@@ -187,7 +189,7 @@ char *get_dom_domid(struct xs_handle *h,
                if (val == NULL)
                        continue;
                
-               if (strcmp(val, name) == 0) {
+               if (strcmp(val, DOMNAME) == 0) {
                        /* match! */
                        asprintf(&path, "/local/domain/%s/domid", e[i]);
                        domid = xs_read(h, xth, path, &len);
@@ -249,12 +251,12 @@ int convert_dev_name_to_num(char *name) 
                ret = BASE_DEV_VAL;
        }
 
-        free(p_sd);
-        free(p_hd);
-        free(p_xvd);
-        free(p_plx);
-        free(alpha);
-        
+       free(p_sd);
+       free(p_hd);
+       free(p_xvd);
+       free(p_plx);
+       free(alpha);
+
        return ret;
 }
 
@@ -281,42 +283,39 @@ int register_xenbus_watch(struct xs_hand
 {
        /* Pointer in ascii is the token. */
        char token[sizeof(watch) * 2 + 1];
-       int er;
-       
+
        sprintf(token, "%lX", (long)watch);
-       if (find_watch(token)) 
-       {
+       if (find_watch(token)) {
                DPRINTF("watch collision!\n");
                return -EINVAL;
        }
        
-       er = xs_watch(h, watch->node, token);
-       if (er != 0) {
-               list_add(&watch->list, &watches);
-       } 
-        
-       return er;
+       if (!xs_watch(h, watch->node, token)) {
+               DPRINTF("unable to set watch!\n");
+               return -EINVAL;
+       }
+
+       list_add(&watch->list, &watches);
+
+       return 0;
 }
 
 int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch)
 {
        char token[sizeof(watch) * 2 + 1];
-       int er;
        
        sprintf(token, "%lX", (long)watch);
-       if (!find_watch(token))
-       {
+       if (!find_watch(token)) {
                DPRINTF("no such watch!\n");
                return -EINVAL;
        }
-       
-       
-       er = xs_unwatch(h, watch->node, token);
+
+       if (!xs_unwatch(h, watch->node, token))
+               DPRINTF("XENBUS Failed to release watch %s: %i\n",
+                       watch->node, er);
+
        list_del(&watch->list);
        
-       if (er == 0)
-               DPRINTF("XENBUS Failed to release watch %s: %i\n",
-                    watch->node, er);
        return 0;
 }
 
@@ -354,14 +353,10 @@ int xs_fire_next_watch(struct xs_handle 
        token = res[XS_WATCH_TOKEN];
        
        w = find_watch(token);
-       if (!w)
-       {
-               DPRINTF("unregistered watch fired\n");
-               goto done;
-       }
-       w->callback(h, w, node);
-       
- done:
+       if (w)
+               w->callback(h, w, node);
+
        free(res);
+
        return 1;
 }
diff -r e7cb3aefc233 -r b53c343b47ae tools/blktap/lib/xs_api.h
--- a/tools/blktap/lib/xs_api.h Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/blktap/lib/xs_api.h Wed Oct 11 13:04:07 2006 -0400
@@ -42,7 +42,7 @@ int xs_printf(struct xs_handle *h, const
 int xs_printf(struct xs_handle *h, const char *dir, const char *node, 
              const char *fmt, ...);
 int xs_exists(struct xs_handle *h, const char *path);
-char *get_dom_domid(struct xs_handle *h, const char *name);
+char *get_dom_domid(struct xs_handle *h);
 int convert_dev_name_to_num(char *name);
 int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
 int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/block
--- a/tools/examples/block      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/examples/block      Wed Oct 11 13:04:07 2006 -0400
@@ -377,7 +377,6 @@ mount it read-write in a guest domain."
       "")
         claim_lock "block"
         success
-        echo happy gun \"$t\" >>/tmp/block.$$
         release_lock "block"
        ;;
     esac
diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/init.d/xendomains
--- a/tools/examples/init.d/xendomains  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/examples/init.d/xendomains  Wed Oct 11 13:04:07 2006 -0400
@@ -352,9 +352,9 @@ stop()
            if test $? -ne 0; then
                rc_failed $?
                echo -n '!'
-               kill $WDOG_PIG >/dev/null 2>&1
-           else
-               kill $WDOG_PIG >/dev/null 2>&1
+               kill $WDOG_PID >/dev/null 2>&1
+           else
+               kill $WDOG_PID >/dev/null 2>&1
                continue
            fi
        fi
@@ -368,7 +368,7 @@ stop()
                rc_failed $?
                echo -n '!'
            fi
-           kill $WDOG_PIG >/dev/null 2>&1
+           kill $WDOG_PID >/dev/null 2>&1
        fi
     done < <(xm list | grep -v '^Name')
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/locking.sh
--- a/tools/examples/locking.sh Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/examples/locking.sh Wed Oct 11 13:04:07 2006 -0400
@@ -21,7 +21,7 @@
 
 LOCK_SLEEPTIME=1
 LOCK_SPINNING_RETRIES=5
-LOCK_RETRIES=10
+LOCK_RETRIES=100
 LOCK_BASEDIR=/var/run/xen-hotplug
 
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/examples/xen-backend.rules  Wed Oct 11 13:04:07 2006 -0400
@@ -5,3 +5,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vif*"
 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", 
RUN+="$env{script} offline"
 SUBSYSTEM=="xen-backend", ACTION=="remove", 
RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
 KERNEL=="evtchn", NAME="xen/%k"
+KERNEL=="blktap[0-9]*", NAME="xen/%k"
diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/examples/xend-config.sxp    Wed Oct 11 13:04:07 2006 -0400
@@ -130,3 +130,8 @@
 
 # The tool used for initiating virtual TPM migration
 #(external-migration-tool '')
+
+# The interface for VNC servers to listen on. Defaults
+# to 127.0.0.1  To restore old 'listen everywhere' behaviour
+# set this to 0.0.0.0
+#(vnc-listen '127.0.0.1')
diff -r e7cb3aefc233 -r b53c343b47ae tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/examples/xmexample.hvm      Wed Oct 11 13:04:07 2006 -0400
@@ -132,6 +132,11 @@ vnc=1
 vnc=1
 
 #----------------------------------------------------------------------------
+# address that should be listened on for the VNC server if vnc is set.
+# default is to use 'vnc-listen' setting from /etc/xen/xend-config.sxp
+#vnclisten="127.0.0.1"
+
+#----------------------------------------------------------------------------
 # set VNC display number, default = domid
 #vncdisplay=1
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/firmware/hvmloader/hvmloader.c      Wed Oct 11 13:04:07 2006 -0400
@@ -170,6 +170,9 @@ main(void)
 
        init_hypercalls();
 
+       puts("Writing SMBIOS tables ...\n");
+       hvm_write_smbios_tables();
+
        puts("Loading ROMBIOS ...\n");
        memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
 
@@ -201,9 +204,6 @@ main(void)
                }
        }
 
-       puts("Writing SMBIOS tables ...\n");
-       hvm_write_smbios_tables();
-
        if (check_amd()) {
                /* AMD implies this is SVM */
                 puts("SVM go ...\n");
diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/firmware/hvmloader/smbios.c Wed Oct 11 13:04:07 2006 -0400
@@ -28,23 +28,15 @@
 #include "util.h"
 #include "hypercall.h"
 
-/* write SMBIOS tables starting at 'start', without writing more
-   than 'max_size' bytes.
-
-   Return the number of bytes written
-*/
 static size_t
-write_smbios_tables(void *start, size_t max_size,
+write_smbios_tables(void *start,
                    uint32_t vcpus, uint64_t memsize,
                    uint8_t uuid[16], char *xen_version,
                    uint32_t xen_major_version, uint32_t xen_minor_version);
 
 static void
 get_cpu_manufacturer(char *buf, int len);
-static size_t
-smbios_table_size(uint32_t vcpus, const char *xen_version,
-                 const char *processor_manufacturer);
-static void *
+static void
 smbios_entry_point_init(void *start,
                        uint16_t max_structure_size,
                        uint16_t structure_table_length,
@@ -71,7 +63,7 @@ smbios_type_20_init(void *start, uint32_
 smbios_type_20_init(void *start, uint32_t memory_size_mb);
 static void *
 smbios_type_32_init(void *start);
-void *
+static void *
 smbios_type_127_init(void *start);
 
 static void
@@ -80,7 +72,8 @@ get_cpu_manufacturer(char *buf, int len)
        char id[12];
        uint32_t eax = 0;
 
-       cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8], (uint32_t 
*)&id[4]);
+       cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8],
+             (uint32_t *)&id[4]);
 
        if (memcmp(id, "GenuineIntel", 12) == 0)
                strncpy(buf, "Intel", len);
@@ -90,90 +83,51 @@ get_cpu_manufacturer(char *buf, int len)
                strncpy(buf, "unknown", len);
 }
 
-
-/* Calculate the size of the SMBIOS structure table.
-*/
 static size_t
-smbios_table_size(uint32_t vcpus, const char *xen_version,
-                 const char *processor_manufacturer)
-{
-       size_t size;
-
-       /* first compute size without strings or terminating 0 bytes */
-       size =  sizeof(struct smbios_type_0) + sizeof(struct smbios_type_1) +
-               sizeof(struct smbios_type_3) + sizeof(struct 
smbios_type_4)*vcpus +
-               sizeof(struct smbios_type_16) + sizeof(struct smbios_type_17) +
-               sizeof(struct smbios_type_19) + sizeof(struct smbios_type_20) +
-               sizeof(struct smbios_type_32) + sizeof(struct smbios_type_127);
-
-       /* 5 structures with no strings, 2 null bytes each */
-       size += 10;
-
-       /* Need to include 1 null byte per structure with strings (first
-          terminating null byte comes from the string terminator of the
-          last string). */
-       size += 4 + vcpus;
-
-       /* type 0: "Xen", xen_version, and release_date */
-       size += strlen("Xen") + strlen(xen_version) + 2;
-       /* type 1: "Xen", xen_version, "HVM domU", UUID as string for 
-                   serial number */
-       size += strlen("Xen") + strlen("HVM domU") + strlen(xen_version) +
-                       36 + 4;
-       /* type 3: "Xen" */
-       size += strlen("Xen") + 1;
-       /* type 4: socket designation ("CPU n"), processor_manufacturer */
-       size += vcpus * (strlen("CPU n") + strlen(processor_manufacturer) + 2);
-       /* Make room for two-digit CPU numbers if necessary -- doesn't handle
-          vcpus > 99 */
-       if (vcpus > 9)
-               size += vcpus - 9;
-       /* type 17: device locator string ("DIMM 1") */
-       size += strlen("DIMM 1") + 1;
-
-       return size;
-}
-
-static size_t
-write_smbios_tables(void *start, size_t max_size,
+write_smbios_tables(void *start,
                    uint32_t vcpus, uint64_t memsize,
                    uint8_t uuid[16], char *xen_version,
                    uint32_t xen_major_version, uint32_t xen_minor_version)
 {
-       unsigned cpu_num;
-       void *p = start;
+       unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
+       char *p, *q;
        char cpu_manufacturer[15];
        size_t structure_table_length;
 
        get_cpu_manufacturer(cpu_manufacturer, 15);
 
-
-       structure_table_length = smbios_table_size(vcpus, xen_version,
-                                                  cpu_manufacturer);
-
-       if (structure_table_length + sizeof(struct smbios_entry_point) > 
max_size)
-               return 0;
-
-       p = smbios_entry_point_init(p, sizeof(struct smbios_type_4), 
-                                   structure_table_length,
-                                   (uint32_t)start + 
-                                   sizeof(struct smbios_entry_point),
-                                   9 + vcpus);
-
-       p = smbios_type_0_init(p, xen_version, xen_major_version,
-                              xen_minor_version);
-       p = smbios_type_1_init(p, xen_version, uuid);
-       p = smbios_type_3_init(p);
-       for (cpu_num = 1; cpu_num <= vcpus; ++cpu_num)
-               p = smbios_type_4_init(p, cpu_num, cpu_manufacturer);
-       p = smbios_type_16_init(p, memsize);
-       p = smbios_type_17_init(p, memsize);
-       p = smbios_type_19_init(p, memsize);
-       p = smbios_type_20_init(p, memsize);
-       p = smbios_type_32_init(p);
-       p = smbios_type_127_init(p);
-
-       return (size_t)((char*)p - (char*)start);
+       p = (char *)start + sizeof(struct smbios_entry_point);
+
+#define do_struct(fn) do {                     \
+       q = (fn);                               \
+       nr_structs++;                           \
+       if ((q - p) > max_struct_size)          \
+               max_struct_size = q - p;        \
+       p = q;                                  \
+} while (0)
+
+       do_struct(smbios_type_0_init(p, xen_version, xen_major_version,
+                                    xen_minor_version));
+       do_struct(smbios_type_1_init(p, xen_version, uuid));
+       do_struct(smbios_type_3_init(p));
+       for (cpu_num = 1; cpu_num <= vcpus; cpu_num++)
+               do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
+       do_struct(smbios_type_16_init(p, memsize));
+       do_struct(smbios_type_17_init(p, memsize));
+       do_struct(smbios_type_19_init(p, memsize));
+       do_struct(smbios_type_20_init(p, memsize));
+       do_struct(smbios_type_32_init(p));
+       do_struct(smbios_type_127_init(p));
+
+#undef do_struct
+
+       smbios_entry_point_init(
+               start, max_struct_size,
+               (p - (char *)start) - sizeof(struct smbios_entry_point),
+               SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
+               nr_structs);
+
+       return (size_t)((char *)p - (char *)start);
 }
 
 /* This tries to figure out how much pseudo-physical memory (in MB)
@@ -278,10 +232,16 @@ hvm_write_smbios_tables(void)
 
        xen_version_str[sizeof(xen_version_str)-1] = '\0';
 
-       write_smbios_tables((void *) SMBIOS_PHYSICAL_ADDRESS,
-                           SMBIOS_SIZE_LIMIT, get_vcpu_nr(), get_memsize(),
-                           uuid, xen_version_str,
-                           xen_major_version, xen_minor_version);
+       /* NB. 0xC0000 is a safe large memory area for scratch. */
+       len = write_smbios_tables((void *)0xC0000,
+                                 get_vcpu_nr(), get_memsize(),
+                                 uuid, xen_version_str,
+                                 xen_major_version, xen_minor_version);
+       if (len > SMBIOS_SIZE_LIMIT)
+               goto error_out;
+       /* Okay, not too large: copy out of scratch to final location. */
+       memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);
+
        return;
 
  error_out:
@@ -290,7 +250,7 @@ hvm_write_smbios_tables(void)
 }
 
 
-static void *
+static void
 smbios_entry_point_init(void *start,
                        uint16_t max_structure_size,
                        uint16_t structure_table_length,
@@ -327,8 +287,6 @@ smbios_entry_point_init(void *start,
        for (i = 0x10; i < ep->length; ++i)
                sum += ((int8_t *)start)[i];
        ep->intermediate_checksum = -sum;
-
-       return (char *)start + sizeof(struct smbios_entry_point);
 }
 
 /* Type 0 -- BIOS Information */
@@ -476,7 +434,7 @@ smbios_type_4_init(void *start, unsigned
        start += strlen(buf) + 1;
 
        strcpy((char *)start, cpu_manufacturer);
-       start += strlen(buf) + 1;
+       start += strlen(cpu_manufacturer) + 1;
 
        *((uint8_t *)start) = 0;
        return start+1;
@@ -597,7 +555,7 @@ smbios_type_32_init(void *start)
 }
 
 /* Type 127 -- End of Table */
-void *
+static void *
 smbios_type_127_init(void *start)
 {
        struct smbios_type_127 *p = (struct smbios_type_127 *)start;
diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/vmxassist/machine.h
--- a/tools/firmware/vmxassist/machine.h        Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/firmware/vmxassist/machine.h        Wed Oct 11 13:04:07 2006 -0400
@@ -36,6 +36,7 @@
 #define CR4_VME                (1 << 0)
 #define CR4_PVI                (1 << 1)
 #define CR4_PSE                (1 << 4)
+#define CR4_PAE                (1 << 5)
 
 #define EFLAGS_ZF      (1 << 6)
 #define EFLAGS_TF      (1 << 8)
diff -r e7cb3aefc233 -r b53c343b47ae tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/firmware/vmxassist/vm86.c   Wed Oct 11 13:04:07 2006 -0400
@@ -52,29 +52,63 @@ static char *rnames[] = { "ax", "cx", "d
 static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
 #endif /* DEBUG */
 
+#define PDE_PS           (1 << 7)
 #define PT_ENTRY_PRESENT 0x1
 
+/* We only support access to <=4G physical memory due to 1:1 mapping */
 static unsigned
-guest_linear_to_real(unsigned long base, unsigned off)
-{
-       unsigned int gcr3 = oldctx.cr3;
-       unsigned int l1_mfn;
-       unsigned int l0_mfn;
+guest_linear_to_real(uint32_t base)
+{
+       uint32_t gcr3 = oldctx.cr3;
+       uint64_t l2_mfn;
+       uint64_t l1_mfn;
+       uint64_t l0_mfn;
 
        if (!(oldctx.cr0 & CR0_PG))
-               return base + off;
-
-       l1_mfn = ((unsigned int *)gcr3)[(base >> 22) & 0x3ff ];
-       if (!(l1_mfn & PT_ENTRY_PRESENT))
-               panic("l2 entry not present\n");
-       l1_mfn = l1_mfn & 0xfffff000 ;
-
-       l0_mfn = ((unsigned int *)l1_mfn)[(base >> 12) & 0x3ff];
-       if (!(l0_mfn & PT_ENTRY_PRESENT))
-               panic("l1 entry not present\n");
-       l0_mfn = l0_mfn & 0xfffff000;
-
-       return l0_mfn + off + (base & 0xfff);
+               return base;
+
+       if (!(oldctx.cr4 & CR4_PAE)) {
+               l1_mfn = ((uint32_t *)(long)gcr3)[(base >> 22) & 0x3ff];
+               if (!(l1_mfn & PT_ENTRY_PRESENT))
+                       panic("l2 entry not present\n");
+
+               if ((oldctx.cr4 & CR4_PSE) && (l1_mfn & PDE_PS)) {
+                       l0_mfn = l1_mfn & 0xffc00000;
+                       return l0_mfn + (base & 0x3fffff);
+               }
+
+               l1_mfn &= 0xfffff000;
+
+               l0_mfn = ((uint32_t *)(long)l1_mfn)[(base >> 12) & 0x3ff];
+               if (!(l0_mfn & PT_ENTRY_PRESENT))
+                       panic("l1 entry not present\n");
+               l0_mfn &= 0xfffff000;
+
+               return l0_mfn + (base & 0xfff);
+       } else {
+               l2_mfn = ((uint64_t *)(long)gcr3)[(base >> 30) & 0x3];
+               if (!(l2_mfn & PT_ENTRY_PRESENT))
+                       panic("l3 entry not present\n");
+               l2_mfn &= 0x3fffff000ULL;
+
+               l1_mfn = ((uint64_t *)(long)l2_mfn)[(base >> 21) & 0x1ff];
+               if (!(l1_mfn & PT_ENTRY_PRESENT))
+                       panic("l2 entry not present\n");
+
+               if (l1_mfn & PDE_PS) { /* CR4.PSE is ignored in PAE mode */
+                       l0_mfn = l1_mfn & 0x3ffe00000ULL;
+                       return l0_mfn + (base & 0x1fffff);
+               }
+
+               l1_mfn &= 0x3fffff000ULL;
+
+               l0_mfn = ((uint64_t *)(long)l1_mfn)[(base >> 12) & 0x1ff];
+               if (!(l0_mfn & PT_ENTRY_PRESENT))
+                       panic("l1 entry not present\n");
+               l0_mfn &= 0x3fffff000ULL;
+
+               return l0_mfn + (base & 0xfff);
+       }
 }
 
 static unsigned
@@ -95,7 +129,8 @@ address(struct regs *regs, unsigned seg,
            (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
                return ((seg & 0xFFFF) << 4) + off;
 
-       entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 
0))[seg >> 3];
+       entry = ((unsigned long long *)
+                 guest_linear_to_real(oldctx.gdtr_base))[seg >> 3];
        entry_high = entry >> 32;
        entry_low = entry & 0xFFFFFFFF;
 
@@ -780,7 +815,8 @@ load_seg(unsigned long sel, uint32_t *ba
                return 1;
        }
 
-       entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 
0))[sel >> 3];
+       entry = ((unsigned long long *)
+                 guest_linear_to_real(oldctx.gdtr_base))[sel >> 3];
 
        /* Check the P bit first */
        if (!((entry >> (15+32)) & 0x1) && sel != 0)
@@ -1193,6 +1229,18 @@ pushrm(struct regs *regs, int prefix, un
 }
 
 enum { OPC_INVALID, OPC_EMULATED };
+
+#define rdmsr(msr,val1,val2)                           \
+       __asm__ __volatile__(                           \
+               "rdmsr"                                 \
+               : "=a" (val1), "=d" (val2)              \
+               : "c" (msr))
+
+#define wrmsr(msr,val1,val2)                           \
+       __asm__ __volatile__(                           \
+               "wrmsr"                                 \
+               : /* no outputs */                      \
+               : "c" (msr), "a" (val1), "d" (val2))
 
 /*
  * Emulate a single instruction, including all its prefixes. We only implement
@@ -1252,6 +1300,12 @@ opcode(struct regs *regs)
                                if (!movcr(regs, prefix, opc))
                                        goto invalid;
                                return OPC_EMULATED;
+                       case 0x30: /* WRMSR */
+                               wrmsr(regs->ecx, regs->eax, regs->edx);
+                               return OPC_EMULATED;
+                       case 0x32: /* RDMSR */
+                               rdmsr(regs->ecx, regs->eax, regs->edx);
+                               return OPC_EMULATED;
                        default:
                                goto invalid;
                        }
@@ -1376,12 +1430,14 @@ opcode(struct regs *regs)
                        {
                                int addr, data;
                                int seg = segment(prefix, regs, regs->vds);
+                               int offset = prefix & ADDR32? fetch32(regs) : 
fetch16(regs);
+
                                if (prefix & DATA32) {
-                                       addr = address(regs, seg, 
fetch32(regs));
+                                       addr = address(regs, seg, offset);
                                        data = read32(addr);
                                        setreg32(regs, 0, data);
                                } else {
-                                       addr = address(regs, seg, 
fetch16(regs));
+                                       addr = address(regs, seg, offset);
                                        data = read16(addr);
                                        setreg16(regs, 0, data);
                                }
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/hw/serial.c   Wed Oct 11 13:04:07 2006 -0400
@@ -22,6 +22,9 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#include <sys/time.h>
+#include <time.h>
+#include <assert.h>
 
 //#define DEBUG_SERIAL
 
@@ -138,6 +141,67 @@ static void serial_update_parameters(Ser
     printf("speed=%d parity=%c data=%d stop=%d\n", 
            speed, parity, data_bits, stop_bits);
 #endif
+}
+
+/* Rate limit serial requests so that e.g. grub on a serial console
+   doesn't kill dom0.  Simple token bucket.  If we get some actual
+   data from the user, instantly refil the bucket. */
+
+/* How long it takes to generate a token, in microseconds. */
+#define TOKEN_PERIOD 1000
+/* Maximum and initial size of token bucket */
+#define TOKENS_MAX 100000
+
+static int tokens_avail;
+
+static void serial_get_token(void)
+{
+    static struct timeval last_refil_time;
+    static int started;
+
+    assert(tokens_avail >= 0);
+    if (!tokens_avail) {
+       struct timeval delta, now;
+       int generated;
+
+       if (!started) {
+           gettimeofday(&last_refil_time, NULL);
+           tokens_avail = TOKENS_MAX;
+           started = 1;
+           return;
+       }
+    retry:
+       gettimeofday(&now, NULL);
+       delta.tv_sec = now.tv_sec - last_refil_time.tv_sec;
+       delta.tv_usec = now.tv_usec - last_refil_time.tv_usec;
+       if (delta.tv_usec < 0) {
+           delta.tv_usec += 1000000;
+           delta.tv_sec--;
+       }
+       assert(delta.tv_usec >= 0 && delta.tv_sec >= 0);
+       if (delta.tv_usec < TOKEN_PERIOD) {
+           struct timespec ts;
+           /* Wait until at least one token is available. */
+           ts.tv_sec = TOKEN_PERIOD / 1000000;
+           ts.tv_nsec = (TOKEN_PERIOD % 1000000) * 1000;
+           while (nanosleep(&ts, &ts) < 0 && errno == EINTR)
+               ;
+           goto retry;
+       }
+       generated = (delta.tv_sec * 1000000) / TOKEN_PERIOD;
+       generated +=
+           ((delta.tv_sec * 1000000) % TOKEN_PERIOD + delta.tv_usec) / 
TOKEN_PERIOD;
+       assert(generated > 0);
+
+       last_refil_time.tv_usec += (generated * TOKEN_PERIOD) % 1000000;
+       last_refil_time.tv_sec  += last_refil_time.tv_usec / 1000000;
+       last_refil_time.tv_usec %= 1000000;
+       last_refil_time.tv_sec  += (generated * TOKEN_PERIOD) / 1000000;
+       if (generated > TOKENS_MAX)
+           generated = TOKENS_MAX;
+       tokens_avail = generated;
+    }
+    tokens_avail--;
 }
 
 static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
@@ -245,9 +309,11 @@ static uint32_t serial_ioport_read(void 
         ret = s->mcr;
         break;
     case 5:
+       serial_get_token();
         ret = s->lsr;
         break;
     case 6:
+       serial_get_token();
         if (s->mcr & UART_MCR_LOOP) {
             /* in loopback, the modem output pins are connected to the
                inputs */
@@ -296,12 +362,14 @@ static void serial_receive1(void *opaque
 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
 {
     SerialState *s = opaque;
+    tokens_avail = TOKENS_MAX;
     serial_receive_byte(s, buf[0]);
 }
 
 static void serial_event(void *opaque, int event)
 {
     SerialState *s = opaque;
+    tokens_avail = TOKENS_MAX;
     if (event == CHR_EVENT_BREAK)
         serial_receive_break(s);
 }
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/hw/vga.c      Wed Oct 11 13:04:07 2006 -0400
@@ -1463,14 +1463,15 @@ void check_sse2(void)
  */
 static void vga_draw_graphic(VGAState *s, int full_update)
 {
-    int y1, y, update, page_min, page_max, linesize, y_start, double_scan, 
mask;
+    int y1, y, update, linesize, y_start, double_scan, mask;
     int width, height, shift_control, line_offset, bwidth;
     ram_addr_t page0, page1;
     int disp_width, multi_scan, multi_run;
     uint8_t *d;
     uint32_t v, addr1, addr;
     vga_draw_line_func *vga_draw_line;
-    
+    ram_addr_t page_min, page_max;
+
     full_update |= update_basic_params(s);
 
     s->get_resolution(s, &width, &height);
@@ -1561,8 +1562,8 @@ static void vga_draw_graphic(VGAState *s
     addr1 = (s->start_addr * 4);
     bwidth = width * 4;
     y_start = -1;
-    page_min = 0x7fffffff;
-    page_max = -1;
+    page_min = 0;
+    page_max = 0;
     d = s->ds->data;
     linesize = s->ds->linesize;
     y1 = 0;
@@ -1592,9 +1593,9 @@ static void vga_draw_graphic(VGAState *s
         if (update) {
             if (y_start < 0)
                 y_start = y;
-            if (page0 < page_min)
+            if (page_min == 0 || page0 < page_min)
                 page_min = page0;
-            if (page1 > page_max)
+            if (page_max == 0 || page1 > page_max)
                 page_max = page1;
             vga_draw_line(s, d, s->vram_ptr + addr, width);
             if (s->cursor_draw_line)
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/hw/xen_platform.c
--- a/tools/ioemu/hw/xen_platform.c     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/hw/xen_platform.c     Wed Oct 11 13:04:07 2006 -0400
@@ -116,10 +116,10 @@ void pci_xen_platform_init(PCIBus *bus)
     d = pci_register_device(bus, "xen-platform", sizeof(PCIDevice), -1, NULL,
                            NULL);
     pch = (struct pci_config_header *)d->config;
-    pch->vendor_id = 0xfffd;
-    pch->device_id = 0x0101;
+    pch->vendor_id = 0x5853;
+    pch->device_id = 0x0001;
     pch->command = 3; /* IO and memory access */
-    pch->revision = 0;
+    pch->revision = 1;
     pch->api = 0;
     pch->subclass = 0x80; /* Other */
     pch->class = 0xff; /* Unclassified device class */
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/domain-timeoffset
--- a/tools/ioemu/patches/domain-timeoffset     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/domain-timeoffset     Wed Oct 11 13:04:07 2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/hw/mc146818rtc.c
 Index: ioemu/hw/mc146818rtc.c
 ===================================================================
---- ioemu.orig/hw/mc146818rtc.c        2006-08-17 19:58:03.222720593 +0100
-+++ ioemu/hw/mc146818rtc.c     2006-08-17 19:58:08.528134087 +0100
+--- ioemu.orig/hw/mc146818rtc.c        2006-09-21 19:33:25.000000000 +0100
++++ ioemu/hw/mc146818rtc.c     2006-09-21 19:33:30.000000000 +0100
 @@ -178,10 +178,27 @@
      }
  }
@@ -46,8 +46,8 @@ Index: ioemu/hw/mc146818rtc.c
  static void rtc_copy_date(RTCState *s)
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-17 19:58:08.252164595 +0100
-+++ ioemu/hw/pc.c      2006-08-17 19:58:08.529133976 +0100
+--- ioemu.orig/hw/pc.c 2006-09-21 19:33:30.000000000 +0100
++++ ioemu/hw/pc.c      2006-09-21 19:33:30.000000000 +0100
 @@ -159,7 +159,7 @@
  }
  
@@ -117,8 +117,8 @@ Index: ioemu/hw/pc.c
  QEMUMachine pc_machine = {
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:58:08.395148788 +0100
-+++ ioemu/vl.c 2006-08-17 19:58:08.532133645 +0100
+--- ioemu.orig/vl.c    2006-09-21 19:33:30.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:33:30.000000000 +0100
 @@ -163,6 +163,8 @@
  
  int xc_handle;
@@ -174,8 +174,8 @@ Index: ioemu/vl.c
      if (usb_enabled) {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:58:08.257164042 +0100
-+++ ioemu/vl.h 2006-08-17 19:58:08.532133645 +0100
+--- ioemu.orig/vl.h    2006-09-21 19:33:30.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:33:30.000000000 +0100
 @@ -576,7 +576,7 @@
                                   int boot_device,
               DisplayState *ds, const char **fd_filename, int snapshot,
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-bootorder
--- a/tools/ioemu/patches/qemu-bootorder        Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/qemu-bootorder        Wed Oct 11 13:04:07 2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-20 22:22:36.000000000 +0100
-+++ ioemu/vl.c 2006-08-20 23:22:25.000000000 +0100
+--- ioemu.orig/vl.c    2006-09-21 19:33:32.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100
 @@ -124,7 +124,7 @@
  int vncunused;
  const char* keyboard_layout = NULL;
@@ -11,7 +11,7 @@ Index: ioemu/vl.c
  uint64_t ram_size;
  int pit_min_timer_count = 0;
  int nb_nics;
-@@ -6057,14 +6057,14 @@
+@@ -6063,14 +6063,14 @@
                  break;
  #endif /* !CONFIG_DM */
              case QEMU_OPTION_boot:
@@ -32,7 +32,7 @@ Index: ioemu/vl.c
                      exit(1);
                  }
                  break;
-@@ -6328,6 +6328,7 @@
+@@ -6334,6 +6334,7 @@
          fd_filename[0] == '\0')
          help();
      
@@ -40,7 +40,7 @@ Index: ioemu/vl.c
      /* boot to cd by default if no hard disk */
      if (hd_filename[0] == '\0' && boot_device == 'c') {
          if (fd_filename[0] != '\0')
-@@ -6335,6 +6336,7 @@
+@@ -6341,6 +6342,7 @@
          else
              boot_device = 'd';
      }
@@ -48,7 +48,7 @@ Index: ioemu/vl.c
  #endif /* !CONFIG_DM */
  
      setvbuf(stdout, NULL, _IOLBF, 0);
-@@ -6593,6 +6595,7 @@
+@@ -6599,6 +6601,7 @@
                    ds, fd_filename, snapshot,
                    kernel_filename, kernel_cmdline, initrd_filename,
                    timeoffset);
@@ -58,9 +58,9 @@ Index: ioemu/vl.c
      if (usb_enabled) {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-20 22:22:36.000000000 +0100
-+++ ioemu/vl.h 2006-08-20 23:22:25.000000000 +0100
-@@ -575,7 +575,7 @@
+--- ioemu.orig/vl.h    2006-09-21 19:33:32.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:33:32.000000000 +0100
+@@ -576,7 +576,7 @@
  #ifndef QEMU_TOOL
  
  typedef void QEMUMachineInitFunc(uint64_t ram_size, int vga_ram_size, 
@@ -69,7 +69,7 @@ Index: ioemu/vl.h
               DisplayState *ds, const char **fd_filename, int snapshot,
               const char *kernel_filename, const char *kernel_cmdline,
               const char *initrd_filename, time_t timeoffset);
-@@ -1020,7 +1020,7 @@
+@@ -1021,7 +1021,7 @@
                      uint32_t start, uint32_t count);
  int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
                            const unsigned char *arch,
@@ -80,8 +80,8 @@ Index: ioemu/vl.h
                            uint32_t initrd_image, uint32_t initrd_size,
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-20 22:22:36.000000000 +0100
-+++ ioemu/hw/pc.c      2006-08-20 23:27:55.000000000 +0100
+--- ioemu.orig/hw/pc.c 2006-09-21 19:33:32.000000000 +0100
++++ ioemu/hw/pc.c      2006-09-21 19:33:32.000000000 +0100
 @@ -158,8 +158,23 @@
      rtc_set_memory(s, info_ofs + 8, sectors);
  }
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-daemonize
--- a/tools/ioemu/patches/qemu-daemonize        Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/qemu-daemonize        Wed Oct 11 13:04:07 2006 -0400
@@ -2,9 +2,9 @@ Changes required because qemu-dm runs da
 
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-16 15:11:32.575865776 +0100
-+++ ioemu/vl.c 2006-08-16 15:11:36.217465702 +0100
-@@ -6036,10 +6036,11 @@
+--- ioemu.orig/vl.c    2006-09-21 19:33:32.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100
+@@ -6042,10 +6042,11 @@
                  }
                  break;
              case QEMU_OPTION_nographic:
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-pci
--- a/tools/ioemu/patches/qemu-pci      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/qemu-pci      Wed Oct 11 13:04:07 2006 -0400
@@ -1,7 +1,8 @@ diff -r d5eb5205ff35 tools/ioemu/hw/pci.
-diff -r d5eb5205ff35 tools/ioemu/hw/pci.c
---- a/tools/ioemu/hw/pci.c     Thu Aug 24 16:25:49 2006 +0100
-+++ b/tools/ioemu/hw/pci.c     Fri Aug 25 11:00:03 2006 +0800
-@@ -286,6 +286,7 @@ void pci_default_write_config(PCIDevice 
+Index: ioemu/hw/pci.c
+===================================================================
+--- ioemu.orig/hw/pci.c        2006-09-21 11:31:14.000000000 +0100
++++ ioemu/hw/pci.c     2006-09-21 11:31:32.000000000 +0100
+@@ -286,6 +286,7 @@
              case 0x0b:
              case 0x0e:
              case 0x10 ... 0x27: /* base */
@@ -9,7 +10,7 @@ diff -r d5eb5205ff35 tools/ioemu/hw/pci.
              case 0x30 ... 0x33: /* rom */
              case 0x3d:
                  can_write = 0;
-@@ -318,6 +319,18 @@ void pci_default_write_config(PCIDevice 
+@@ -318,6 +319,18 @@
              break;
          }
          if (can_write) {
@@ -28,10 +29,11 @@ diff -r d5eb5205ff35 tools/ioemu/hw/pci.
              d->config[addr] = val;
          }
          addr++;
-diff -r d5eb5205ff35 tools/ioemu/hw/rtl8139.c
---- a/tools/ioemu/hw/rtl8139.c Thu Aug 24 16:25:49 2006 +0100
-+++ b/tools/ioemu/hw/rtl8139.c Fri Aug 25 11:00:03 2006 +0800
-@@ -3423,6 +3423,8 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
+Index: ioemu/hw/rtl8139.c
+===================================================================
+--- ioemu.orig/hw/rtl8139.c    2006-09-21 11:31:14.000000000 +0100
++++ ioemu/hw/rtl8139.c 2006-09-21 11:31:32.000000000 +0100
+@@ -3423,6 +3423,8 @@
      pci_conf[0x0e] = 0x00; /* header_type */
      pci_conf[0x3d] = 1;    /* interrupt pin 0 */
      pci_conf[0x34] = 0xdc;
@@ -40,10 +42,11 @@ diff -r d5eb5205ff35 tools/ioemu/hw/rtl8
  
      s = &d->rtl8139;
  
-diff -r d5eb5205ff35 tools/ioemu/hw/usb-uhci.c
---- a/tools/ioemu/hw/usb-uhci.c        Thu Aug 24 16:25:49 2006 +0100
-+++ b/tools/ioemu/hw/usb-uhci.c        Fri Aug 25 11:00:03 2006 +0800
-@@ -659,6 +659,8 @@ void usb_uhci_init(PCIBus *bus, int devf
+Index: ioemu/hw/usb-uhci.c
+===================================================================
+--- ioemu.orig/hw/usb-uhci.c   2006-09-21 11:31:14.000000000 +0100
++++ ioemu/hw/usb-uhci.c        2006-09-21 11:31:32.000000000 +0100
+@@ -659,6 +659,8 @@
      pci_conf[0x0e] = 0x00; // header_type
      pci_conf[0x3d] = 4; // interrupt pin 3
      pci_conf[0x60] = 0x10; // release number
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/qemu-target-i386-dm
--- a/tools/ioemu/patches/qemu-target-i386-dm   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/qemu-target-i386-dm   Wed Oct 11 13:04:07 2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-08-08 11:24:33.479955101 +0100
-+++ ioemu/Makefile.target      2006-08-08 11:24:39.008338255 +0100
+--- ioemu.orig/Makefile.target 2006-09-21 11:30:11.000000000 +0100
++++ ioemu/Makefile.target      2006-09-21 18:54:22.000000000 +0100
 @@ -62,6 +62,8 @@
  QEMU_SYSTEM=qemu-fast
  endif
@@ -32,8 +32,8 @@ Index: ioemu/Makefile.target
  DEFINES += -DHAS_AUDIO
 Index: ioemu/configure
 ===================================================================
---- ioemu.orig/configure       2006-08-08 11:24:33.480954990 +0100
-+++ ioemu/configure    2006-08-08 11:24:38.122437102 +0100
+--- ioemu.orig/configure       2006-09-21 11:30:11.000000000 +0100
++++ ioemu/configure    2006-09-21 18:54:21.000000000 +0100
 @@ -373,6 +373,8 @@
      if [ "$user" = "yes" ] ; then
          target_list="i386-user arm-user armeb-user sparc-user ppc-user 
mips-user mipsel-user $target_list"
@@ -45,8 +45,8 @@ Index: ioemu/configure
  fi
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-08-08 11:24:33.484954543 +0100
-+++ ioemu/monitor.c    2006-08-08 11:24:39.253310921 +0100
+--- ioemu.orig/monitor.c       2006-09-21 11:30:11.000000000 +0100
++++ ioemu/monitor.c    2006-09-21 18:54:23.000000000 +0100
 @@ -1262,6 +1262,10 @@
        "", "show profiling information", },
      { "capture", "", do_info_capture,
@@ -60,8 +60,8 @@ Index: ioemu/monitor.c
  
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-08 11:24:33.486954320 +0100
-+++ ioemu/vl.c 2006-08-08 11:24:39.454288496 +0100
+--- ioemu.orig/vl.c    2006-09-21 11:30:11.000000000 +0100
++++ ioemu/vl.c 2006-09-21 18:54:23.000000000 +0100
 @@ -87,7 +87,7 @@
  
  #include "exec-all.h"
@@ -98,8 +98,8 @@ Index: ioemu/vl.c
  {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-08 11:24:31.082222636 +0100
-+++ ioemu/vl.h 2006-08-08 11:24:39.454288496 +0100
+--- ioemu.orig/vl.h    2006-09-21 11:30:11.000000000 +0100
++++ ioemu/vl.h 2006-09-21 18:54:23.000000000 +0100
 @@ -37,6 +37,8 @@
  #include <unistd.h>
  #include <fcntl.h>
@@ -132,7 +132,7 @@ Index: ioemu/target-i386-dm/cpu.h
 Index: ioemu/target-i386-dm/cpu.h
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/cpu.h 2006-08-08 11:24:39.099328102 +0100
++++ ioemu/target-i386-dm/cpu.h 2006-09-21 18:54:22.000000000 +0100
 @@ -0,0 +1,86 @@
 +/*
 + * i386 virtual CPU header
@@ -223,7 +223,7 @@ Index: ioemu/target-i386-dm/exec-dm.c
 Index: ioemu/target-i386-dm/exec-dm.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/exec-dm.c     2006-08-08 11:24:39.099328102 +0100
++++ ioemu/target-i386-dm/exec-dm.c     2006-09-21 18:54:22.000000000 +0100
 @@ -0,0 +1,516 @@
 +/*
 + *  virtual page mapping and translated block handling
@@ -744,7 +744,7 @@ Index: ioemu/target-i386-dm/helper2.c
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/helper2.c     2006-08-08 11:24:44.888682140 +0100
++++ ioemu/target-i386-dm/helper2.c     2006-09-21 18:55:31.000000000 +0100
 @@ -0,0 +1,469 @@
 +/*
 + *  i386 helpers (without register variable usage)
@@ -1205,8 +1205,8 @@ Index: ioemu/target-i386-dm/helper2.c
 +                break;
 +        }
 +
-+        /* Wait up to 10 msec. */
-+        main_loop_wait(10);
++        /* Wait up to 100 msec. */
++        main_loop_wait(100);
 +
 +        if (env->send_event) {
 +            env->send_event = 0;
@@ -1218,7 +1218,7 @@ Index: ioemu/target-i386-dm/i8259-dm.c
 Index: ioemu/target-i386-dm/i8259-dm.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/i8259-dm.c    2006-08-08 11:24:33.505952200 +0100
++++ ioemu/target-i386-dm/i8259-dm.c    2006-09-21 11:30:11.000000000 +0100
 @@ -0,0 +1,107 @@
 +/* Xen 8259 stub for interrupt controller emulation
 + * 
@@ -1330,7 +1330,7 @@ Index: ioemu/target-i386-dm/qemu-dm.debu
 Index: ioemu/target-i386-dm/qemu-dm.debug
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/qemu-dm.debug 2006-08-08 11:24:33.505952200 +0100
++++ ioemu/target-i386-dm/qemu-dm.debug 2006-09-21 11:30:11.000000000 +0100
 @@ -0,0 +1,5 @@
 +#!/bin/sh
 +
@@ -1340,7 +1340,7 @@ Index: ioemu/target-i386-dm/qemu-ifup
 Index: ioemu/target-i386-dm/qemu-ifup
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/target-i386-dm/qemu-ifup     2006-08-08 11:24:33.505952200 +0100
++++ ioemu/target-i386-dm/qemu-ifup     2006-09-21 11:30:11.000000000 +0100
 @@ -0,0 +1,10 @@
 +#!/bin/sh
 +
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/series
--- a/tools/ioemu/patches/series        Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/series        Wed Oct 11 13:04:07 2006 -0400
@@ -29,12 +29,14 @@ acpi-support
 acpi-support
 acpi-timer-support
 acpi-poweroff-support
+fix-vga-scanning-code-overflow
 vnc-cleanup
 vnc-fixes
 vnc-start-vncviewer
 vnc-title-domain-name
 vnc-access-monitor-vt
 vnc-display-find-unused
+vnc-backoff-screen-scan
 xenstore-block-device-config
 xenstore-write-vnc-port
 qemu-allow-disable-sdl
@@ -44,4 +46,4 @@ xen-platform-device
 xen-platform-device
 qemu-bootorder
 qemu-tunable-ide-write-cache
-qemu-pci -p3
+qemu-pci 
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-access-monitor-vt
--- a/tools/ioemu/patches/vnc-access-monitor-vt Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/vnc-access-monitor-vt Wed Oct 11 13:04:07 2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-08-17 19:50:14.623519661 +0100
-+++ ioemu/vnc.c        2006-08-17 19:50:15.956372339 +0100
+--- ioemu.orig/vnc.c   2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vnc.c        2006-09-21 19:33:31.000000000 +0100
 @@ -32,6 +32,10 @@
  #include "vnc_keysym.h"
  #include "keymaps.c"
@@ -22,7 +22,7 @@ Index: ioemu/vnc.c
  };
  
  #define DIRTY_PIXEL_BITS 64
-@@ -794,16 +800,80 @@
+@@ -791,16 +797,80 @@
  
  static void do_key_event(VncState *vs, int down, uint32_t sym)
  {
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-cleanup
--- a/tools/ioemu/patches/vnc-cleanup   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/vnc-cleanup   Wed Oct 11 13:04:07 2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-08-17 19:37:36.091553839 +0100
-+++ ioemu/vnc.c        2006-08-17 19:50:10.313996001 +0100
+--- ioemu.orig/vnc.c   2006-09-21 18:54:22.000000000 +0100
++++ ioemu/vnc.c        2006-09-21 19:05:39.000000000 +0100
 @@ -143,13 +143,16 @@
  static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
  {
@@ -30,7 +30,16 @@ Index: ioemu/vnc.c
  
      if (vs->need_update && vs->csock != -1) {
        int y;
-@@ -390,7 +394,7 @@
+@@ -383,6 +387,8 @@
+       int saved_offset;
+       int has_dirty = 0;
+ 
++      qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
++
+         vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
+ 
+       /* Walk through the dirty map and eliminate tiles that
+@@ -390,7 +396,7 @@
        row = vs->ds->data;
        old_row = vs->old_data;
  
@@ -39,34 +48,50 @@ Index: ioemu/vnc.c
            if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
                int x;
                char *ptr, *old_ptr;
-@@ -415,10 +419,8 @@
+@@ -415,10 +421,8 @@
            old_row += vs->ds->linesize;
        }
  
 -      if (!has_dirty) {
 -          qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + 
VNC_REFRESH_INTERVAL);
--          return;
++      if (!has_dirty)
+           return;
 -      }
-+      if (!has_dirty)
-+          goto out;
  
        /* Count rectangles */
        n_rectangles = 0;
-@@ -456,7 +458,9 @@
+@@ -454,17 +458,13 @@
+       vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
+       vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
        vnc_flush(vs);
- 
+-
      }
 -    qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + 
VNC_REFRESH_INTERVAL);
-+
-+ out:
-+    qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
  }
  
  static void vnc_timer_init(VncState *vs)
+ {
+-    if (vs->timer == NULL) {
++    if (vs->timer == NULL)
+       vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
+-      qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
+-    }
+ }
+ 
+ static void vnc_dpy_refresh(DisplayState *ds)
+@@ -736,6 +736,8 @@
+           old_row += vs->ds->linesize;
+       }
+     }
++
++    qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
+ }
+ 
+ static void set_encodings(VncState *vs, int32_t *encodings, size_t 
n_encodings)
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:50:02.410869542 +0100
-+++ ioemu/vl.c 2006-08-17 19:50:10.316995669 +0100
+--- ioemu.orig/vl.c    2006-09-21 18:55:38.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:00:48.000000000 +0100
 @@ -5120,10 +5120,10 @@
          /* XXX: better handling of removal */
          for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-display-find-unused
--- a/tools/ioemu/patches/vnc-display-find-unused       Wed Oct 11 13:01:31 
2006 -0400
+++ b/tools/ioemu/patches/vnc-display-find-unused       Wed Oct 11 13:04:07 
2006 -0400
@@ -1,8 +1,8 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-08-17 19:50:15.956372339 +0100
-+++ ioemu/vnc.c        2006-08-17 19:50:17.083247783 +0100
-@@ -1183,7 +1183,7 @@
+--- ioemu.orig/vnc.c   2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vnc.c        2006-09-21 19:33:31.000000000 +0100
+@@ -1182,7 +1182,7 @@
      }
  }
  
@@ -11,7 +11,7 @@ Index: ioemu/vnc.c
  {
      struct sockaddr_in addr;
      int reuse_addr, ret;
-@@ -1214,10 +1214,6 @@
+@@ -1213,10 +1213,6 @@
        exit(1);
      }
  
@@ -22,7 +22,7 @@ Index: ioemu/vnc.c
      reuse_addr = 1;
      ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
                     (const char *)&reuse_addr, sizeof(reuse_addr));
-@@ -1226,7 +1222,16 @@
+@@ -1225,7 +1221,16 @@
        exit(1);
      }
  
@@ -39,7 +39,7 @@ Index: ioemu/vnc.c
        fprintf(stderr, "bind() failed\n");
        exit(1);
      }
-@@ -1247,6 +1252,8 @@
+@@ -1246,6 +1251,8 @@
      vs->ds->dpy_refresh = vnc_dpy_refresh;
  
      vnc_dpy_resize(vs->ds, 640, 400);
@@ -50,8 +50,8 @@ Index: ioemu/vnc.c
  int vnc_start_viewer(int port)
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:50:13.152682236 +0100
-+++ ioemu/vl.c 2006-08-17 19:50:17.086247452 +0100
+--- ioemu.orig/vl.c    2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:33:31.000000000 +0100
 @@ -121,6 +121,7 @@
  static DisplayState display_state;
  int nographic;
@@ -115,8 +115,8 @@ Index: ioemu/vl.c
      } else {
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:50:13.153682125 +0100
-+++ ioemu/vl.h 2006-08-17 19:50:17.087247341 +0100
+--- ioemu.orig/vl.h    2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:33:31.000000000 +0100
 @@ -785,7 +785,7 @@
  void cocoa_display_init(DisplayState *ds, int full_screen);
  
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-fixes
--- a/tools/ioemu/patches/vnc-fixes     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/vnc-fixes     Wed Oct 11 13:04:07 2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:50:10.316995669 +0100
-+++ ioemu/vl.c 2006-08-17 19:50:12.100798502 +0100
+--- ioemu.orig/vl.c    2006-09-21 19:08:18.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:26:24.000000000 +0100
 @@ -6534,8 +6534,10 @@
          }
      }
@@ -17,8 +17,8 @@ Index: ioemu/vl.c
      if (use_gdbstub) {
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-08-17 19:50:10.313996001 +0100
-+++ ioemu/vnc.c        2006-08-17 19:50:12.101798392 +0100
+--- ioemu.orig/vnc.c   2006-09-21 19:08:18.000000000 +0100
++++ ioemu/vnc.c        2006-09-21 19:26:38.000000000 +0100
 @@ -3,6 +3,7 @@
   * 
   * Copyright (C) 2006 Anthony Liguori <anthony@xxxxxxxxxxxxx>
@@ -240,7 +240,7 @@ Index: ioemu/vnc.c
  {
      VncState *vs = opaque;
      int64_t now = qemu_get_clock(rt_clock);
-@@ -382,12 +445,16 @@
+@@ -382,14 +445,18 @@
        int y;
        char *row;
        char *old_row;
@@ -252,6 +252,8 @@ Index: ioemu/vnc.c
 +      int maxx, maxy;
 +      int tile_bytes = vs->depth * DP2X(vs, 1);
  
+       qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
+ 
 -        vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
 +      if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
 +          width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
@@ -260,7 +262,7 @@ Index: ioemu/vnc.c
  
        /* Walk through the dirty map and eliminate tiles that
           really aren't dirty */
-@@ -395,23 +462,25 @@
+@@ -397,23 +464,25 @@
        old_row = vs->old_data;
  
        for (y = 0; y < vs->ds->height; y++) {
@@ -295,17 +297,17 @@ Index: ioemu/vnc.c
                }
            }
  
-@@ -419,7 +488,8 @@
+@@ -421,7 +490,8 @@
            old_row += vs->ds->linesize;
        }
  
 -      if (!has_dirty)
 +      if (!vs->has_update || vs->visible_y >= vs->ds->height ||
 +          vs->visible_x >= vs->ds->width)
-           goto out;
+           return;
  
        /* Count rectangles */
-@@ -429,40 +499,61 @@
+@@ -431,34 +501,56 @@
        saved_offset = vs->output.offset;
        vnc_write_u16(vs, 0);
  
@@ -354,32 +356,26 @@ Index: ioemu/vnc.c
        }
        vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
        vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
--      vnc_flush(vs);
- 
--    }
++
 +      vs->has_update = 0;
 +      vs->need_update = 0;
-+      vnc_flush(vs);
+       vnc_flush(vs);
+-    }
 +      vs->slow_client = 0;
 +    } else
 +      vs->slow_client = 1;
- 
-  out:
-     qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
- }
- 
++}
++
 +static void vnc_update_client(void *opaque)
 +{
 +    VncState *vs = opaque;
 +
 +    vs->ds->dpy_refresh(vs->ds);
 +    _vnc_update_client(vs);
-+}
-+
+ }
+ 
  static void vnc_timer_init(VncState *vs)
- {
-     if (vs->timer == NULL) {
-@@ -473,8 +564,6 @@
+@@ -469,8 +561,6 @@
  
  static void vnc_dpy_refresh(DisplayState *ds)
  {
@@ -388,7 +384,7 @@ Index: ioemu/vnc.c
      vga_hw_update();
  }
  
-@@ -510,7 +599,7 @@
+@@ -506,7 +596,7 @@
  
  static void buffer_reset(Buffer *buffer)
  {
@@ -397,7 +393,7 @@ Index: ioemu/vnc.c
  }
  
  static void buffer_append(Buffer *buffer, const void *data, size_t len)
-@@ -551,12 +640,12 @@
+@@ -547,12 +637,12 @@
      if (!ret)
        return;
  
@@ -413,7 +409,7 @@ Index: ioemu/vnc.c
  }
  
  static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-@@ -588,11 +677,11 @@
+@@ -584,11 +674,11 @@
            return;
  
        if (!ret) {
@@ -428,7 +424,7 @@ Index: ioemu/vnc.c
      }
  }
  
-@@ -600,9 +689,9 @@
+@@ -596,9 +686,9 @@
  {
      buffer_reserve(&vs->output, len);
  
@@ -441,7 +437,7 @@ Index: ioemu/vnc.c
  
      buffer_append(&vs->output, data, len);
  }
-@@ -724,22 +813,25 @@
+@@ -720,22 +810,25 @@
      do_key_event(vs, down, sym);
  }
  
@@ -475,10 +471,10 @@ Index: ioemu/vnc.c
 +    vs->visible_y = y_position;
 +    vs->visible_w = w;
 +    vs->visible_h = h;
- }
- 
- static void set_encodings(VncState *vs, int32_t *encodings, size_t 
n_encodings)
-@@ -845,8 +937,6 @@
+ 
+     qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
+ }
+@@ -843,8 +936,6 @@
      }
  
      vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
@@ -487,7 +483,7 @@ Index: ioemu/vnc.c
  
      vga_hw_invalidate();
      vga_hw_update();
-@@ -1012,11 +1102,11 @@
+@@ -1010,11 +1101,11 @@
        vnc_write(vs, "RFB 003.003\n", 12);
        vnc_flush(vs);
        vnc_read_when(vs, protocol_version, 12);
@@ -501,7 +497,7 @@ Index: ioemu/vnc.c
      }
  }
  
-@@ -1073,17 +1163,15 @@
+@@ -1071,17 +1162,15 @@
        exit(1);
      }
  
@@ -524,8 +520,8 @@ Index: ioemu/vnc.c
  }
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:50:02.411869432 +0100
-+++ ioemu/vl.h 2006-08-17 19:50:12.102798281 +0100
+--- ioemu.orig/vl.h    2006-09-21 19:00:48.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:26:24.000000000 +0100
 @@ -319,6 +319,7 @@
  int is_graphic_console(void);
  CharDriverState *text_console_init(DisplayState *ds);
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-start-vncviewer
--- a/tools/ioemu/patches/vnc-start-vncviewer   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/vnc-start-vncviewer   Wed Oct 11 13:04:07 2006 -0400
@@ -1,8 +1,8 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-08-17 19:50:12.101798392 +0100
-+++ ioemu/vnc.c        2006-08-17 19:50:13.149682567 +0100
-@@ -1175,3 +1175,25 @@
+--- ioemu.orig/vnc.c   2006-09-21 19:26:38.000000000 +0100
++++ ioemu/vnc.c        2006-09-21 19:29:58.000000000 +0100
+@@ -1174,3 +1174,25 @@
  
      vnc_dpy_resize(vs->ds, 640, 400);
  }
@@ -20,7 +20,7 @@ Index: ioemu/vnc.c
 +      exit(1);
 +
 +    case 0:   /* child */
-+      execlp("vncviewer", "vncviewer", s, 0);
++      execlp("vncviewer", "vncviewer", s, NULL);
 +      fprintf(stderr, "vncviewer execlp failed\n");
 +      exit(1);
 +
@@ -30,8 +30,8 @@ Index: ioemu/vnc.c
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:50:12.100798502 +0100
-+++ ioemu/vl.c 2006-08-17 19:50:13.152682236 +0100
+--- ioemu.orig/vl.c    2006-09-21 19:26:24.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:29:50.000000000 +0100
 @@ -120,6 +120,7 @@
  int bios_size;
  static DisplayState display_state;
@@ -93,8 +93,8 @@ Index: ioemu/vl.c
          sdl_display_init(ds, full_screen);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:50:12.102798281 +0100
-+++ ioemu/vl.h 2006-08-17 19:50:13.153682125 +0100
+--- ioemu.orig/vl.h    2006-09-21 19:26:24.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:29:50.000000000 +0100
 @@ -786,6 +786,7 @@
  
  /* vnc.c */
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/vnc-title-domain-name
--- a/tools/ioemu/patches/vnc-title-domain-name Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/vnc-title-domain-name Wed Oct 11 13:04:07 2006 -0400
@@ -1,8 +1,8 @@ Index: ioemu/vnc.c
 Index: ioemu/vnc.c
 ===================================================================
---- ioemu.orig/vnc.c   2006-08-17 19:50:13.149682567 +0100
-+++ ioemu/vnc.c        2006-08-17 19:50:14.623519661 +0100
-@@ -1014,6 +1014,7 @@
+--- ioemu.orig/vnc.c   2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vnc.c        2006-09-21 19:33:31.000000000 +0100
+@@ -1013,6 +1013,7 @@
  
  static int protocol_client_init(VncState *vs, char *data, size_t len)
  {
@@ -10,7 +10,7 @@ Index: ioemu/vnc.c
      char pad[3] = { 0, 0, 0 };
  
      vs->width = vs->ds->width;
-@@ -1059,8 +1060,10 @@
+@@ -1058,8 +1059,10 @@
        
      vnc_write(vs, pad, 3);           /* padding */
  
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/xen-platform-device
--- a/tools/ioemu/patches/xen-platform-device   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/patches/xen-platform-device   Wed Oct 11 13:04:07 2006 -0400
@@ -3,8 +3,8 @@ will come later.
 
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-08-17 19:50:18.866050726 +0100
-+++ ioemu/Makefile.target      2006-08-17 19:55:35.776020218 +0100
+--- ioemu.orig/Makefile.target 2006-09-21 19:33:31.000000000 +0100
++++ ioemu/Makefile.target      2006-09-21 19:33:32.000000000 +0100
 @@ -359,6 +359,7 @@
  VL_OBJS+= usb-uhci.o
  VL_OBJS+= piix4acpi.o
@@ -15,8 +15,8 @@ Index: ioemu/Makefile.target
  ifeq ($(TARGET_BASE_ARCH), ppc)
 Index: ioemu/hw/pc.c
 ===================================================================
---- ioemu.orig/hw/pc.c 2006-08-17 19:50:02.406869984 +0100
-+++ ioemu/hw/pc.c      2006-08-17 19:55:35.777020107 +0100
+--- ioemu.orig/hw/pc.c 2006-09-21 19:33:31.000000000 +0100
++++ ioemu/hw/pc.c      2006-09-21 19:33:32.000000000 +0100
 @@ -823,6 +823,9 @@
      }
  #endif /* !CONFIG_DM */
@@ -30,7 +30,7 @@ Index: ioemu/hw/xen_platform.c
 Index: ioemu/hw/xen_platform.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/hw/xen_platform.c    2006-08-17 19:55:35.777020107 +0100
++++ ioemu/hw/xen_platform.c    2006-09-21 19:33:32.000000000 +0100
 @@ -0,0 +1,138 @@
 +/*
 + * XEN platform fake pci device, formerly known as the event channel device
@@ -150,10 +150,10 @@ Index: ioemu/hw/xen_platform.c
 +    d = pci_register_device(bus, "xen-platform", sizeof(PCIDevice), -1, NULL,
 +                          NULL);
 +    pch = (struct pci_config_header *)d->config;
-+    pch->vendor_id = 0xfffd;
-+    pch->device_id = 0x0101;
++    pch->vendor_id = 0x5853;
++    pch->device_id = 0x0001;
 +    pch->command = 3; /* IO and memory access */
-+    pch->revision = 0;
++    pch->revision = 1;
 +    pch->api = 0;
 +    pch->subclass = 0x80; /* Other */
 +    pch->class = 0xff; /* Unclassified device class */
@@ -172,9 +172,9 @@ Index: ioemu/hw/xen_platform.c
 +}
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:50:22.278673522 +0100
-+++ ioemu/vl.h 2006-08-17 19:55:35.778019997 +0100
-@@ -1209,6 +1209,9 @@
+--- ioemu.orig/vl.h    2006-09-21 19:33:32.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:33:32.000000000 +0100
+@@ -1210,6 +1210,9 @@
  void xenstore_check_new_media_present(int timeout);
  void xenstore_write_vncport(int vnc_display);
  
diff -r e7cb3aefc233 -r b53c343b47ae 
tools/ioemu/patches/xen-support-buffered-ioreqs
--- a/tools/ioemu/patches/xen-support-buffered-ioreqs   Wed Oct 11 13:01:31 
2006 -0400
+++ b/tools/ioemu/patches/xen-support-buffered-ioreqs   Wed Oct 11 13:04:07 
2006 -0400
@@ -1,8 +1,8 @@ Index: ioemu/vl.c
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:50:22.277673633 +0100
-+++ ioemu/vl.c 2006-08-17 19:55:21.878556486 +0100
-@@ -5838,6 +5838,7 @@
+--- ioemu.orig/vl.c    2006-09-21 19:33:32.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100
+@@ -5844,6 +5844,7 @@
      unsigned long nr_pages, tmp_nr_pages, shared_page_nr;
      xen_pfn_t *page_array;
      extern void *shared_page;
@@ -10,7 +10,7 @@ Index: ioemu/vl.c
  
      char qemu_dm_logfilename[64];
  
-@@ -6419,6 +6420,18 @@
+@@ -6425,6 +6426,18 @@
      fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n",
              shared_page_nr, (uint64_t)(page_array[shared_page_nr]));
  
@@ -31,8 +31,8 @@ Index: ioemu/vl.c
  #elif defined(__ia64__)
 Index: ioemu/target-i386-dm/helper2.c
 ===================================================================
---- ioemu.orig/target-i386-dm/helper2.c        2006-08-17 19:49:44.491850141 
+0100
-+++ ioemu/target-i386-dm/helper2.c     2006-08-17 19:50:41.490549986 +0100
+--- ioemu.orig/target-i386-dm/helper2.c        2006-09-21 19:33:30.000000000 
+0100
++++ ioemu/target-i386-dm/helper2.c     2006-09-21 19:33:32.000000000 +0100
 @@ -76,6 +76,10 @@
  
  shared_iopage_t *shared_page = NULL;
diff -r e7cb3aefc233 -r b53c343b47ae 
tools/ioemu/patches/xenstore-block-device-config
--- a/tools/ioemu/patches/xenstore-block-device-config  Wed Oct 11 13:01:31 
2006 -0400
+++ b/tools/ioemu/patches/xenstore-block-device-config  Wed Oct 11 13:04:07 
2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/Makefile.target
 Index: ioemu/Makefile.target
 ===================================================================
---- ioemu.orig/Makefile.target 2006-08-17 19:50:02.405870095 +0100
-+++ ioemu/Makefile.target      2006-08-17 19:50:18.866050726 +0100
+--- ioemu.orig/Makefile.target 2006-09-21 19:33:31.000000000 +0100
++++ ioemu/Makefile.target      2006-09-21 19:33:31.000000000 +0100
 @@ -358,6 +358,7 @@
  VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
  VL_OBJS+= usb-uhci.o
@@ -13,7 +13,7 @@ Index: ioemu/xenstore.c
 Index: ioemu/xenstore.c
 ===================================================================
 --- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ ioemu/xenstore.c   2006-08-17 19:50:18.867050616 +0100
++++ ioemu/xenstore.c   2006-09-21 19:33:31.000000000 +0100
 @@ -0,0 +1,187 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General
@@ -204,9 +204,9 @@ Index: ioemu/xenstore.c
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:50:17.086247452 +0100
-+++ ioemu/vl.c 2006-08-17 19:50:18.870050284 +0100
-@@ -5243,9 +5243,11 @@
+--- ioemu.orig/vl.c    2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:33:31.000000000 +0100
+@@ -5249,9 +5249,11 @@
             "Standard options:\n"
             "-M machine      select emulated machine (-M ? for list)\n"
             "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
@@ -218,7 +218,7 @@ Index: ioemu/vl.c
             "-boot [a|c|d]   boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
           "-snapshot       write to temporary files instead of disk image 
files\n"
  #ifdef TARGET_I386
-@@ -5372,11 +5374,13 @@
+@@ -5378,11 +5380,13 @@
      QEMU_OPTION_M,
      QEMU_OPTION_fda,
      QEMU_OPTION_fdb,
@@ -232,7 +232,7 @@ Index: ioemu/vl.c
      QEMU_OPTION_boot,
      QEMU_OPTION_snapshot,
  #ifdef TARGET_I386
-@@ -5448,11 +5452,13 @@
+@@ -5454,11 +5458,13 @@
      { "M", HAS_ARG, QEMU_OPTION_M },
      { "fda", HAS_ARG, QEMU_OPTION_fda },
      { "fdb", HAS_ARG, QEMU_OPTION_fdb },
@@ -246,7 +246,7 @@ Index: ioemu/vl.c
      { "boot", HAS_ARG, QEMU_OPTION_boot },
      { "snapshot", 0, QEMU_OPTION_snapshot },
  #ifdef TARGET_I386
-@@ -5801,10 +5807,16 @@
+@@ -5807,10 +5813,16 @@
  #ifdef CONFIG_GDBSTUB
      int use_gdbstub, gdbstub_port;
  #endif
@@ -265,7 +265,7 @@ Index: ioemu/vl.c
      const char *kernel_filename, *kernel_cmdline;
      DisplayState *ds = &display_state;
      int cyls, heads, secs, translation;
-@@ -5865,8 +5877,10 @@
+@@ -5871,8 +5883,10 @@
      initrd_filename = NULL;
      for(i = 0; i < MAX_FD; i++)
          fd_filename[i] = NULL;
@@ -276,7 +276,7 @@ Index: ioemu/vl.c
      ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
      vga_ram_size = VGA_RAM_SIZE;
      bios_size = BIOS_SIZE;
-@@ -5880,11 +5894,13 @@
+@@ -5886,11 +5900,13 @@
      vncunused = 0;
      kernel_filename = NULL;
      kernel_cmdline = "";
@@ -290,7 +290,7 @@ Index: ioemu/vl.c
      cyls = heads = secs = 0;
      translation = BIOS_ATA_TRANSLATION_AUTO;
      pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-@@ -5917,7 +5933,11 @@
+@@ -5923,7 +5939,11 @@
              break;
          r = argv[optind];
          if (r[0] != '-') {
@@ -302,7 +302,7 @@ Index: ioemu/vl.c
          } else {
              const QEMUOption *popt;
  
-@@ -5961,6 +5981,7 @@
+@@ -5967,6 +5987,7 @@
              case QEMU_OPTION_initrd:
                  initrd_filename = optarg;
                  break;
@@ -310,7 +310,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_hda:
              case QEMU_OPTION_hdb:
              case QEMU_OPTION_hdc:
-@@ -5973,6 +5994,7 @@
+@@ -5979,6 +6000,7 @@
                          cdrom_index = -1;
                  }
                  break;
@@ -318,7 +318,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_snapshot:
                  snapshot = 1;
                  break;
-@@ -6025,11 +6047,13 @@
+@@ -6031,11 +6053,13 @@
              case QEMU_OPTION_append:
                  kernel_cmdline = optarg;
                  break;
@@ -332,7 +332,7 @@ Index: ioemu/vl.c
              case QEMU_OPTION_boot:
                  boot_device = optarg[0];
                  if (boot_device != 'a' && 
-@@ -6284,12 +6308,18 @@
+@@ -6290,12 +6314,18 @@
          }
      }
  
@@ -351,7 +351,7 @@ Index: ioemu/vl.c
      if (!linux_boot && 
          hd_filename[0] == '\0' && 
          (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
-@@ -6303,6 +6333,7 @@
+@@ -6309,6 +6339,7 @@
          else
              boot_device = 'd';
      }
@@ -359,7 +359,7 @@ Index: ioemu/vl.c
  
      setvbuf(stdout, NULL, _IOLBF, 0);
      
-@@ -6435,6 +6466,7 @@
+@@ -6441,6 +6472,7 @@
  
  #endif /* !CONFIG_DM */
  
@@ -367,7 +367,7 @@ Index: ioemu/vl.c
      /* we always create the cdrom drive, even if no disk is there */
      bdrv_init();
      if (cdrom_index >= 0) {
-@@ -6461,6 +6493,7 @@
+@@ -6467,6 +6499,7 @@
              }
          }
      }
@@ -375,7 +375,7 @@ Index: ioemu/vl.c
  
      /* we always create at least one floppy disk */
      fd_table[0] = bdrv_new("fda");
-@@ -6539,6 +6572,8 @@
+@@ -6545,6 +6578,8 @@
          }
      }
  
@@ -386,8 +386,8 @@ Index: ioemu/vl.c
                    kernel_filename, kernel_cmdline, initrd_filename,
 Index: ioemu/monitor.c
 ===================================================================
---- ioemu.orig/monitor.c       2006-08-17 19:49:44.491850141 +0100
-+++ ioemu/monitor.c    2006-08-17 19:50:18.871050174 +0100
+--- ioemu.orig/monitor.c       2006-09-21 19:33:30.000000000 +0100
++++ ioemu/monitor.c    2006-09-21 19:33:31.000000000 +0100
 @@ -24,6 +24,7 @@
  #include "vl.h"
  #include "disas.h"
@@ -416,8 +416,8 @@ Index: ioemu/monitor.c
      int i;
 Index: ioemu/block.c
 ===================================================================
---- ioemu.orig/block.c 2006-08-17 19:37:35.865578948 +0100
-+++ ioemu/block.c      2006-08-17 19:50:18.872050063 +0100
+--- ioemu.orig/block.c 2006-09-21 19:33:25.000000000 +0100
++++ ioemu/block.c      2006-09-21 19:33:31.000000000 +0100
 @@ -758,6 +758,7 @@
  static void raw_close(BlockDriverState *bs)
  {
@@ -428,9 +428,9 @@ Index: ioemu/block.c
  
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:50:17.087247341 +0100
-+++ ioemu/vl.h 2006-08-17 19:50:18.872050063 +0100
-@@ -1188,6 +1188,8 @@
+--- ioemu.orig/vl.h    2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:33:31.000000000 +0100
+@@ -1189,6 +1189,8 @@
  void term_print_help(void);
  void monitor_readline(const char *prompt, int is_password,
                        char *buf, int buf_size);
@@ -439,7 +439,7 @@ Index: ioemu/vl.h
  
  /* readline.c */
  typedef void ReadLineFunc(void *opaque, const char *str);
-@@ -1200,6 +1202,13 @@
+@@ -1201,6 +1203,13 @@
  void readline_start(const char *prompt, int is_password,
                      ReadLineFunc *readline_func, void *opaque);
  
@@ -455,8 +455,8 @@ Index: ioemu/vl.h
  extern char domain_name[];
 Index: ioemu/hw/ide.c
 ===================================================================
---- ioemu.orig/hw/ide.c        2006-08-17 19:49:57.830375828 +0100
-+++ ioemu/hw/ide.c     2006-08-17 19:50:18.874049842 +0100
+--- ioemu.orig/hw/ide.c        2006-09-21 19:33:30.000000000 +0100
++++ ioemu/hw/ide.c     2006-09-21 19:33:31.000000000 +0100
 @@ -1158,6 +1158,7 @@
          } else {
              ide_atapi_cmd_error(s, SENSE_NOT_READY, 
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/patches/xenstore-write-vnc-port
--- a/tools/ioemu/patches/xenstore-write-vnc-port       Wed Oct 11 13:01:31 
2006 -0400
+++ b/tools/ioemu/patches/xenstore-write-vnc-port       Wed Oct 11 13:04:07 
2006 -0400
@@ -1,7 +1,7 @@ Index: ioemu/xenstore.c
 Index: ioemu/xenstore.c
 ===================================================================
---- ioemu.orig/xenstore.c      2006-08-17 19:50:18.867050616 +0100
-+++ ioemu/xenstore.c   2006-08-17 19:50:22.274673964 +0100
+--- ioemu.orig/xenstore.c      2006-09-21 19:33:31.000000000 +0100
++++ ioemu/xenstore.c   2006-09-21 19:33:32.000000000 +0100
 @@ -185,3 +185,31 @@
      free(image);
      free(vec);
@@ -36,9 +36,9 @@ Index: ioemu/xenstore.c
 +}
 Index: ioemu/vl.c
 ===================================================================
---- ioemu.orig/vl.c    2006-08-17 19:50:18.870050284 +0100
-+++ ioemu/vl.c 2006-08-17 19:50:22.277673633 +0100
-@@ -6529,6 +6529,7 @@
+--- ioemu.orig/vl.c    2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:33:32.000000000 +0100
+@@ -6535,6 +6535,7 @@
        vnc_display = vnc_display_init(ds, vnc_display, vncunused);
        if (vncviewer)
            vnc_start_viewer(vnc_display);
@@ -48,9 +48,9 @@ Index: ioemu/vl.c
          sdl_display_init(ds, full_screen);
 Index: ioemu/vl.h
 ===================================================================
---- ioemu.orig/vl.h    2006-08-17 19:50:18.872050063 +0100
-+++ ioemu/vl.h 2006-08-17 19:50:22.278673522 +0100
-@@ -1207,6 +1207,7 @@
+--- ioemu.orig/vl.h    2006-09-21 19:33:31.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:33:32.000000000 +0100
+@@ -1208,6 +1208,7 @@
  int xenstore_fd(void);
  void xenstore_process_event(void *opaque);
  void xenstore_check_new_media_present(int timeout);
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/usb-linux.c
--- a/tools/ioemu/usb-linux.c   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/usb-linux.c   Wed Oct 11 13:04:07 2006 -0400
@@ -26,7 +26,9 @@
 #if defined(__linux__)
 #include <dirent.h>
 #include <sys/ioctl.h>
-#include <linux/compiler.h>
+/* Some versions of usbdevice_fs.h need __user to be defined for them.   */
+/* This may (harmlessly) conflict with a definition in linux/compiler.h. */
+#define __user
 #include <linux/usbdevice_fs.h>
 #include <linux/version.h>
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/vl.c  Wed Oct 11 13:04:07 2006 -0400
@@ -122,6 +122,7 @@ int nographic;
 int nographic;
 int vncviewer;
 int vncunused;
+struct sockaddr_in vnclisten_addr;
 const char* keyboard_layout = NULL;
 int64_t ticks_per_sec;
 char *boot_device = NULL;
@@ -723,6 +724,12 @@ void qemu_del_timer(QEMUTimer *ts)
         }
         pt = &t->next;
     }
+}
+
+void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time)
+{
+    if (ts->expire_time > expire_time || !qemu_timer_pending(ts))
+       qemu_mod_timer(ts, expire_time);
 }
 
 /* modify the current timer so that it will be fired when current_time
@@ -2777,10 +2784,22 @@ fail:
     return -1;
 }
 
+int parse_host(struct sockaddr_in *saddr, const char *buf)
+{
+    struct hostent *he;
+
+    if ((he = gethostbyname(buf)) != NULL) {
+        saddr->sin_addr = *(struct in_addr *)he->h_addr;
+    } else {
+        if (!inet_aton(buf, &saddr->sin_addr))
+            return -1;
+    }
+    return 0;
+}
+
 int parse_host_port(struct sockaddr_in *saddr, const char *str)
 {
     char buf[512];
-    struct hostent *he;
     const char *p, *r;
     int port;
 
@@ -2791,14 +2810,8 @@ int parse_host_port(struct sockaddr_in *
     if (buf[0] == '\0') {
         saddr->sin_addr.s_addr = 0;
     } else {
-        if (isdigit(buf[0])) {
-            if (!inet_aton(buf, &saddr->sin_addr))
-                return -1;
-        } else {
-            if ((he = gethostbyname(buf)) == NULL)
-                return - 1;
-            saddr->sin_addr = *(struct in_addr *)he->h_addr;
-        }
+        if (parse_host(&saddr, buf) == -1)
+            return -1;
     }
     port = strtol(p, (char **)&r, 0);
     if (r == p)
@@ -5346,6 +5359,7 @@ void help(void)
           "-vnc display    start a VNC server on display\n"
            "-vncviewer      start a vncviewer process for this domain\n"
            "-vncunused      bind the VNC server to an unused port\n"
+           "-vnclisten      bind the VNC server to this address\n"
            "-timeoffset     time offset (in seconds) from local time\n"
            "-acpi           disable or enable ACPI of HVM domain \n"
            "\n"
@@ -5438,6 +5452,7 @@ enum {
     QEMU_OPTION_acpi,
     QEMU_OPTION_vncviewer,
     QEMU_OPTION_vncunused,
+    QEMU_OPTION_vnclisten,
 };
 
 typedef struct QEMUOption {
@@ -5516,6 +5531,7 @@ const QEMUOption qemu_options[] = {
     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
     { "vncviewer", 0, QEMU_OPTION_vncviewer },
     { "vncunused", 0, QEMU_OPTION_vncunused },
+    { "vnclisten", HAS_ARG, QEMU_OPTION_vnclisten },
     
     /* temporary options */
     { "usb", 0, QEMU_OPTION_usb },
@@ -5922,6 +5938,8 @@ int main(int argc, char **argv)
 
     nb_nics = 0;
     /* default mac address of the first network interface */
+
+    memset(&vnclisten_addr.sin_addr, 0, sizeof(vnclisten_addr.sin_addr));
     
     /* init debug */
     sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm.%d.log", getpid());
@@ -6304,7 +6322,10 @@ int main(int argc, char **argv)
             case QEMU_OPTION_vncunused:
                 vncunused++;
                 if (vnc_display == -1)
-                    vnc_display = -2;
+                    vnc_display = 0;
+                break;
+            case QEMU_OPTION_vnclisten:
+                parse_host(&vnclisten_addr, optarg);
                 break;
             }
         }
@@ -6542,7 +6563,7 @@ int main(int argc, char **argv)
     if (nographic) {
         dumb_display_init(ds);
     } else if (vnc_display != -1) {
-       vnc_display = vnc_display_init(ds, vnc_display, vncunused);
+       vnc_display = vnc_display_init(ds, vnc_display, vncunused, 
&vnclisten_addr);
        if (vncviewer)
            vnc_start_viewer(vnc_display);
        xenstore_write_vncport(vnc_display);
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/vl.h  Wed Oct 11 13:04:07 2006 -0400
@@ -37,6 +37,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 #include "xenctrl.h"
 #include "xs.h"
 #include <xen/hvm/e820.h>
@@ -405,6 +407,7 @@ void qemu_free_timer(QEMUTimer *ts);
 void qemu_free_timer(QEMUTimer *ts);
 void qemu_del_timer(QEMUTimer *ts);
 void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
+void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time);
 int qemu_timer_pending(QEMUTimer *ts);
 
 extern int64_t ticks_per_sec;
@@ -785,7 +788,7 @@ void cocoa_display_init(DisplayState *ds
 void cocoa_display_init(DisplayState *ds, int full_screen);
 
 /* vnc.c */
-int vnc_display_init(DisplayState *ds, int display, int find_unused);
+int vnc_display_init(DisplayState *ds, int display, int find_unused, struct 
sockaddr_in *addr);
 int vnc_start_viewer(int port);
 
 /* ide.c */
diff -r e7cb3aefc233 -r b53c343b47ae tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/ioemu/vnc.c Wed Oct 11 13:04:07 2006 -0400
@@ -26,8 +26,21 @@
 
 #include "vl.h"
 #include "qemu_socket.h"
-
-#define VNC_REFRESH_INTERVAL (1000 / 30)
+#include <assert.h>
+
+/* The refresh interval starts at BASE.  If we scan the buffer and
+   find no change, we increase by INC, up to MAX.  If the mouse moves
+   or we get a keypress, the interval is set back to BASE.  If we find
+   an update, halve the interval.
+
+   All times in milliseconds. */
+#define VNC_REFRESH_INTERVAL_BASE 30
+#define VNC_REFRESH_INTERVAL_INC  50
+#define VNC_REFRESH_INTERVAL_MAX  2000
+
+/* Wait at most one second between updates, so that we can detect a
+   minimised vncviewer reasonably quickly. */
+#define VNC_MAX_UPDATE_INTERVAL   5000
 
 #include "vnc_keysym.h"
 #include "keymaps.c"
@@ -64,10 +77,11 @@ struct VncState
 struct VncState
 {
     QEMUTimer *timer;
+    int timer_interval;
+    int64_t last_update_time;
     int lsock;
     int csock;
     DisplayState *ds;
-    int need_update;
     int width;
     int height;
     uint64_t *dirty_row;       /* screen regions which are possibly dirty */
@@ -97,8 +111,6 @@ struct VncState
     int visible_y;
     int visible_w;
     int visible_h;
-
-    int slow_client;
 
     int ctl_keys;               /* Ctrl+Alt starts calibration */
 };
@@ -380,7 +392,7 @@ static void vnc_copy(DisplayState *ds, i
     int y = 0;
     int pitch = ds->linesize;
     VncState *vs = ds->opaque;
-    int updating_client = !vs->slow_client;
+    int updating_client = 1;
 
     if (src_x < vs->visible_x || src_y < vs->visible_y ||
        dst_x < vs->visible_x || dst_y < vs->visible_y ||
@@ -390,10 +402,8 @@ static void vnc_copy(DisplayState *ds, i
        (dst_y + h) > (vs->visible_y + vs->visible_h))
        updating_client = 0;
 
-    if (updating_client) {
-       vs->need_update = 1;
+    if (updating_client)
        _vnc_update_client(vs);
-    }
 
     if (dst_y > src_y) {
        y = h - 1;
@@ -445,111 +455,149 @@ static void _vnc_update_client(void *opa
 static void _vnc_update_client(void *opaque)
 {
     VncState *vs = opaque;
-    int64_t now = qemu_get_clock(rt_clock);
-
-    if (vs->need_update && vs->csock != -1) {
-       int y;
-       char *row;
-       char *old_row;
-       uint64_t width_mask;
-       int n_rectangles;
-       int saved_offset;
-       int maxx, maxy;
-       int tile_bytes = vs->depth * DP2X(vs, 1);
-
-       if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
-           width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
-       else
-           width_mask = ~(0ULL);
-
-       /* Walk through the dirty map and eliminate tiles that
-          really aren't dirty */
-       row = vs->ds->data;
-       old_row = vs->old_data;
-
-       for (y = 0; y < vs->ds->height; y++) {
-           if (vs->dirty_row[y] & width_mask) {
-               int x;
-               char *ptr, *old_ptr;
-
-               ptr = row;
-               old_ptr = old_row;
-
-               for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
-                   if (vs->dirty_row[y] & (1ULL << x)) {
-                       if (memcmp(old_ptr, ptr, tile_bytes)) {
-                           vs->has_update = 1;
-                           vs->update_row[y] |= (1ULL << x);
-                           memcpy(old_ptr, ptr, tile_bytes);
-                       }
-                       vs->dirty_row[y] &= ~(1ULL << x);
+    int64_t now;
+    int y;
+    char *row;
+    char *old_row;
+    uint64_t width_mask;
+    int n_rectangles;
+    int saved_offset;
+    int maxx, maxy;
+    int tile_bytes = vs->depth * DP2X(vs, 1);
+
+    if (vs->csock == -1)
+       return;
+
+    now = qemu_get_clock(rt_clock);
+
+    if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
+       width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
+    else
+       width_mask = ~(0ULL);
+
+    /* Walk through the dirty map and eliminate tiles that really
+       aren't dirty */
+    row = vs->ds->data;
+    old_row = vs->old_data;
+
+    for (y = 0; y < vs->ds->height; y++) {
+       if (vs->dirty_row[y] & width_mask) {
+           int x;
+           char *ptr, *old_ptr;
+
+           ptr = row;
+           old_ptr = old_row;
+
+           for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
+               if (vs->dirty_row[y] & (1ULL << x)) {
+                   if (memcmp(old_ptr, ptr, tile_bytes)) {
+                       vs->has_update = 1;
+                       vs->update_row[y] |= (1ULL << x);
+                       memcpy(old_ptr, ptr, tile_bytes);
                    }
-
-                   ptr += tile_bytes;
-                   old_ptr += tile_bytes;
+                   vs->dirty_row[y] &= ~(1ULL << x);
                }
+
+               ptr += tile_bytes;
+               old_ptr += tile_bytes;
            }
-
-           row += vs->ds->linesize;
-           old_row += vs->ds->linesize;
-       }
-
-       if (!vs->has_update || vs->visible_y >= vs->ds->height ||
-           vs->visible_x >= vs->ds->width)
-           goto out;
-
-       /* Count rectangles */
-       n_rectangles = 0;
-       vnc_write_u8(vs, 0);  /* msg id */
-       vnc_write_u8(vs, 0);
-       saved_offset = vs->output.offset;
-       vnc_write_u16(vs, 0);
-
-       maxy = vs->visible_y + vs->visible_h;
-       if (maxy > vs->ds->height)
-           maxy = vs->ds->height;
-       maxx = vs->visible_x + vs->visible_w;
-       if (maxx > vs->ds->width)
-           maxx = vs->ds->width;
-
-       for (y = vs->visible_y; y < maxy; y++) {
-           int x;
-           int last_x = -1;
-           for (x = X2DP_DOWN(vs, vs->visible_x);
-                x < X2DP_UP(vs, maxx); x++) {
-               if (vs->update_row[y] & (1ULL << x)) {
-                   if (last_x == -1)
-                       last_x = x;
-                   vs->update_row[y] &= ~(1ULL << x);
-               } else {
-                   if (last_x != -1) {
-                       int h = find_update_height(vs, y, maxy, last_x, x);
+       }
+  
+       row += vs->ds->linesize;
+       old_row += vs->ds->linesize;
+    }
+
+    if (!vs->has_update || vs->visible_y >= vs->ds->height ||
+       vs->visible_x >= vs->ds->width)
+       goto backoff;
+
+    /* Count rectangles */
+    n_rectangles = 0;
+    vnc_write_u8(vs, 0);  /* msg id */
+    vnc_write_u8(vs, 0);
+    saved_offset = vs->output.offset;
+    vnc_write_u16(vs, 0);
+    
+    maxy = vs->visible_y + vs->visible_h;
+    if (maxy > vs->ds->height)
+       maxy = vs->ds->height;
+    maxx = vs->visible_x + vs->visible_w;
+    if (maxx > vs->ds->width)
+       maxx = vs->ds->width;
+
+    for (y = vs->visible_y; y < maxy; y++) {
+       int x;
+       int last_x = -1;
+       for (x = X2DP_DOWN(vs, vs->visible_x);
+            x < X2DP_UP(vs, maxx); x++) {
+           if (vs->update_row[y] & (1ULL << x)) {
+               if (last_x == -1)
+                   last_x = x;
+               vs->update_row[y] &= ~(1ULL << x);
+           } else {
+               if (last_x != -1) {
+                   int h = find_update_height(vs, y, maxy, last_x, x);
+                   if (h != 0) {
                        send_framebuffer_update(vs, DP2X(vs, last_x), y,
                                                DP2X(vs, (x - last_x)), h);
                        n_rectangles++;
                    }
-                   last_x = -1;
                }
+               last_x = -1;
            }
-           if (last_x != -1) {
-               int h = find_update_height(vs, y, maxy, last_x, x);
+       }
+       if (last_x != -1) {
+           int h = find_update_height(vs, y, maxy, last_x, x);
+           if (h != 0) {
                send_framebuffer_update(vs, DP2X(vs, last_x), y,
                                        DP2X(vs, (x - last_x)), h);
                n_rectangles++;
            }
        }
-       vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
-       vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-
-       vs->has_update = 0;
-       vs->need_update = 0;
-       vnc_flush(vs);
-       vs->slow_client = 0;
-    } else
-       vs->slow_client = 1;
-
- out:
-    qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
+    }
+    vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
+    vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
+
+    if (n_rectangles == 0)
+       goto backoff;
+
+    vs->has_update = 0;
+    vnc_flush(vs);
+    vs->last_update_time = now;
+
+    vs->timer_interval /= 2;
+    if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE)
+       vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+
+    return;
+
+ backoff:
+    /* No update -> back off a bit */
+    vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
+    if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
+       vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
+       if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
+           /* Send a null update.  If the client is no longer
+              interested (e.g. minimised) it'll ignore this, and we
+              can stop scanning the buffer until it sends another
+              update request. */
+           /* It turns out that there's a bug in realvncviewer 4.1.2
+              which means that if you send a proper null update (with
+              no update rectangles), it gets a bit out of sync and
+              never sends any further requests, regardless of whether
+              it needs one or not.  Fix this by sending a single 1x1
+              update rectangle instead. */
+           vnc_write_u8(vs, 0);
+           vnc_write_u8(vs, 0);
+           vnc_write_u16(vs, 1);
+           send_framebuffer_update(vs, 0, 0, 1, 1);
+           vnc_flush(vs);
+           vs->last_update_time = now;
+           return;
+       }
+    }
+    qemu_mod_timer(vs->timer, now + vs->timer_interval);
+    return;
 }
 
 static void vnc_update_client(void *opaque)
@@ -564,7 +612,7 @@ static void vnc_timer_init(VncState *vs)
 {
     if (vs->timer == NULL) {
        vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
-       qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
+       vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
     }
 }
 
@@ -625,7 +673,6 @@ static int vnc_client_io_error(VncState 
        vs->csock = -1;
        buffer_reset(&vs->input);
        buffer_reset(&vs->output);
-       vs->need_update = 0;
        return 0;
     }
     return ret;
@@ -686,8 +733,10 @@ static void vnc_client_read(void *opaque
            memmove(vs->input.buffer, vs->input.buffer + len,
                    vs->input.offset - len);
            vs->input.offset -= len;
-       } else
+       } else {
+           assert(ret > vs->read_handler_expect);
            vs->read_handler_expect = ret;
+       }
     }
 }
 
@@ -895,13 +944,14 @@ static void framebuffer_update_request(V
                                       int x_position, int y_position,
                                       int w, int h)
 {
-    vs->need_update = 1;
     if (!incremental)
        framebuffer_set_updated(vs, x_position, y_position, w, h);
     vs->visible_x = x_position;
     vs->visible_y = y_position;
     vs->visible_w = w;
     vs->visible_h = h;
+
+    qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
 }
 
 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
@@ -1016,6 +1066,7 @@ static int protocol_client_msg(VncState 
 {
     int i;
     uint16_t limit;
+    int64_t now;
 
     switch (data[0]) {
     case 0:
@@ -1032,8 +1083,12 @@ static int protocol_client_msg(VncState 
        if (len == 1)
            return 4;
 
-       if (len == 4)
-           return 4 + (read_u16(data, 2) * 4);
+       if (len == 4) {
+           uint16_t v;
+           v = read_u16(data, 2);
+           if (v)
+               return 4 + v * 4;
+       }
 
        limit = read_u16(data, 2);
        for (i = 0; i < limit; i++) {
@@ -1055,20 +1110,30 @@ static int protocol_client_msg(VncState 
        if (len == 1)
            return 8;
 
+       vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+       qemu_advance_timer(vs->timer,
+                          qemu_get_clock(rt_clock) + vs->timer_interval);
        key_event(vs, read_u8(data, 1), read_u32(data, 4));
        break;
     case 5:
        if (len == 1)
            return 6;
 
+       vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+       qemu_advance_timer(vs->timer,
+                          qemu_get_clock(rt_clock) + vs->timer_interval);
        pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 
4));
        break;
     case 6:
        if (len == 1)
            return 8;
 
-       if (len == 8)
-           return 8 + read_u32(data, 4);
+       if (len == 8) {
+           uint32_t v;
+           v = read_u32(data, 4);
+           if (v)
+               return 8 + v;
+       }
 
        client_cut_text(vs, read_u32(data, 4), data + 8);
        break;
@@ -1086,6 +1151,8 @@ static int protocol_client_init(VncState
 {
     size_t l;
     char pad[3] = { 0, 0, 0 };
+
+    vga_hw_update();
 
     vs->width = vs->ds->width;
     vs->height = vs->ds->height;
@@ -1183,9 +1250,8 @@ static void vnc_listen_read(void *opaque
     }
 }
 
-int vnc_display_init(DisplayState *ds, int display, int find_unused)
-{
-    struct sockaddr_in addr;
+int vnc_display_init(DisplayState *ds, int display, int find_unused, struct 
sockaddr_in *addr)
+{
     int reuse_addr, ret;
     VncState *vs;
 
@@ -1223,11 +1289,10 @@ int vnc_display_init(DisplayState *ds, i
     }
 
  retry:
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(5900 + display);
-    memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
-
-    if (bind(vs->lsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+    addr->sin_family = AF_INET;
+    addr->sin_port = htons(5900 + display);
+
+    if (bind(vs->lsock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) 
== -1) {
        if (find_unused && errno == EADDRINUSE) {
            display++;
            goto retry;
@@ -1269,7 +1334,7 @@ int vnc_start_viewer(int port)
        exit(1);
 
     case 0:    /* child */
-       execlp("vncviewer", "vncviewer", s, 0);
+       execlp("vncviewer", "vncviewer", s, NULL);
        fprintf(stderr, "vncviewer execlp failed\n");
        exit(1);
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/libxc/xc_linux.c    Wed Oct 11 13:04:07 2006 -0400
@@ -133,27 +133,95 @@ int do_xen_hypercall(int xc_handle, priv
                       (unsigned long)hypercall);
 }
 
+#define MTAB "/proc/mounts"
+#define MAX_PATH 255
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
+static int find_sysfsdir(char *sysfsdir)
+{
+    FILE *fp;
+    char type[MAX_PATH + 1];
+
+    if ( (fp = fopen(MTAB, "r")) == NULL )
+        return -1;
+
+    while ( fscanf(fp, "%*s %"
+                   STR(MAX_PATH)
+                   "s %"
+                   STR(MAX_PATH)
+                   "s %*s %*d %*d\n",
+                   sysfsdir, type) == 2 )
+    {
+        if ( strncmp(type, "sysfs", 5) == 0 )
+            break;
+    }
+
+    fclose(fp);
+
+    return ((strncmp(type, "sysfs", 5) == 0) ? 0 : -1);
+}
+
+int xc_find_device_number(const char *name)
+{
+    FILE *fp;
+    int i, major, minor;
+    char sysfsdir[MAX_PATH + 1];
+    static char *classlist[] = { "xen", "misc" };
+
+    for ( i = 0; i < (sizeof(classlist) / sizeof(classlist[0])); i++ )
+    {
+        if ( find_sysfsdir(sysfsdir) < 0 )
+            goto not_found;
+
+        /* <base>/class/<classname>/<devname>/dev */
+        strncat(sysfsdir, "/class/", MAX_PATH);
+        strncat(sysfsdir, classlist[i], MAX_PATH);
+        strncat(sysfsdir, "/", MAX_PATH);
+        strncat(sysfsdir, name, MAX_PATH);
+        strncat(sysfsdir, "/dev", MAX_PATH);
+
+        if ( (fp = fopen(sysfsdir, "r")) != NULL )
+            goto found;
+    }
+
+ not_found:
+    errno = -ENOENT;
+    return -1;
+
+ found:
+    if ( fscanf(fp, "%d:%d", &major, &minor) != 2 )
+    {
+        fclose(fp);
+        goto not_found;
+    }
+
+    fclose(fp);
+
+    return makedev(major, minor);
+}
+
 #define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
-#define EVTCHN_DEV_MAJOR 10
-#define EVTCHN_DEV_MINOR 201
 
 int xc_evtchn_open(void)
 {
     struct stat st;
     int fd;
+    int devnum;
+
+    devnum = xc_find_device_number("evtchn");
 
     /* Make sure any existing device file links to correct device. */
-    if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
-        (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
+    if ( (lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
+         (st.st_rdev != devnum) )
         (void)unlink(EVTCHN_DEV_NAME);
 
-reopen:
+ reopen:
     if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 )
     {
         if ( (errno == ENOENT) &&
             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
-            (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
-            makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) )
+             (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, devnum) == 0) )
             goto reopen;
 
         PERROR("Could not open event channel interface");
diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/libxc/xc_load_elf.c Wed Oct 11 13:04:07 2006 -0400
@@ -364,7 +364,7 @@ static int parseelfimage(const char *ima
         if ( p != NULL && strncmp(p, "yes", 3) == 0 )
         {
             dsi->pae_kernel = PAEKERN_yes;
-            if ( !strncmp(p+4, "[extended-cr3]", 14) )
+            if ( !strncmp(p+3, "[extended-cr3]", 14) )
                 dsi->pae_kernel = PAEKERN_extended_cr3;
         }
     }
diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/libxc/xc_ptrace.c   Wed Oct 11 13:04:07 2006 -0400
@@ -251,7 +251,7 @@ map_domain_va_pae(
     if ( !(l2e & _PAGE_PRESENT) )
         return NULL;
     l1p = to_ma(cpu, l2e);
-    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p 
>> PAGE_SHIFT);
+    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l1p >> PAGE_SHIFT);
     if ( l1 == NULL )
         return NULL;
 
@@ -281,7 +281,6 @@ map_domain_va_64(
     uint64_t *l4, *l3, *l2, *l1;
     static void *v[MAX_VIRT_CPUS];
 
-
     if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
         return map_domain_va_32(xc_handle, cpu, guest_va, perm);
 
@@ -309,7 +308,6 @@ map_domain_va_64(
     if ( l2 == NULL )
         return NULL;
 
-    l1 = NULL;
     l2e = l2[l2_table_offset(va)];
     munmap(l2, PAGE_SIZE);
     if ( !(l2e & _PAGE_PRESENT) )
@@ -318,11 +316,12 @@ map_domain_va_64(
     if (l2e & 0x80)  { /* 2M pages */
         p = to_ma(cpu, (l1p + l1_table_offset(va)) << PAGE_SHIFT);
     } else { /* 4K pages */
-        l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, 
l1p >> PAGE_SHIFT);
+        l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, 
PROT_READ, l1p >> PAGE_SHIFT);
         if ( l1 == NULL )
             return NULL;
 
         l1e = l1[l1_table_offset(va)];
+        munmap(l1, PAGE_SIZE);
         if ( !(l1e & _PAGE_PRESENT) )
             return NULL;
         p = to_ma(cpu, l1e);
@@ -330,8 +329,6 @@ map_domain_va_64(
     if ( v[cpu] != NULL )
         munmap(v[cpu], PAGE_SIZE);
     v[cpu] = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p 
>> PAGE_SHIFT);
-    if (l1)
-        munmap(l1, PAGE_SIZE);
     if ( v[cpu] == NULL )
         return NULL;
 
@@ -611,17 +608,12 @@ xc_ptrace(
             online_vcpus_changed(cpumap);
         break;
 
-    case PTRACE_SETFPREGS:
-    case PTRACE_SETFPXREGS:
-    case PTRACE_PEEKUSER:
-    case PTRACE_POKEUSER:
-    case PTRACE_SYSCALL:
-    case PTRACE_KILL:
-        goto out_unsupported; /* XXX not yet supported */
-
     case PTRACE_TRACEME:
         IPRINTF("PTRACE_TRACEME is an invalid request under Xen\n");
         goto out_error;
+
+    default:
+        goto out_unsupported; /* XXX not yet supported */
     }
 
     return retval;
diff -r e7cb3aefc233 -r b53c343b47ae tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/libxc/xenctrl.h     Wed Oct 11 13:04:07 2006 -0400
@@ -92,6 +92,16 @@ int xc_interface_close(int xc_handle);
 int xc_interface_close(int xc_handle);
 
 /*
+ * KERNEL INTERFACES
+ */
+
+/*
+ * Resolve a kernel device name (e.g., "evtchn", "blktap0") into a kernel
+ * device number. Returns -1 on error (and sets errno).
+ */
+int xc_find_device_number(const char *name);
+
+/*
  * DOMAIN DEBUGGING FUNCTIONS
  */
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/mbootpack/Makefile
--- a/tools/misc/mbootpack/Makefile     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/misc/mbootpack/Makefile     Wed Oct 11 13:04:07 2006 -0400
@@ -20,12 +20,8 @@ install: build
 
 #  Tools etc.
 RM     := rm -f
-GDB    := gdb
 INCS   := -I. -I-
 DEFS   := 
-LDFLAGS        := 
-CFLAGS += -Wpointer-arith -Wcast-qual -Wno-unused -Wno-format
-CFLAGS += -Wmissing-prototypes -pipe
 
 #  What object files need building for the program
 OBJS   := mbootpack.o buildimage.o
@@ -35,22 +31,22 @@ DEPS     = .*.d
 DEPS     = .*.d
 
 mbootpack: $(OBJS)
-       $(HOSTCC) -o $@ $(filter-out %.a, $^)
+       $(HOSTCC) $(HOSTCFLAGS) -o $@ $(filter-out %.a, $^)
 
 .PHONY: clean
 clean:
        $(RM) mbootpack *.o $(DEPS) bootsect setup bzimage_header.c bin2c
 
 bootsect: bootsect.S
-       $(CC) $(CFLAGS) $(INCS) $(DEFS) -D__MB_ASM -c bootsect.S -o bootsect.o
+       $(CC) -m32 $(INCS) $(DEFS) -D__MB_ASM -c bootsect.S -o bootsect.o
        $(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary bootsect.o -o $@
 
 setup: setup.S
-       $(CC) $(CFLAGS) $(INCS) $(DEFS) -D__MB_ASM -c setup.S -o setup.o
+       $(CC) -m32 $(INCS) $(DEFS) -D__MB_ASM -c setup.S -o setup.o
        $(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary setup.o -o $@
 
 bin2c: bin2c.o 
-       $(HOSTCC) -o $@ $^ 
+       $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ 
 
 bzimage_header.c: bootsect setup bin2c
        ./bin2c -n 8 -b1 -a bzimage_bootsect bootsect > bzimage_header.c
@@ -59,11 +55,8 @@ buildimage.c: bzimage_header.c
 buildimage.c: bzimage_header.c
        @
 
-%.o: %.S
-       $(HOSTCC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@
-
 %.o: %.c
-       $(HOSTCC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@
+       $(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(INCS) $(DEFS) -c $< -o $@
 
 .PRECIOUS: $(OBJS) $(OBJS:.o=.c) $(DEPS)
 .SUFFIXES: 
diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/mbootpack/buildimage.c
--- a/tools/misc/mbootpack/buildimage.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/misc/mbootpack/buildimage.c Wed Oct 11 13:04:07 2006 -0400
@@ -24,8 +24,6 @@
  * $Id: buildimage.c,v 1.2 2005/03/23 10:39:19 tjd21 Exp $
  *
  */
-
-
 
 #include <assert.h>
 #include <stdio.h>
@@ -77,20 +75,22 @@
 /* Bring in the bzImage boot sector and setup code */
 #include "bzimage_header.c"
 
+#define _p(x) ((void *)(unsigned long)(x))
+
 address_t place_mbi(long int size) 
 /* Find space at the top of *low* memory for the MBI and associated red tape */
 {
     address_t start;
     start = 0xa000 - size;
     if (start < 0x9000 + sizeof(bzimage_bootsect) + sizeof(bzimage_setup)) {
-        printf("Fatal: command-lines too long: need %i, have %i bytes\n",
+        printf("Fatal: command-lines too long: need %ld, have %ld bytes\n",
                size, 
-               0x1000 - (sizeof(bzimage_bootsect) + sizeof(bzimage_setup)));
-        exit(1);        
+               0x1000L - (sizeof(bzimage_bootsect) + sizeof(bzimage_setup)));
+        exit(1);
     }
     if (!quiet) {
         printf("Placed MBI and strings (%p+%p)\n", 
-               start, size);
+               _p(start), _p(size));
     }
     return start;
 }
@@ -108,7 +108,7 @@ void make_bzImage(section_t *sections,
     /* Patch the kernel and mbi addresses into the setup code */
     *(address_t *)(bzimage_setup + BZ_ENTRY_OFFSET) = eswap(entry);
     *(address_t *)(bzimage_setup + BZ_MBI_OFFSET) = eswap(mbi);
-    if (!quiet) printf("Kernel entry is %p, MBI is %p.\n", entry, mbi);
+    if (!quiet) printf("Kernel entry is %p, MBI is %p.\n",_p(entry), _p(mbi));
 
     /* Write out header and trampoline */
     if (fseek(fp, 0, SEEK_SET) < 0) {
@@ -127,8 +127,9 @@ void make_bzImage(section_t *sections,
         exit(1);
     }
 
-    if (!quiet) printf("Wrote bzImage header: %i + %i bytes.\n", 
-                       sizeof(bzimage_bootsect), sizeof(bzimage_setup));
+    if (!quiet) printf("Wrote bzImage header: %ld + %ld bytes.\n", 
+                       (long)sizeof(bzimage_bootsect),
+                       (long)sizeof(bzimage_setup));
 
     /* Sorted list of sections below 1MB: write them out */
     for (s = sections, i = 0; s; s = s->next) {
diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/mbootpack/mbootpack.c
--- a/tools/misc/mbootpack/mbootpack.c  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/misc/mbootpack/mbootpack.c  Wed Oct 11 13:04:07 2006 -0400
@@ -128,6 +128,7 @@ static void usage(void)
     exit(1);
 }
 
+#define _p(x) ((void *)(unsigned long)(x))
 
 static void place_kernel_section(address_t start, long int size)
 /* Place the kernel in memory, checking for the memory hole. */
@@ -136,7 +137,8 @@ static void place_kernel_section(address
         /* Above the memory hole: easy */
         next_free_space = MAX(next_free_space, start + size);
         if (!quiet) {
-            printf("Placed kernel section (%p+%p)\n", start, size);
+            printf("Placed kernel section (%p+%p)\n",
+                   _p(start), _p(size));
         }
         return;
     }
@@ -144,14 +146,14 @@ static void place_kernel_section(address
     if (start >= MEM_HOLE_START) {
         /* In the memory hole.  Not so good */
         printf("Fatal: kernel load address (%p) is in the memory hole.\n",
-               start);
+               _p(start));
         exit(1);
     }
     
     if (start + size > MEM_HOLE_START) {
         /* Too big for low memory */
         printf("Fatal: kernel (%p+%p) runs into the memory hole.\n",
-               start, size);
+               _p(start), _p(size));
         exit(1);
     }  
     
@@ -159,7 +161,7 @@ static void place_kernel_section(address
     next_free_space = MAX(next_free_space, start + size);
 
     if (!quiet) {
-        printf("Placed kernel section (%p+%p)\n", start, size);
+        printf("Placed kernel section (%p+%p)\n", _p(start), _p(size));
     }
 }
 
@@ -182,12 +184,10 @@ static address_t place_section(long int 
 
     if (!quiet) {
         printf("Placed section (%p+%p), align=%p\n", 
-               start, size, align);
+               _p(start), _p(size), _p(align));
     }
     return start;
 }
-
-
 
 
 static address_t load_kernel(const char *filename)
@@ -296,7 +296,7 @@ static address_t load_kernel(const char 
                 size = loadsize;
             
             if (loadsize > size) {
-                printf("Fatal: can't load %i bytes of kernel into %i bytes " 
+                printf("Fatal: can't load %ld bytes of kernel into %ld bytes "
                        "of memory.\n", loadsize, size);
                 exit(1);
             }
@@ -466,8 +466,6 @@ static address_t load_kernel(const char 
 }
 
 
-
-
 int main(int argc, char **argv) 
 {
     char *buffer, *imagename, *command_line, *p;
@@ -480,7 +478,7 @@ int main(int argc, char **argv)
     struct mod_list *modp;
     address_t start, kernel_entry;
     long int size, mod_command_line_space, command_line_len;
-    int modules, opt, mbi_reloc_offset, make_multiboot;
+    int modules, opt, mbi_reloc_offset;
 
     static const char short_options[] = "hc:m:o:qM";
     static const struct option options[] = {
diff -r e7cb3aefc233 -r b53c343b47ae tools/misc/miniterm/miniterm.c
--- a/tools/misc/miniterm/miniterm.c    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/misc/miniterm/miniterm.c    Wed Oct 11 13:04:07 2006 -0400
@@ -32,10 +32,11 @@
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <string.h>
 
 #define DEFAULT_BAUDRATE   115200
 #define DEFAULT_SERDEVICE  "/dev/ttyS0"
-#define ENDMINITERM        2  /* ctrl-b to quit miniterm */
+#define ENDMINITERM        0x1d
 
 volatile int stop = 0;
 
@@ -76,7 +77,11 @@ int main(int argc, char **argv)
     char            *sername = DEFAULT_SERDEVICE;
     struct termios   oldsertio, newsertio, oldstdtio, newstdtio;
     struct sigaction sa;
- 
+    static char start_str[] = 
+        "************ REMOTE CONSOLE: CTRL-] TO QUIT ********\r\n";
+    static char end_str[] =
+        "\n************ REMOTE CONSOLE EXITED *****************\n";
+
     while ( --argc != 0 )
     {
         char *p = argv[argc];
@@ -121,7 +126,7 @@ int main(int argc, char **argv)
     newsertio.c_iflag = IGNBRK | IGNPAR;
 
     /* Raw output. */
-    newsertio.c_oflag = 0; 
+    newsertio.c_oflag = OPOST;
 
     /* No echo and no signals. */
     newsertio.c_lflag = 0;
@@ -137,7 +142,13 @@ int main(int argc, char **argv)
     /* next stop echo and buffering for stdin */
     tcgetattr(0,&oldstdtio);
     tcgetattr(0,&newstdtio); /* get working stdtio */
-    newstdtio.c_lflag &= ~(ICANON | ECHO);
+    newstdtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+    newstdtio.c_oflag &= ~OPOST;
+    newstdtio.c_cflag &= ~(CSIZE | PARENB);
+    newstdtio.c_cflag |= CS8;
+    newstdtio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+    newstdtio.c_cc[VMIN]=1;
+    newstdtio.c_cc[VTIME]=0;
     tcsetattr(0,TCSANOW,&newstdtio);
 
     /* Terminal settings done: now enter the main I/O loops. */
@@ -145,7 +156,7 @@ int main(int argc, char **argv)
     {
     case 0:
         close(1); /* stdout not needed */
-        for ( c = getchar(); c != ENDMINITERM ; c = getchar() ) 
+        for ( c = (char)getchar(); c != ENDMINITERM; c = (char)getchar() )
             write(fd,&c,1);
         tcsetattr(fd,TCSANOW,&oldsertio);
         tcsetattr(0,TCSANOW,&oldstdtio);
@@ -158,7 +169,7 @@ int main(int argc, char **argv)
         close(fd);
         exit(-1);
     default:
-        printf("** ctrl-b quits miniterm **\n");
+        write(1, start_str, strlen(start_str));
         close(0); /* stdin not needed */
         sa.sa_handler = child_handler;
         sa.sa_flags = 0;
@@ -166,9 +177,11 @@ int main(int argc, char **argv)
         while ( !stop )
         {
             read(fd,&c,1); /* modem */
+            c = (char)c;
             write(1,&c,1); /* stdout */
         }
         wait(NULL); /* wait for child to die or it will become a zombie */
+        write(1, end_str, strlen(end_str));
         break;
     }
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/Makefile
--- a/tools/pygrub/Makefile     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/pygrub/Makefile     Wed Oct 11 13:04:07 2006 -0400
@@ -12,9 +12,11 @@ ifndef XEN_PYTHON_NATIVE_INSTALL
 ifndef XEN_PYTHON_NATIVE_INSTALL
 install: all
        CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" 
--prefix=""
+       $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen
 else
 install: all
        CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)"
+       $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen
 endif
 
 .PHONY: clean
diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/src/fsys/ext2/__init__.py
--- a/tools/pygrub/src/fsys/ext2/__init__.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/pygrub/src/fsys/ext2/__init__.py    Wed Oct 11 13:04:07 2006 -0400
@@ -23,7 +23,7 @@ class Ext2FileSystemType(FileSystemType)
         fd = os.open(fn, os.O_RDONLY)
         os.lseek(fd, offset, 0)
         buf = os.read(fd, 2048)
-        
+        os.close(fd)        
         if len(buf) > 1082 and \
                struct.unpack("<H", buf[1080:1082]) == (0xef53,):
             return True
diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/src/fsys/reiser/__init__.py
--- a/tools/pygrub/src/fsys/reiser/__init__.py  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/pygrub/src/fsys/reiser/__init__.py  Wed Oct 11 13:04:07 2006 -0400
@@ -26,6 +26,7 @@ class ReiserFileSystemType(FileSystemTyp
         fd = os.open(fn, os.O_RDONLY)
         os.lseek(fd, 0x10000, 0)
         buf = os.read(fd, 0x40)
+        os.close(fd)
         if len(buf) == 0x40 and (buf[0x34:0x3B] in [FSMAGIC2, FSMAGIC3]) :
             return True
         return False
diff -r e7cb3aefc233 -r b53c343b47ae tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/pygrub/src/pygrub   Wed Oct 11 13:04:07 2006 -0400
@@ -25,7 +25,18 @@ import grub.GrubConf
 import grub.GrubConf
 import grub.fsys
 
-PYGRUB_VER = 0.4
+PYGRUB_VER = 0.5
+
+def enable_cursor(ison):
+    if ison:
+        val = 2
+    else:
+        val = 0
+        
+    try:
+        curses.curs_set(val)
+    except _curses.error:
+        pass
 
 def is_disk_image(file):
     fd = os.open(file, os.O_RDONLY)
@@ -141,10 +152,7 @@ class Grub:
             self.screen.timeout(1000)
             if hasattr(curses, 'use_default_colors'):
                 curses.use_default_colors()
-            try:
-                curses.curs_set(0)
-            except _curses.error:
-                pass
+            enable_cursor(False)
             self.entry_win = curses.newwin(10, 74, 2, 1)
             self.text_win = curses.newwin(10, 70, 12, 5)
             
@@ -247,6 +255,7 @@ class Grub:
         self.screen.refresh()
 
         t = GrubLineEditor(self.screen, 5, 2, line)
+        enable_cursor(True)
         ret = t.edit()
         if ret:
             return ret
@@ -262,6 +271,7 @@ class Grub:
         lines = []
         while 1:
             t = GrubLineEditor(self.screen, y, 2)
+            enable_cursor(True)            
             ret = t.edit()
             if ret:
                 if ret in ("quit", "return"):
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/util/blkif.py
--- a/tools/python/xen/util/blkif.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/util/blkif.py    Wed Oct 11 13:04:07 2006 -0400
@@ -7,7 +7,7 @@ def expand_dev_name(name):
 def expand_dev_name(name):
     if not name:
         return name
-    if re.match( '^/dev/', name ):
+    if re.match( '^/', name ):
         return name
     else:
         return '/dev/' + name
@@ -64,9 +64,11 @@ def blkdev_uname_to_file(uname):
     """Take a blkdev uname and return the corresponding filename."""
     fn = None
     if uname.find(":") != -1:
-        (typ, fn) = uname.split(":")
-        if typ == "phy" and not fn.startswith("/dev/"):
+        (typ, fn) = uname.split(":", 1)
+        if typ == "phy" and not fn.startswith("/"):
             fn = "/dev/%s" %(fn,)
+        if typ == "tap":
+            (typ, fn) = fn.split(":", 1)
     return fn
 
 def mount_mode(name):
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xend/XendBootloader.py   Wed Oct 11 13:04:07 2006 -0400
@@ -15,6 +15,7 @@ import os, select, errno
 import os, select, errno
 import random
 import sxp
+import shlex
 
 from XendLogging import log
 from XendError import VmError
@@ -49,7 +50,7 @@ def bootloader(blexec, disk, quiet = 0, 
             args.append("-q")
         args.append("--output=%s" %(fifo,))
         if blargs is not None:
-            args.extend(blargs.split())
+            args.extend(shlex.split(blargs))
         args.append(disk)
 
         try:
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xend/XendCheckpoint.py   Wed Oct 11 13:04:07 2006 -0400
@@ -161,8 +161,8 @@ def restore(xd, fd):
         if handler.store_mfn is None or handler.console_mfn is None:
             raise XendError('Could not read store/console MFN')
 
-        #Block until src closes connection
-        os.read(fd, 1)
+        os.read(fd, 1)           # Wait for source to close connection
+        dominfo.waitForDevices() # Wait for backends to set up
         dominfo.unpause()
         
         dominfo.completeRestore(handler.store_mfn, handler.console_mfn)
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xend/XendDomain.py       Wed Oct 11 13:04:07 2006 -0400
@@ -487,10 +487,19 @@ class XendDomain:
         if not dominfo:
             raise XendInvalidDomain(str(domid))
 
-        try:
-            return xc.vcpu_setaffinity(dominfo.getDomid(), vcpu, cpumap)
-        except Exception, ex:
-            raise XendError(str(ex))
+        # if vcpu is keyword 'all', apply the cpumap to all vcpus
+        vcpus = [ vcpu ]
+        if str(vcpu).lower() == "all":
+            vcpus = range(0, int(dominfo.getVCpuCount()))
+       
+        # set the same cpumask for all vcpus
+        rc = 0
+        for v in vcpus:
+            try:
+                rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap)
+            except Exception, ex:
+                raise XendError(str(ex))
+        return rc
 
     def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
                             weight):
@@ -560,13 +569,23 @@ class XendDomain:
         except Exception, ex:
             raise XendError(str(ex))
     
-    def domain_sched_credit_set(self, domid, weight, cap):
+    def domain_sched_credit_set(self, domid, weight = None, cap = None):
         """Set credit scheduler parameters for a domain.
         """
         dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         try:
+            if weight is None:
+                weight = int(0)
+            elif weight < 1 or weight > 65535:
+                raise XendError("weight is out of range")
+
+            if cap is None:
+                cap = int(~0)
+            elif cap < 0 or cap > dominfo.getVCpuCount() * 100:
+                raise XendError("cap is out of range")
+
             return xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap)
         except Exception, ex:
             raise XendError(str(ex))
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Oct 11 13:04:07 2006 -0400
@@ -600,6 +600,8 @@ class XendDomainInfo:
             if self.info['memory'] == 0:
                 if self.infoIsSet('mem_kb'):
                     self.info['memory'] = (self.info['mem_kb'] + 1023) / 1024
+            if self.info['memory'] <= 0:
+                raise VmError('Invalid memory size')
 
             if self.info['maxmem'] < self.info['memory']:
                 self.info['maxmem'] = self.info['memory']
@@ -990,14 +992,18 @@ class XendDomainInfo:
                 this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
                 corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
                                   self.info['name'], self.domid)
+                
+            if os.path.isdir(corefile):
+                raise XendError("Cannot dump core in a directory: %s" %
+                                corefile)
+            
             xc.domain_dumpcore(self.domid, corefile)
-
-        except:
+        except RuntimeError, ex:
             corefile_incomp = corefile+'-incomplete'
             os.rename(corefile, corefile_incomp)
             log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
                           self.domid, self.info['name'])
-
+            raise XendError("Failed to dump core: %s" %  str(ex))
 
     ## public:
 
@@ -1005,6 +1011,9 @@ class XendDomainInfo:
         """Set the memory target of this domain.
         @param target In MiB.
         """
+        if target <= 0:
+            raise XendError('Invalid memory size')
+        
         log.debug("Setting memory target of domain %s (%d) to %d MiB.",
                   self.info['name'], self.domid, target)
         
@@ -1097,15 +1106,16 @@ class XendDomainInfo:
     ## public:
 
     def destroyDevice(self, deviceClass, devid):
-       if type(devid) is str:
-           devicePath = '%s/device/%s' % (self.dompath, deviceClass)
-           for entry in xstransact.List(devicePath):
-               backend = xstransact.Read('%s/%s' % (devicePath, entry), 
"backend")
-               devName = xstransact.Read(backend, "dev")
-               if devName == devid:
-                   # We found the integer matching our devid, use it instead
-                   devid = entry
-                   break
+        if type(devid) is str:
+            devicePath = '%s/device/%s' % (self.dompath, deviceClass)
+            for entry in xstransact.List(devicePath):
+                backend = xstransact.Read('%s/%s' % (devicePath, entry),
+                                          "backend")
+                devName = xstransact.Read(backend, "dev")
+                if devName == devid:
+                    # We found the integer matching our devid, use it instead
+                    devid = entry
+                    break
         return self.getDeviceController(deviceClass).destroyDevice(devid)
 
 
@@ -1742,7 +1752,7 @@ class XendDomainInfo:
         blcfg = None
         # FIXME: this assumes that we want to use the first disk device
         for (n,c) in self.info['device']:
-            if not n or not c or n != "vbd":
+            if not n or not c or not(n in ["vbd", "tap"]):
                 continue
             disk = sxp.child_value(c, "uname")
             if disk is None:
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xend/XendRoot.py Wed Oct 11 13:04:07 2006 -0400
@@ -95,6 +95,9 @@ class XendRoot:
     dom0_min_mem_default = '0'
 
     dom0_vcpus_default = '0'
+
+    """Default interface to listen for VNC connections on"""
+    xend_vnc_listen_default = '127.0.0.1'
 
     components = {}
 
@@ -272,6 +275,9 @@ class XendRoot:
     def get_console_limit(self):
         return self.get_config_int('console-limit', 1024)
 
+    def get_vnclisten_address(self):
+        return self.get_config_value('vnc-listen', 
self.xend_vnc_listen_default)
+
 def instance():
     """Get an instance of XendRoot.
     Use this instead of the constructor.
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xend/image.py    Wed Oct 11 13:04:07 2006 -0400
@@ -252,7 +252,8 @@ class HVMImageHandler(ImageHandler):
 
         info = xc.xeninfo()
         if not 'hvm' in info['xen_caps']:
-            raise VmError("Not an HVM capable platform, we stop creating!")
+            raise VmError("HVM guest support is unavailable: is VT/AMD-V "
+                          "supported by your CPU and enabled in your BIOS?")
 
         self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
         self.device_model = sxp.child_value(imageConfig, 'device_model')
@@ -362,10 +363,17 @@ class HVMImageHandler(ImageHandler):
         if vnc:
             vncdisplay = sxp.child_value(config, 'vncdisplay',
                                          int(self.vm.getDomid()))
-            ret = ret + ['-vnc', '%d' % vncdisplay, '-k', 'en-us']
             vncunused = sxp.child_value(config, 'vncunused')
             if vncunused:
                 ret += ['-vncunused']
+            else:
+                ret += ['-vnc', '%d' % vncdisplay]
+            ret += ['-k', 'en-us']
+            vnclisten = sxp.child_value(config, 'vnclisten')
+            if not(vnclisten):
+                vnclisten = 
xen.xend.XendRoot.instance().get_vnclisten_address()
+            if vnclisten:
+                ret += ['-vnclisten', vnclisten]
         return ret
 
     def createDeviceModel(self):
diff -r e7cb3aefc233 -r b53c343b47ae 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Wed Oct 11 13:01:31 
2006 -0400
+++ b/tools/python/xen/xend/server/DevController.py     Wed Oct 11 13:04:07 
2006 -0400
@@ -25,7 +25,7 @@ from xen.xend.xenstore.xstransact import
 from xen.xend.xenstore.xstransact import xstransact, complete
 from xen.xend.xenstore.xswatch import xswatch
 
-DEVICE_CREATE_TIMEOUT = 10
+DEVICE_CREATE_TIMEOUT = 100
 HOTPLUG_STATUS_NODE = "hotplug-status"
 HOTPLUG_ERROR_NODE  = "hotplug-error"
 HOTPLUG_STATUS_ERROR = "error"
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xend/server/SrvDomain.py Wed Oct 11 13:04:07 2006 -0400
@@ -97,7 +97,7 @@ class SrvDomain(SrvDir):
     def op_pincpu(self, _, req):
         fn = FormFn(self.xd.domain_pincpu,
                     [['dom', 'int'],
-                     ['vcpu', 'int'],
+                     ['vcpu', 'str'],
                      ['cpumap', 'str']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/addlabel.py
--- a/tools/python/xen/xm/addlabel.py   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/addlabel.py   Wed Oct 11 13:04:07 2006 -0400
@@ -19,19 +19,23 @@
 
 """Labeling a domain configuration file or a resoruce.
 """
-import sys, os
+import os
+import sys
+
 from xen.util import dictio
 from xen.util import security
+from xen.xm.opts import OptionError
 
-def usage():
-    print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]"
-    print "       xm addlabel <label> res <resource> [<policy>]\n"
-    print "  This program adds an acm_label entry into the 'configfile'"
-    print "  for a domain or to the global resource label file for a"
-    print "  resource. It derives the policy from the running hypervisor"
-    print "  if it is not given (optional parameter). If a label already"
-    print "  exists for the given domain or resource, then addlabel fails.\n"
-    security.err("Usage")
+def help():
+    return """
+    Format: xm addlabel <label> dom <configfile> [<policy>]
+            xm addlabel <label> res <resource> [<policy>]
+    
+    This program adds an acm_label entry into the 'configfile'
+    for a domain or to the global resource label file for a
+    resource. It derives the policy from the running hypervisor
+    if it is not given (optional parameter). If a label already
+    exists for the given domain or resource, then addlabel fails."""
 
 
 def validate_config_file(configfile):
@@ -111,44 +115,45 @@ def add_domain_label(label, configfile, 
     config_fd.close()
 
 
-def main (argv):
+def main(argv):
+    policyref = None
+    if len(argv) not in (4, 5):
+        raise OptionError('Needs either 2 or 3 arguments')
+    
+    label = argv[1]
+    
+    if len(argv) == 5:
+        policyref = argv[4]
+    elif security.on():
+        policyref = security.active_policy
+    else:
+        raise OptionError("No active policy. Must specify policy on the "
+                          "command line.")
+
+    if argv[2].lower() == "dom":
+        configfile = argv[3]
+        if configfile[0] != '/':
+            for prefix in [".", "/etc/xen"]:
+                configfile = prefix + "/" + configfile
+                if os.path.isfile(configfile):
+                    break
+        if not validate_config_file(configfile):
+            raise OptionError('Invalid config file')
+        else:
+            add_domain_label(label, configfile, policyref)
+    elif argv[2].lower() == "res":
+        resource = argv[3]
+        add_resource_label(label, resource, policyref)
+    else:
+        raise OptionError('Need to specify either "dom" or "res" as '
+                          'object to add label to.')
+            
+if __name__ == '__main__':
     try:
-        policyref = None
-        if len(argv) not in [4,5]:
-            usage()
-            return
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
+    
 
-        label = argv[1]
 
-        if len(argv) == 5:
-            policyref = argv[4]
-        elif security.on():
-            policyref = security.active_policy
-        else:
-            security.err("No active policy. Policy must be specified in 
command line.")
-
-        if argv[2].lower() == "dom":
-            configfile = argv[3]
-            if configfile[0] != '/':
-                for prefix in [".", "/etc/xen"]:
-                    configfile = prefix + "/" + configfile
-                    if os.path.isfile(configfile):
-                        break
-            if not validate_config_file(configfile):
-                usage()
-            else:
-                add_domain_label(label, configfile, policyref)
-        elif argv[2].lower() == "res":
-            resource = argv[3]
-            add_resource_label(label, resource, policyref)
-        else:
-            usage()
-
-    except security.ACMError:
-        sys.exit(-1)
-
-
-if __name__ == '__main__':
-    main(sys.argv)
-
-
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/cfgbootpolicy.py      Wed Oct 11 13:04:07 2006 -0400
@@ -28,20 +28,17 @@ from xen.util.security import policy_dir
 from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
 from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, 
any_module_re
 from xen.util.security import empty_line_re, binary_name_re, policy_name_re
+from xen.xm.opts import OptionError
 
-
-def usage():
-    print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n"
-    print "  Adds a 'module' line to the Xen grub.conf entry"
-    print "  so that xen boots into a specific access control"
-    print "  policy. If kernelversion is not given, then this"
-    print "  script tries to determine it by looking for a grub"
-    print "  entry with a line kernel xen.* If there are multiple"
-    print "  Xen entries, then it must be called with an explicit"
-    print "  version (it will fail otherwise).\n"
-    err("Usage")
-
-
+def help():
+    return """
+    Adds a 'module' line to the Xen grub.conf entry
+    so that xen boots into a specific access control
+    policy. If kernelversion is not given, then this
+    script tries to determine it by looking for a grub
+    entry with a line kernel xen.* If there are multiple
+    Xen entries, then it must be called with an explicit
+    version (it will fail otherwise).\n"""
 
 def determine_kernelversion(user_specified):
     within_xen_title = 0
@@ -143,44 +140,41 @@ def insert_policy(boot_file, kernel_vers
 
 
 def main(argv):
-    try:
-        user_kver = None
-        policy = None
-        if len(argv) == 2:
-            policy = argv[1]
-        elif len(argv) == 3:
-            policy = argv[1]
-            user_kver = argv[2]
+    user_kver = None
+    policy = None
+    if len(argv) == 2:
+        policy = argv[1]
+    elif len(argv) == 3:
+        policy = argv[1]
+        user_kver = argv[2]
+    else:
+        raise OptionError('Invalid number of arguments')
+    
+    if not policy_name_re.match(policy):
+        raise OptionError("Illegal policy name: '%s'" % policy)
+
+    policy_file = '/'.join([policy_dir_prefix] + policy.split('.'))
+    src_binary_policy_file = policy_file + ".bin"
+    #check if .bin exists or if policy file exists
+    if not os.path.isfile(src_binary_policy_file):
+        if not os.path.isfile(policy_file + "-security_policy.xml"):
+            raise OptionError("Unknown policy '%s'" % policy)
         else:
-            usage()
-
-        if not policy_name_re.match(policy):
-            err("Illegal policy name \'" + policy + "\'")
-
-        policy_file = policy_dir_prefix + "/" + 
string.join(string.split(policy, "."), "/")
-        src_binary_policy_file = policy_file + ".bin"
-        #check if .bin exists or if policy file exists
-        if not os.path.isfile(src_binary_policy_file):
-            if not os.path.isfile(policy_file + "-security_policy.xml"):
-                err("Unknown policy \'" + policy +"\'")
-            else:
-                err("Cannot find binary file for policy \'" + policy +
-                    "\'. Please use makepolicy to create binary file.")
-        dst_binary_policy_file = "/boot/" + policy + ".bin"
-        shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
-
-        kernel_version = determine_kernelversion(user_kver)
-        insert_policy(boot_filename, kernel_version, policy)
-        print "Boot entry created and \'%s\' copied to /boot" % (policy + 
".bin")
-
-    except ACMError:
-        sys.exit(-1)
-    except:
-        traceback.print_exc(limit=1)
-        sys.exit(-1)
-
-
+            err_msg = "Cannot find binary file for policy '%s'." % policy
+            err_msg += " Please use makepolicy to create binary file."
+            raise OptionError(err_msg)
+    
+    dst_binary_policy_file = "/boot/" + policy + ".bin"
+    shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
+    
+    kernel_version = determine_kernelversion(user_kver)
+    insert_policy(boot_filename, kernel_version, policy)
+    print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin")
 
 if __name__ == '__main__':
-    main(sys.argv)
-
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: ' + str(e) + '\n')    
+        sys.exit(-1)
+        
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/console.py
--- a/tools/python/xen/xm/console.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/console.py    Wed Oct 11 13:04:07 2006 -0400
@@ -18,9 +18,7 @@
 
 XENCONSOLE = "xenconsole"
 
-
 import xen.util.auxbin
-
 
 def execConsole(domid):
     xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/create.py     Wed Oct 11 13:04:07 2006 -0400
@@ -25,7 +25,6 @@ import socket
 import socket
 import re
 import xmlrpclib
-import traceback
 
 from xen.xend import sxp
 from xen.xend import PrettyPrint
@@ -57,7 +56,8 @@ gopts.opt('help', short='h',
 
 gopts.opt('help_config',
           fn=set_true, default=0,
-          use="Print help for the configuration script.")
+          use="Print the available configuration variables (vars) for the "
+          "configuration script.")
 
 gopts.opt('quiet', short='q',
           fn=set_true, default=0,
@@ -65,35 +65,36 @@ gopts.opt('quiet', short='q',
 
 gopts.opt('path', val='PATH',
           fn=set_value, default='.:/etc/xen',
-          use="""Search path for configuration scripts.
-         The value of PATH is a colon-separated directory list.""")
+          use="Search path for configuration scripts. "
+          "The value of PATH is a colon-separated directory list.")
 
 gopts.opt('defconfig', short='f', val='FILE',
           fn=set_value, default='xmdefconfig',
-          use="""Use the given Python configuration script.
-          The configuration script is loaded after arguments have been 
processed.
-          Each command-line option sets a configuration variable named after
-          its long option name, and these variables are placed in the
-          environment of the script before it is loaded.
-          Variables for options that may be repeated have list values.
-          Other variables can be set using VAR=VAL on the command line.
-        
-          After the script is loaded, option values that were not set on the
-          command line are replaced by the values set in the script.""")
+          use="Use the given Python configuration script."
+          "The configuration script is loaded after arguments have been "
+          "processed. Each command-line option sets a configuration "
+          "variable named after its long option name, and these "
+          "variables are placed in the environment of the script before "
+          "it is loaded. Variables for options that may be repeated have "
+          "list values. Other variables can be set using VAR=VAL on the "
+          "command line. "     
+          "After the script is loaded, option values that were not set "
+          "on the command line are replaced by the values set in the script.")
 
 gopts.default('defconfig')
 
 gopts.opt('config', short='F', val='FILE',
           fn=set_value, default=None,
-          use="""Domain configuration to use (SXP).
-          SXP is the underlying configuration format used by Xen.
-          SXP configurations can be hand-written or generated from Python 
configuration
-          scripts, using the -n (dryrun) option to print the configuration.""")
+          use="Domain configuration to use (SXP).\n"
+          "SXP is the underlying configuration format used by Xen.\n"
+          "SXP configurations can be hand-written or generated from Python "
+          "configuration scripts, using the -n (dryrun) option to print "
+          "the configuration.")
 
 gopts.opt('dryrun', short='n',
           fn=set_true, default=0,
-          use="""Dry run - print the configuration but don't create the domain.
-          Loads the configuration script, creates the SXP configuration and 
prints it.""")
+          use="Dry run - prints the resulting configuration in SXP but "
+          "does not create the domain.")
 
 gopts.opt('paused', short='p',
           fn=set_true, default=0,
@@ -105,18 +106,16 @@ gopts.opt('console_autoconnect', short='
 
 gopts.var('vncviewer', val='no|yes',
           fn=set_bool, default=None,
-          use="""Spawn a vncviewer listening for a vnc server in the domain.
-          The address of the vncviewer is passed to the domain on the kernel 
command
-          line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 
+ DISPLAY.
-          A display value with a free port is chosen if possible.
-          Only valid when vnc=1.
-          """)
+           use="Spawn a vncviewer listening for a vnc server in the domain.\n"
+           "The address of the vncviewer is passed to the domain on the "
+           "kernel command line using 'VNC_SERVER=<host>:<port>'. The port "
+           "used by vnc is 5500 + DISPLAY. A display value with a free port "
+           "is chosen if possible.\nOnly valid when vnc=1.")
 
 gopts.var('vncconsole', val='no|yes',
           fn=set_bool, default=None,
-          use="""Spawn a vncviewer process for the domain's graphical console.
-          Only valid when vnc=1.
-          """)
+          use="Spawn a vncviewer process for the domain's graphical console.\n"
+          "Only valid when vnc=1.")
 
 gopts.var('name', val='NAME',
           fn=set_value, default=None,
@@ -420,6 +419,10 @@ gopts.var('vncdisplay', val='',
           fn=set_value, default=None,
           use="""VNC display to use""")
 
+gopts.var('vnclisten', val='',
+          fn=set_value, default=None,
+          use="""Address for VNC server to listen on.""")
+
 gopts.var('vncunused', val='',
           fn=set_bool, default=1,
           use="""Try to find an unused port for the VNC server.
@@ -443,7 +446,6 @@ gopts.var('uuid', val='',
           will be randomly generated if this option is not set, just like MAC 
           addresses for virtual network interfaces.  This must be a unique 
           value across the entire cluster.""")
-
 
 def err(msg):
     """Print an error to stderr and exit.
@@ -494,7 +496,6 @@ def configure_disks(config_devs, vals):
     """Create the config for disks (virtual block devices).
     """
     for (uname, dev, mode, backend) in vals.disk:
-
         if uname.startswith('tap:'):
             cls = 'tap'
         else:
@@ -640,8 +641,9 @@ def configure_hvm(config_image, vals):
     """
     args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb',
              'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
-             'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'sdl', 'display',
-             'acpi', 'apic', 'xauthority', 'usb', 'usbdevice' ]
+             'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
+             'sdl', 'display', 'xauthority',
+             'acpi', 'apic', 'usb', 'usbdevice' ]
     for a in args:
         if (vals.__dict__[a]):
             config_image.append([a, vals.__dict__[a]])
@@ -700,7 +702,7 @@ def make_config(vals):
         config_image = run_bootloader(vals, config_image)
         config.append(['bootloader', vals.bootloader])
         if vals.bootargs:
-            config.append(['bootloader_args'], vals.bootargs)
+            config.append(['bootloader_args', vals.bootargs])
     config.append(['image', config_image])
 
     config_devs = []
@@ -855,7 +857,6 @@ def choose_vnc_display():
         if port in ports: continue
         return d
     return None
-
 vncpid = None
 
 def daemonize(prog, args):
@@ -889,7 +890,6 @@ def daemonize(prog, args):
             w.write(str(pid2 or 0))
             w.close()
             os._exit(0)
-
     os.close(w)
     r = os.fdopen(r)
     daemon_pid = int(r.read())
@@ -908,6 +908,7 @@ def spawn_vnc(display):
     vncpid = daemonize("vncviewer", vncargs)
     if vncpid == 0:
         return 0
+
     return VNC_BASE_PORT + display
 
 def preprocess_vnc(vals):
@@ -1023,11 +1024,10 @@ def parseCommandLine(argv):
 def parseCommandLine(argv):
     gopts.reset()
     args = gopts.parse(argv)
-    if gopts.vals.help:
-        gopts.usage()
+
     if gopts.vals.help or gopts.vals.help_config:
-        gopts.load_defconfig(help=1)
-    if gopts.vals.help or gopts.vals.help_config:
+        if gopts.vals.help_config:
+            print gopts.val_usage()
         return (None, None)
 
     if not gopts.vals.display:
@@ -1095,7 +1095,6 @@ def check_domain_label(config, verbose):
 
     return answer
 
-
 def config_security_check(config, verbose):
     """Checks each resource listed in the config to see if the active
        policy will permit creation of a new domain using the config.
@@ -1149,7 +1148,6 @@ def config_security_check(config, verbos
 
     return answer
 
-
 def create_security_check(config):
     passed = 0
     try:
@@ -1162,7 +1160,9 @@ def create_security_check(config):
         sys.exit(-1)
 
     return passed
-
+  
+def help():
+    return str(gopts)
 
 def main(argv):
     try:
@@ -1180,11 +1180,11 @@ def main(argv):
         PrettyPrint.prettyprint(config)
     else:
         if not create_security_check(config):
-            err("Security configuration prevents domain from starting.")
+            raise OptionError('Security Configuration prevents domain from 
starting')
         else:
             dom = make_domain(opts, config)
             if opts.vals.console_autoconnect:
-                console.execConsole(dom)
-        
+                console.execConsole(dom)        
+             
 if __name__ == '__main__':
     main(sys.argv)
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/dry-run.py
--- a/tools/python/xen/xm/dry-run.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/dry-run.py    Wed Oct 11 13:04:07 2006 -0400
@@ -22,38 +22,36 @@ from xen.util import security
 from xen.util import security
 from xen.xm import create
 from xen.xend import sxp
+from xen.xm.opts import OptionError
 
-def usage():
-    print "\nUsage: xm dry-run <configfile>\n"
-    print "This program checks each resource listed in the configfile"
-    print "to see if the domain created by the configfile can access"
-    print "the resources.  The status of each resource is listed"
-    print "individually along with the final security decision.\n"
-    security.err("Usage")
-
+def help():
+    return """
+    This program checks each resource listed in the configfile
+    to see if the domain created by the configfile can access
+    the resources.  The status of each resource is listed
+    individually along with the final security decision."""
 
 def main (argv):
-    try:
-        if len(argv) != 2:
-            usage()
-
-        passed = 0
-        (opts, config) = create.parseCommandLine(argv)
-        if create.check_domain_label(config, verbose=1):
-            if create.config_security_check(config, verbose=1):
-                passed = 1
-        else:
-            print "Checking resources: (skipped)"
-
-        if passed:
-            print "Dry Run: PASSED"
-        else:
-            print "Dry Run: FAILED"
-            sys.exit(-1)
-
-    except security.ACMError:
+    if len(argv) != 2:
+        raise OptionError('Invalid number of arguments')
+    
+    passed = 0
+    (opts, config) = create.parseCommandLine(argv)
+    if create.check_domain_label(config, verbose=1):
+        if create.config_security_check(config, verbose=1):
+            passed = 1
+    else:
+        print "Checking resources: (skipped)"
+        
+    if passed:
+        print "Dry Run: PASSED"
+    else:
+        print "Dry Run: FAILED"
         sys.exit(-1)
 
-
 if __name__ == '__main__':
-    main(sys.argv)
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/dumppolicy.py
--- a/tools/python/xen/xm/dumppolicy.py Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/dumppolicy.py Wed Oct 11 13:04:07 2006 -0400
@@ -19,27 +19,24 @@
 """
 import sys
 from xen.util.security import ACMError, err, dump_policy
+from xen.xm.opts import OptionError
 
-
-def usage():
-    print "\nUsage: xm dumppolicy\n"
-    print " Retrieve and print currently enforced"
-    print " hypervisor policy information (low-level).\n"
-    err("Usage")
-
+def help():
+    return """
+    Retrieve and print currently enforced hypervisor policy information
+    (low-level)."""
 
 def main(argv):
+    if len(argv) != 1:
+        raise OptionError("No arguments expected.")
+
+    dump_policy()
+
+if __name__ == '__main__':
     try:
-        if len(argv) != 1:
-            usage()
-
-        dump_policy()
-
-    except ACMError:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))    
         sys.exit(-1)
 
 
-if __name__ == '__main__':
-    main(sys.argv)
-
-
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/getlabel.py
--- a/tools/python/xen/xm/getlabel.py   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/getlabel.py   Wed Oct 11 13:04:07 2006 -0400
@@ -21,13 +21,14 @@ import sys, os, re
 import sys, os, re
 from xen.util import dictio
 from xen.util import security
+from xen.xm.opts import OptionError
 
-def usage():
-    print "\nUsage: xm getlabel dom <configfile>"
-    print "       xm getlabel res <resource>\n"
-    print "  This program shows the label for a domain or resource.\n"
-    security.err("Usage")
-
+def help():
+    return """
+    Usage: xm getlabel dom <configfile>
+           xm getlabel res <resource>
+           
+    This program shows the label for a domain or resource."""
 
 def get_resource_label(resource):
     """Gets the resource label
@@ -37,7 +38,7 @@ def get_resource_label(resource):
     try:
         access_control = dictio.dict_read("resources", file)
     except:
-        security.err("Resource label file not found")
+        raise OptionError("Resource label file not found")
 
     # get the entry and print label
     if access_control.has_key(resource):
@@ -45,23 +46,22 @@ def get_resource_label(resource):
         label = access_control[resource][1]
         print "policy="+policy+",label="+label
     else:
-        security.err("Resource not labeled")
+        raise security.ACMError("Resource not labeled")
 
 
 def get_domain_label(configfile):
     # open the domain config file
     fd = None
-    file = None
     if configfile[0] == '/':
         fd = open(configfile, "rb")
     else:
         for prefix in [".", "/etc/xen"]:
-            file = prefix + "/" + configfile
-            if os.path.isfile(file):
-                fd = open(file, "rb")
+            abs_file = prefix + "/" + configfile
+            if os.path.isfile(abs_file):
+                fd = open(abs_file, "rb")
                 break
     if not fd:
-        security.err("Configuration file '"+configfile+"' not found.")
+        raise OptionError("Configuration file '%s' not found." % configfile)
 
     # read in the domain config file, finding the label line
     ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE)
@@ -79,7 +79,7 @@ def get_domain_label(configfile):
 
     # send error message if we didn't find anything
     if acline == "":
-        security.err("Domain not labeled")
+        raise security.ACMError("Domain not labeled")
 
     # print out the label
     (title, data) = acline.split("=", 1)
@@ -89,24 +89,25 @@ def get_domain_label(configfile):
     print data
 
 
-def main (argv):
-    try:
-        if len(argv) != 3:
-            usage()
+def main(argv):
+    if len(argv) != 3:
+        raise OptionError('Requires 2 arguments')
 
-        if argv[1].lower() == "dom":
-            configfile = argv[2]
-            get_domain_label(configfile)
-        elif argv[1].lower() == "res":
-            resource = argv[2]
-            get_resource_label(resource)
-        else:
-            usage()
-
-    except security.ACMError:
-        sys.exit(-1)
+    if argv[1].lower() == "dom":
+        configfile = argv[2]
+        get_domain_label(configfile)
+    elif argv[1].lower() == "res":
+        resource = argv[2]
+        get_resource_label(resource)
+    else:
+        raise OptionError('First subcommand argument must be "dom" or "res"')
 
 if __name__ == '__main__':
-    main(sys.argv)
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
+        
 
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/labels.py
--- a/tools/python/xen/xm/labels.py     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/labels.py     Wed Oct 11 13:04:07 2006 -0400
@@ -23,49 +23,46 @@ import string
 import string
 from xen.util.security import ACMError, err, list_labels, active_policy
 from xen.util.security import vm_label_re, res_label_re, all_label_re
+from xen.xm.opts import OptionError
 
-def usage():
-    print "\nUsage: xm labels [<policy>] [<type=dom|res|any>]\n"
-    print " Prints labels of the specified type (default is dom)"
-    print " that are defined in policy (default is current"
-    print " hypervisor policy).\n"
-    err("Usage")
 
+def help():
+    return """
+    Prints labels of the specified type (default is dom)
+    that are defined in policy (default is current hypervisor policy)."""
 
 def main(argv):
+    policy = None
+    ptype = None
+    for arg in argv[1:]:
+        key_val = arg.split('=')
+        if len(key_val) == 2 and key_val[0] == 'type':
+            if ptype:
+                raise OptionError('type is definied twice')
+            ptype = key_val[1].lower()
+
+        elif len(key_val) == 1:
+            if policy:
+                raise OptionError('policy is defined twice')
+            policy = arg
+        else:
+            raise OptionError('Unrecognised option: %s' % arg)
+
+    if not policy:
+        policy = active_policy
+        if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
+            raise OptionError('No policy active, you must specify a <policy>')
+
+    if not ptype or ptype == 'dom':
+        condition = vm_label_re
+    elif ptype == 'res':
+        condition = res_label_re
+    elif ptype == 'any':
+        condition = all_label_re
+    else:
+        err("Unknown label type \'" + ptype + "\'")
+
     try:
-        policy = None
-        type = None
-        for i in argv[1:]:
-            i_s = string.split(i, '=')
-            if len(i_s) > 1:
-                if (i_s[0] == 'type') and (len(i_s) == 2):
-                    if not type:
-                        type = i_s[1]
-                    else:
-                        usage()
-                else:
-                    usage()
-            else:
-                if not policy:
-                    policy = i
-                else:
-                    usage()
-
-        if not policy:
-            policy = active_policy
-            if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
-                err("No policy active. Please specify the <policy> parameter.")
-
-        if not type or (type in ['DOM', 'dom']):
-            condition = vm_label_re
-        elif type in ['RES', 'res']:
-            condition = res_label_re
-        elif type in ['ANY', 'any']:
-            condition = all_label_re
-        else:
-            err("Unknown label type \'" + type + "\'")
-
         labels = list_labels(policy, condition)
         labels.sort()
         for label in labels:
@@ -74,9 +71,7 @@ def main(argv):
     except ACMError:
         sys.exit(-1)
     except:
-        traceback.print_exc(limit=1)
-        sys.exit(-1)
-
+        traceback.print_exc(limit = 1)
 
 if __name__ == '__main__':
     main(sys.argv)
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/loadpolicy.py Wed Oct 11 13:04:07 2006 -0400
@@ -21,28 +21,22 @@ import sys
 import sys
 import traceback
 from xen.util.security import ACMError, err, load_policy
+from xen.xm.opts import OptionError
 
-
-def usage():
-    print "\nUsage: xm loadpolicy <policy>\n"
-    print " Load the compiled binary (.bin) policy"
-    print " into the running hypervisor.\n"
-    err("Usage")
+def help():
+    return """Load the compiled binary (.bin) policy into the running
+    hypervisor."""
 
 def main(argv):
-    try:
-        if len(argv) != 2:
-            usage()
-        load_policy(argv[1])
-
-    except ACMError:
-        sys.exit(-1)
-    except:
-        traceback.print_exc(limit=1)
-        sys.exit(-1)
-
+    if len(argv) != 2:
+        raise OptionError('No policy defined')
+    
+    load_policy(argv[1])
 
 if __name__ == '__main__':
-    main(sys.argv)
-
-
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
+        
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/main.py       Wed Oct 11 13:04:07 2006 -0400
@@ -22,28 +22,27 @@
 """Grand unified management application for Xen.
 """
 import os
-import os.path
 import sys
 import re
 import getopt
 import socket
-import warnings
-warnings.filterwarnings('ignore', category=FutureWarning)
+import traceback
 import xmlrpclib
 import traceback
 import datetime
-
-import xen.xend.XendProtocol
+from select import select
+
+import warnings
+warnings.filterwarnings('ignore', category=FutureWarning)
 
 from xen.xend import PrettyPrint
 from xen.xend import sxp
-from xen.xm.opts import *
-
-import console
-import xen.xend.XendClient
+from xen.xend import XendClient
 from xen.xend.XendClient import server
+
+from xen.xm.opts import OptionError, Opts, wrap, set_true
+from xen.xm import console
 from xen.util import security
-from select import select
 
 # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
 # getopt.getopt if gnu_getopt is not available.  This will mean that options
@@ -51,93 +50,148 @@ if not hasattr(getopt, 'gnu_getopt'):
 if not hasattr(getopt, 'gnu_getopt'):
     getopt.gnu_getopt = getopt.getopt
 
-
-# Strings for shorthelp
-console_help = "console <DomId>                  Attach to domain DomId's 
console."
-create_help =  """create [-c] <ConfigFile>
-               [Name=Value]..       Create a domain based on Config File"""
-destroy_help = "destroy <DomId>                  Terminate a domain 
immediately"
-dump_core_help =   """dump-core [-L|--live][-C|--crash]
-            <DomId> [FileName]      Dump core of the specified domain"""
-
-help_help =    "help                             Display this message"
-list_help =    "list [--long] [DomId, ...]       List information about 
domains"
-list_label_help = "list [--label] [DomId, ...]      List information about 
domains including their labels"
-
-mem_max_help = "mem-max <DomId> <Mem>            Set maximum memory 
reservation for a domain"
-mem_set_help = "mem-set <DomId> <Mem>            Adjust the current memory 
usage for a domain"
-migrate_help = "migrate <DomId> <Host>           Migrate a domain to another 
machine"
-pause_help =   "pause <DomId>                    Pause execution of a domain"
-reboot_help =  "reboot <DomId> [-w][-a]          Reboot a domain"
-restore_help = "restore <File>                   Create a domain from a saved 
state file"
-save_help =    "save <DomId> <File>              Save domain state (and 
config) to file"
-shutdown_help ="shutdown <DomId> [-w][-a][-R|-H] Shutdown a domain"
-top_help =     "top                              Monitor system and domains in 
real-time"
-unpause_help = "unpause <DomId>                  Unpause a paused domain"
-uptime_help  = "uptime [-s|--short] [DomId, ...] List uptime for domains"
-
-help_spacer = """
-   """
-
-# Strings for longhelp
-sysrq_help =   "sysrq   <DomId> <letter>         Send a sysrq to a domain"
-domid_help =   "domid <DomName>                  Converts a domain name to a 
domain id"
-domname_help = "domname <DomId>                  Convert a domain id to a 
domain name"
-vcpu_set_help = """vcpu-set <DomId> <VCPUs>         Set the number of active 
VCPUs for a domain
-                                    within the range allowed by the domain
-                                    configuration"""
-vcpu_list_help = "vcpu-list <DomId>                List the VCPUs for a domain 
(or all domains)"
-vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs>   Set which cpus a VCPU can 
use" 
-dmesg_help =   "dmesg [-c|--clear]               Read or clear Xen's message 
buffer"
-info_help =    "info                             Get information about the xen 
host"
-rename_help =  "rename <DomId> <New Name>        Rename a domain"
-log_help =     "log                              Print the xend log"
-sched_sedf_help = "sched-sedf [DOM] [OPTIONS]       Show|Set simple EDF 
parameters\n" + \
-"              -p, --period          Relative deadline(ms).\n\
-              -s, --slice           Worst-case execution time(ms)\n\
-                                    (slice < period).\n\
-              -l, --latency         scaled period(ms) in case the domain\n\
-                                    is doing heavy I/O.\n\
-              -e, --extra           flag (0/1) which controls whether the\n\
-                                    domain can run in extra-time\n\
-              -w, --weight          mutually exclusive with period/slice and\n\
-                                    specifies another way of setting a 
domain's\n\
-                                    cpu period/slice."
-
-sched_credit_help = "sched-credit                           Set or get credit 
scheduler parameters"
-block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode>
-                [BackDomId]         Create a new virtual block device"""
-block_detach_help = """block-detach  <DomId> <DevId>    Destroy a domain's 
virtual block device,
-                                    where <DevId> may either be the device ID
-                                    or the device name as mounted in the 
guest"""
-
-block_list_help = "block-list <DomId> [--long]      List virtual block devices 
for a domain"
-block_configure_help = """block-configure <DomId> <BackDev> <FrontDev> <Mode>
-                   [BackDomId] Change block device configuration"""
-network_attach_help = """network-attach  <DomID> [script=<script>] [ip=<ip>] 
[mac=<mac>]
-                           [bridge=<bridge>] [backend=<backDomID>]
-                                    Create a new virtual network device """
-network_detach_help = """network-detach  <DomId> <DevId>  Destroy a domain's 
virtual network
-                                    device, where <DevId> is the device ID."""
-
-network_list_help = "network-list <DomId> [--long]    List virtual network 
interfaces for a domain"
-vnet_list_help = "vnet-list [-l|--long]            list vnets"
-vnet_create_help = "vnet-create <config>             create a vnet from a 
config file"
-vnet_delete_help = "vnet-delete <vnetid>             delete a vnet"
-vtpm_list_help = "vtpm-list <DomId> [--long]       list virtual TPM devices"
-addlabel_help =  "addlabel <label> dom <configfile> Add security label to 
domain\n            <label> res <resource>   or resource"
-rmlabel_help =  "rmlabel dom <configfile>         Remove security label from 
domain\n           res <resource>           or resource"
-getlabel_help =  "getlabel dom <configfile>        Show security label for 
domain\n            res <resource>          or resource"
-dry_run_help =  "dry-run <configfile>             Tests if domain can access 
its resources"
-resources_help =  "resources                        Show info for each labeled 
resource"
-cfgbootpolicy_help = "cfgbootpolicy <policy>           Add policy to boot 
configuration "
-dumppolicy_help = "dumppolicy                       Print hypervisor ACM state 
information"
-loadpolicy_help = "loadpolicy <policy>              Load binary policy into 
hypervisor"
-makepolicy_help = "makepolicy <policy>              Build policy and create 
.bin/.map files"
-labels_help     = "labels [policy] [type=DOM|..]    List <type> labels for 
(active) policy."
-serve_help      = "serve                            Proxy Xend XML-RPC over 
stdio"
-
-short_command_list = [
+# General help message
+
+USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \
+             "Control, list, and manipulate Xen guest instances.\n"
+
+USAGE_FOOTER = '<Domain> can either be the Domain Name or Id.\n' \
+               'For more help on \'xm\' see the xm(1) man page.\n' \
+               'For more help on \'xm create\' see the xmdomain.cfg(5) '\
+               ' man page.\n'
+
+# Help strings are indexed by subcommand name in this way:
+# 'subcommand': (argstring, description)
+
+SUBCOMMAND_HELP = {
+    # common commands
+    
+    'console'     : ('<Domain>',
+                     'Attach to <Domain>\'s console.'),
+    'create'      : ('<ConfigFile> [options] [vars]',
+                     'Create a domain based on <ConfigFile>.'),
+    'destroy'     : ('<Domain>',
+                     'Terminate a domain immediately.'),
+    'help'        : ('', 'Display this message.'),
+    'list'        : ('[options] [Domain, ...]',
+                     'List information about all/some domains.'),
+    'mem-max'     : ('<Domain> <Mem>',
+                     'Set the maximum amount reservation for a domain.'),
+    'mem-set'     : ('<Domain> <Mem>',
+                     'Set the current memory usage for a domain.'),
+    'migrate'     : ('<Domain> <Host>',
+                     'Migrate a domain to another machine.'),
+    'pause'       : ('<Domain>', 'Pause execution of a domain.'),
+    'reboot'      : ('<Domain> [-wa]', 'Reboot a domain.'),
+    'restore'     : ('<CheckpointFile>',
+                     'Restore a domain from a saved state.'),
+    'save'        : ('<Domain> <CheckpointFile>',
+                     'Save a domain state to restore later.'),
+    'shutdown'    : ('<Domain> [-waRH]', 'Shutdown a domain.'),
+    'top'         : ('', 'Monitor a host and the domains in real time.'),
+    'unpause'     : ('<Domain>', 'Unpause a paused domain.'),
+    'uptime'      : ('[-s] <Domain>', 'Print uptime for a domain.'),
+
+    # less used commands
+
+    'dmesg'       : ('[-c|--clear]',
+                     'Read and/or clear Xend\'s message buffer.'),
+    'domid'       : ('<DomainName>', 'Convert a domain name to domain id.'),
+    'domname'     : ('<DomId>', 'Convert a domain id to domain name.'),
+    'dump-core'   : ('[-L|--live] [-C|--crash] <Domain> [Filename]',
+                     'Dump core for a specific domain.'),
+    'info'        : ('', 'Get information about Xen host.'),
+    'log'         : ('', 'Print Xend log'),
+    'rename'      : ('<Domain> <NewDomainName>', 'Rename a domain.'),
+    'sched-sedf'  : ('<Domain> [options]', 'Get/set EDF parameters.'),
+    'sched-credit': ('-d <Domain> [-w[=WEIGHT]|-c[=CAP]]',
+                     'Get/set credit scheduler parameters.'),
+    'sysrq'       : ('<Domain> <letter>', 'Send a sysrq to a domain.'),
+    'vcpu-list'   : ('[<Domain>]',
+                     'List the VCPUs for a domain or all domains.'),
+    'vcpu-pin'    : ('<Domain> <VCPU> <CPUs>',
+                     'Set which CPUs a VCPU can use.'),
+    'vcpu-set'    : ('<Domain> <vCPUs>',
+                     'Set the number of active VCPUs for allowed for the'
+                     ' domain.'),
+
+    # device commands
+
+    'block-attach'  :  ('<Domain> <BackDev> <FrontDev> <Mode>',
+                        'Create a new virtual block device.'),
+    'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]',
+                        'Change block device configuration'),
+    'block-detach'  :  ('<Domain> <DevId>',
+                        'Destroy a domain\'s virtual block device.'),
+    'block-list'    :  ('<Domain> [--long]',
+                        'List virtual block devices for a domain.'),
+    'network-attach':  ('<Domain> [--script=<script>] [--ip=<ip>] '
+                        '[--mac=<mac>]',
+                        'Create a new virtual network device.'),
+    'network-detach':  ('<Domain> <DevId>',
+                        'Destroy a domain\'s virtual network device.'),
+    'network-list'  :  ('<Domain> [--long]',
+                        'List virtual network interfaces for a domain.'),
+    'vnet-create'   :  ('<ConfigFile>','Create a vnet from ConfigFile.'),
+    'vnet-delete'   :  ('<VnetId>', 'Delete a Vnet.'),
+    'vnet-list'     :  ('[-l|--long]', 'List Vnets.'),
+    'vtpm-list'     :  ('<Domain> [--long]', 'List virtual TPM devices.'),
+
+    # security
+
+    'addlabel'      :  ('<label> {dom <ConfigFile>|res <resource>} [<policy>]',
+                        'Add security label to domain.'),
+    'rmlabel'       :  ('{dom <ConfigFile>|res <Resource>}',
+                        'Remove a security label from domain.'),
+    'getlabel'      :  ('{dom <ConfigFile>|res <Resource>}',
+                        'Show security label for domain or resource.'),
+    'dry-run'       :  ('<ConfigFile>',
+                        'Test if a domain can access its resources.'),
+    'resources'     :  ('', 'Show info for each labeled resource.'),
+    'cfgbootpolicy' :  ('<policy> [kernelversion]',
+                        'Add policy to boot configuration.'),
+    'dumppolicy'    :  ('', 'Print hypervisor ACM state information.'),
+    'loadpolicy'    :  ('<policy.bin>', 'Load binary policy into hypervisor.'),
+    'makepolicy'    :  ('<policy>', 'Build policy and create .bin/.map '
+                        'files.'),
+    'labels'        :  ('[policy] [type=dom|res|any]',
+                        'List <type> labels for (active) policy.'),
+    'serve'         :  ('', 'Proxy Xend XMLRPC over stdio.'),
+}
+
+SUBCOMMAND_OPTIONS = {
+    'sched-sedf': (
+       ('-p [MS]', '--period[=MS]', 'Relative deadline(ms)'),
+       ('-s [MS]', '--slice[=MS]' ,
+        'Worst-case execution time(ms). (slice < period)'),
+       ('-l [MS]', '--latency[=MS]',
+        'Scaled period (ms) when domain performs heavy I/O'),
+       ('-e [FLAG]', '--extra[=FLAG]',
+        'Flag (0 or 1) controls if domain can run in extra time.'),
+       ('-w [FLOAT]', '--weight[=FLOAT]',
+        'CPU Period/slice (do not set with --period/--slice)'),
+    ),
+    'sched-credit': (
+       ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'),
+       ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'),
+       ('-c CAP',    '--cap=CAP',       'Cap (int)'),
+    ),
+    'list': (
+       ('-l', '--long', 'Output all VM details in SXP'),
+       ('', '--label',  'Include security labels'),
+    ),
+    'dmesg': (
+       ('-c', '--clear', 'Clear dmesg buffer'),
+    ),
+    'vnet-list': (
+       ('-l', '--long', 'List Vnets as SXP'),
+    ),
+    'network-list': (
+       ('-l', '--long', 'List resources as SXP'),
+    ),
+}
+
+common_commands = [
     "console",
     "create",
     "destroy",
@@ -165,7 +219,6 @@ domain_commands = [
     "domname",
     "dump-core",
     "list",
-    "list_label",
     "mem-max",
     "mem-set",
     "migrate",
@@ -223,67 +276,110 @@ acm_commands = [
     "makepolicy",
     "loadpolicy",
     "cfgbootpolicy",
-    "dumppolicy"
+    "dumppolicy",
     ]
 
 all_commands = (domain_commands + host_commands + scheduler_commands +
                 device_commands + vnet_commands + acm_commands)
 
-
-def commandToHelp(cmd):
-    return eval(cmd.replace("-", "_") + "_help")
-
-
-shorthelp = """Usage: xm <subcommand> [args]
-    Control, list, and manipulate Xen guest instances
-
-xm common subcommands:
-   """  + help_spacer.join(map(commandToHelp, short_command_list))  + """
-
-<DomName> can be substituted for <DomId> in xm subcommands.
-
-For a complete list of subcommands run 'xm help --long'
-For more help on xm see the xm(1) man page
-For more help on xm create, see the xmdomain.cfg(5) man page"""
-
-longhelp = """Usage: xm <subcommand> [args]
-    Control, list, and manipulate Xen guest instances
-
-xm full list of subcommands:
-
-  Domain Commands:
-   """ + help_spacer.join(map(commandToHelp,  domain_commands)) + """
-
-  Xen Host Commands:
-   """ + help_spacer.join(map(commandToHelp,  host_commands)) + """
-
-  Scheduler Commands:
-   """ + help_spacer.join(map(commandToHelp,  scheduler_commands)) + """
-
-  Virtual Device Commands:
-   """  + help_spacer.join(map(commandToHelp, device_commands)) + """
-
-  Vnet commands:
-   """ + help_spacer.join(map(commandToHelp,  vnet_commands)) + """
-
-  Access Control commands:
-   """ + help_spacer.join(map(commandToHelp,  acm_commands)) + """
-
-<DomName> can be substituted for <DomId> in xm subcommands.
-
-For a short list of subcommands run 'xm help'
-For more help on xm see the xm(1) man page
-For more help on xm create, see the xmdomain.cfg(5) man page"""
-
-# array for xm help <command>
-help = {
-    "--long": longhelp
-    }
-
-for command in all_commands:
-    # create is handled specially
-    if (command != 'create'):
-        help[command] = commandToHelp(command)
+####################################################################
+#
+#  Help/usage printing functions
+#
+####################################################################
+
+def cmdHelp(cmd):
+    """Print help for a specific subcommand."""
+    
+    for fc in SUBCOMMAND_HELP.keys():
+        if fc[:len(cmd)] == cmd:
+            cmd = fc
+            break
+    
+    try:
+        args, desc = SUBCOMMAND_HELP[cmd]
+    except KeyError:
+        shortHelp()
+        return
+    
+    print 'Usage: xm %s %s' % (cmd, args)
+    print
+    print desc
+    
+    try:
+        # If options help message is defined, print this.
+        for shortopt, longopt, desc in SUBCOMMAND_OPTIONS[cmd]:
+            if shortopt and longopt:
+                optdesc = '%s, %s' % (shortopt, longopt)
+            elif shortopt:
+                optdesc = shortopt
+            elif longopt:
+                optdesc = longopt
+
+            wrapped_desc = wrap(desc, 43)   
+            print '  %-30s %-43s' % (optdesc, wrapped_desc[0])
+            for line in wrapped_desc[1:]:
+                print ' ' * 33 + line
+        print
+    except KeyError:
+        # if the command is an external module, we grab usage help
+        # from the module itself.
+        if cmd in IMPORTED_COMMANDS:
+            try:
+                cmd_module =  __import__(cmd, globals(), locals(), 'xen.xm')
+                cmd_usage = getattr(cmd_module, "help", None)
+                if cmd_usage:
+                    print cmd_usage()
+            except ImportError:
+                pass
+        
+def shortHelp():
+    """Print out generic help when xm is called without subcommand."""
+    
+    print USAGE_HELP
+    print 'Common \'xm\' commands:\n'
+    
+    for command in common_commands:
+        try:
+            args, desc = SUBCOMMAND_HELP[command]
+        except KeyError:
+            continue
+        wrapped_desc = wrap(desc, 50)
+        print ' %-20s %-50s' % (command, wrapped_desc[0])
+        for line in wrapped_desc[1:]:
+            print ' ' * 22 + line
+
+    print
+    print USAGE_FOOTER
+    print 'For a complete list of subcommands run \'xm help\'.'
+    
+def longHelp():
+    """Print out full help when xm is called with xm --help or xm help"""
+    
+    print USAGE_HELP
+    print 'xm full list of subcommands:\n'
+    
+    for command in all_commands:
+        try:
+            args, desc = SUBCOMMAND_HELP[command]
+        except KeyError:
+            continue
+
+        wrapped_desc = wrap(desc, 50)
+        print ' %-20s %-50s' % (command, wrapped_desc[0])
+        for line in wrapped_desc[1:]:
+            print ' ' * 22 + line        
+
+    print
+    print USAGE_FOOTER        
+
+def usage(cmd = None):
+    """ Print help usage information and exits """
+    if cmd:
+        cmdHelp(cmd)
+    else:
+        shortHelp()
+    sys.exit(1)
 
 
 ####################################################################
@@ -298,7 +394,7 @@ def arg_check(args, name, lo, hi = -1):
     if hi == -1:
         if n != lo:
             err("'xm %s' requires %d argument%s.\n" % (name, lo,
-                                                       lo > 1 and 's' or ''))
+                                                       lo == 1 and '' or 's'))
             usage(name)
     else:
         if n < lo or n > hi:
@@ -345,14 +441,19 @@ def xm_save(args):
 def xm_save(args):
     arg_check(args, "save", 2)
 
-    dom = args[0] # TODO: should check if this exists
+    try:
+        dominfo = parse_doms_info(server.xend.domain(args[0]))
+    except xmlrpclib.Fault, ex:
+        raise ex
+    
+    domid = dominfo['domid']
     savefile = os.path.abspath(args[1])
 
     if not os.access(os.path.dirname(savefile), os.W_OK):
         err("xm save: Unable to create file %s" % savefile)
         sys.exit(1)
     
-    server.xend.domain.save(dom, savefile)
+    server.xend.domain.save(domid, savefile)
     
 def xm_restore(args):
     arg_check(args, "restore", 1)
@@ -366,9 +467,9 @@ def xm_restore(args):
     server.xend.domain.restore(savefile)
 
 
-def getDomains(domain_names):
+def getDomains(domain_names, full = 0):
     if domain_names:
-        return map(server.xend.domain, domain_names)
+        return [server.xend.domain(dom) for dom in domain_names]
     else:
         return server.xend.domains(1)
 
@@ -378,9 +479,11 @@ def xm_list(args):
     show_vcpus = 0
     show_labels = 0
     try:
-        (options, params) = getopt.gnu_getopt(args, 'lv', 
['long','vcpus','label'])
+        (options, params) = getopt.gnu_getopt(args, 'lv',
+                                              ['long','vcpus','label'])
     except getopt.GetoptError, opterr:
         err(opterr)
+        usage('list')
         sys.exit(1)
     
     for (k, v) in options:
@@ -397,7 +500,7 @@ def xm_list(args):
         xm_vcpu_list(params)
         return
 
-    doms = getDomains(params)
+    doms = getDomains(params, use_long)
 
     if use_long:
         map(PrettyPrint.prettyprint, doms)
@@ -412,7 +515,7 @@ def parse_doms_info(info):
         return t(sxp.child_value(info, n, d))
     
     return {
-        'dom'      : get_info('domid',        int,   -1),
+        'domid'    : get_info('domid',        int,   -1),
         'name'     : get_info('name',         str,   '??'),
         'mem'      : get_info('memory',       int,   0),
         'vcpus'    : get_info('online_vcpus', int,   0),
@@ -428,7 +531,7 @@ def parse_sedf_info(info):
         return t(sxp.child_value(info, n, d))
 
     return {
-        'dom'      : get_info('domain',        int,   -1),
+        'domid'    : get_info('domain',        int,   -1),
         'period'   : get_info('period',        int,   -1),
         'slice'    : get_info('slice',         int,   -1),
         'latency'  : get_info('latency',       int,   -1),
@@ -436,34 +539,40 @@ def parse_sedf_info(info):
         'weight'   : get_info('weight',        int,   -1),
         }
 
-
 def xm_brief_list(doms):
-    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)'
+    print '%-40s %3s %8s %5s %5s %9s' % \
+          ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)')
+    
+    format = "%(name)-40s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s " \
+             "%(cpu_time)8.1f"
+    
     for dom in doms:
         d = parse_doms_info(dom)
-        print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s 
%(cpu_time)7.1f" % d)
-
+        print format % d
 
 def xm_label_list(doms):
+    print '%-32s %3s %8s %5s %5s %9s %-8s' % \
+          ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)', 'Label')
+    
     output = []
-    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)  
Label'
+    format = '%(name)-32s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s ' \
+             '%(cpu_time)8.1f %(seclabel)9s'
+    
     for dom in doms:
         d = parse_doms_info(dom)
-        l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s 
%(cpu_time)7.1f  " % d
         if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
-            if d['seclabel']:
-                line = (l, d['seclabel'])
-            else:
-                line = (l, "ERROR")
+            if not d['seclabel']:
+                d['seclabel'] = 'ERROR'
         elif security.active_policy in ['DEFAULT']:
-            line = (l, "DEFAULT")
+            d['seclabel'] = 'DEFAULT'
         else:
-            line = (l, "INACTIVE")
-        output.append(line)
+            d['seclabel'] = 'INACTIVE'
+        output.append((format % d, d['seclabel']))
+        
     #sort by labels
     output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
-    for l in output:
-        print l[0] + l[1]
+    for line, label in output:
+        print line
 
 
 def xm_vcpu_list(args):
@@ -474,7 +583,11 @@ def xm_vcpu_list(args):
         doms = server.xend.domains(False)
         dominfo = map(server.xend.domain.getVCPUInfo, doms)
 
-    print 'Name                              ID  VCPU  CPU  State  Time(s)  
CPU Affinity'
+    print '%-32s %3s %5s %5s %5s %9s %s' % \
+          ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
+
+    format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
+             ' %(cpu_time)8.1f %(cpumap)s'
 
     for dom in dominfo:
         def get_info(n):
@@ -568,10 +681,7 @@ def xm_vcpu_list(args):
                 c = "-"
                 s = "--p"
 
-            print (
-                "%(name)-32s %(domid)3d  %(number)4d  %(c)3s   %(s)-3s   
%(cpu_time)7.1f  %(cpumap)s" %
-                locals())
-
+            print format % locals()
 
 def xm_reboot(args):
     arg_check(args, "reboot", 1, 3)
@@ -596,22 +706,21 @@ def xm_unpause(args):
     server.xend.domain.unpause(dom)
 
 def xm_dump_core(args):
-    arg_check(args, "dump-core",1,3)
     live = False
     crash = False
-    import getopt
-    (options, params) = getopt.gnu_getopt(args, 'LC', ['live','crash'])
-
-    for (k, v) in options:
-        if k in ['-L', '--live']:
-            live = True
-        if k in ['-C', '--crash']:
-            crash = True
-
-    if len(params) == 0 or len(params) > 2:
-        err("invalid number of parameters")
-        usage("dump-core")
-
+    try:
+        (options, params) = getopt.gnu_getopt(args, 'LC', ['live','crash'])
+        for (k, v) in options:
+            if k in ('-L', '--live'):
+                live = True
+            if k in ('-C', '--crash'):
+                crash = True
+
+        if len(params) not in (1, 2):
+            raise OptionError("Expects 1 or 2 argument(s)")
+    except getopt.GetoptError, e:
+        raise OptionError(str(e))
+    
     dom = params[0]
     if len(params) == 2:
         filename = os.path.abspath(params[1])
@@ -622,45 +731,49 @@ def xm_dump_core(args):
         server.xend.domain.pause(dom)
 
     try:
-        print "dumping core of domain:%s ..." % str(dom)
+        print "Dumping core of domain: %s ..." % str(dom)
         server.xend.domain.dump(dom, filename, live, crash)
     finally:
         if not live:
             server.xend.domain.unpause(dom)
 
     if crash:
-        print "destroying domain:%s ..." % str(dom)
+        print "Destroying domain: %s ..." % str(dom)
         server.xend.domain.destroy(dom)
 
 def xm_rename(args):
     arg_check(args, "rename", 2)
-
+        
     server.xend.domain.setName(args[0], args[1])
 
-def xm_subcommand(command, args):
+def xm_importcommand(command, args):
     cmd = __import__(command, globals(), locals(), 'xen.xm')
     cmd.main([command] + args)
 
 
 #############################################################
 
-def cpu_make_map(cpulist):
-    cpus = []
-    for c in cpulist.split(','):
-        if c.find('-') != -1:
-            (x,y) = c.split('-')
-            for i in range(int(x),int(y)+1):
-                cpus.append(int(i))
-        else:
-            cpus.append(int(c))
-    cpus.sort()
-    return cpus
-
 def xm_vcpu_pin(args):
     arg_check(args, "vcpu-pin", 3)
 
+    def cpu_make_map(cpulist):
+        cpus = []
+        for c in cpulist.split(','):
+            if c.find('-') != -1:
+                (x,y) = c.split('-')
+                for i in range(int(x),int(y)+1):
+                    cpus.append(int(i))
+            else:
+                # remove this element from the list
+                if c[0] == '^':
+                    cpus = [x for x in cpus if x != int(c[1:])]
+                else:
+                    cpus.append(int(c))
+        cpus.sort()
+        return cpus
+
     dom  = args[0]
-    vcpu = int(args[1])
+    vcpu = args[1]
     cpumap = cpu_make_map(args[2])
     
     server.xend.domain.pincpu(dom, vcpu, cpumap)
@@ -719,11 +832,12 @@ def xm_sched_sedf(args):
         info['period']  = ns_to_ms(info['period'])
         info['slice']   = ns_to_ms(info['slice'])
         info['latency'] = ns_to_ms(info['latency'])
-        print( ("%(name)-32s %(dom)3d %(period)9.1f %(slice)9.1f" +
+        print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" +
                 " %(latency)7.1f %(extratime)6d %(weight)6d") % info)
 
     def domid_match(domid, info):
-        return domid is None or domid == info['name'] or domid == 
str(info['dom'])
+        return domid is None or domid == info['name'] or \
+               domid == str(info['domid'])
 
     # we want to just display current info if no parameters are passed
     if len(args) == 0:
@@ -757,20 +871,25 @@ def xm_sched_sedf(args):
         elif k in ['-w', '--weight']:
             opts['weight'] = v
 
+    doms = filter(lambda x : domid_match(domid, x),
+                        [parse_doms_info(dom) for dom in getDomains("")])
+
     # print header if we aren't setting any parameters
     if len(opts.keys()) == 0:
-        print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s'%('Name','ID','Period(ms)',
-                                                     'Slice(ms)', 'Lat(ms)',
-                                                     'Extra','Weight')
-
-    doms = filter(lambda x : domid_match(domid, x),
-                        [parse_doms_info(dom) for dom in getDomains("")])
+        print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s' % \
+              ('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)',
+               'Extra','Weight')
+    
     for d in doms:
         # fetch current values so as not to clobber them
-        sedf_info = \
-            parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
+        try:
+            sedf_raw = server.xend.domain.cpu_sedf_get(d['domid'])
+        except xmlrpclib.Fault:
+            # domain does not support sched-sedf?
+            sedf_raw = {}
+
+        sedf_info = parse_sedf_info(sedf_raw)
         sedf_info['name'] = d['name']
-
         # update values in case of call to set
         if len(opts.keys()) > 0:
             for k in opts.keys():
@@ -780,7 +899,7 @@ def xm_sched_sedf(args):
             v = map(int, [sedf_info['period'], sedf_info['slice'],
                           sedf_info['latency'],sedf_info['extratime'], 
                           sedf_info['weight']])
-            rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
+            rv = server.xend.domain.cpu_sedf_set(d['domid'], *v)
             if int(rv) != 0:
                 err("Failed to set sedf parameters (rv=%d)."%(rv))
 
@@ -789,17 +908,14 @@ def xm_sched_sedf(args):
             print_sedf(sedf_info)
 
 def xm_sched_credit(args):
-    usage_msg = """sched-credit:     Set or get credit scheduler parameters
- Usage:
-
-        sched-credit -d domain [-w weight] [-c cap]
-    """
+    """Get/Set options for Credit Scheduler."""
+    
     try:
-        opts, args = getopt.getopt(args[0:], "d:w:c:",
+        opts, params = getopt.getopt(args, "d:w:c:",
             ["domain=", "weight=", "cap="])
-    except getopt.GetoptError:
-        # print help information and exit:
-        print usage_msg
+    except getopt.GetoptError, opterr:
+        err(opterr)
+        usage('sched-credit')
         sys.exit(1)
 
     domain = None
@@ -816,20 +932,16 @@ def xm_sched_credit(args):
 
     if domain is None:
         # place holder for system-wide scheduler parameters
-        print usage_msg
+        err("No domain given.")
+        usage('sched-credit')
         sys.exit(1)
 
     if weight is None and cap is None:
         print server.xend.domain.sched_credit_get(domain)
     else:
-        if weight is None:
-            weight = int(0)
-        if cap is None:
-            cap = int(~0)
-
-        err = server.xend.domain.sched_credit_set(domain, weight, cap)
-        if err != 0:
-            print err
+        result = server.xend.domain.sched_credit_set(domain, weight, cap)
+        if result != 0:
+            err(str(result))
 
 def xm_info(args):
     arg_check(args, "info", 0)
@@ -848,6 +960,8 @@ def xm_console(args):
     dom = args[0]
     info = server.xend.domain(dom)
     domid = int(sxp.child_value(info, 'domid', '-1'))
+    if domid == -1:
+        raise Exception("Domain is not started")
     console.execConsole(domid)
 
 def xm_uptime(args):
@@ -870,7 +984,7 @@ def xm_uptime(args):
 
     for dom in doms:
         d = parse_doms_info(dom)
-        if d['dom'] > 0:
+        if d['domid'] > 0:
             uptime = int(round(d['up_time']))
         else:
             f=open('/proc/uptime', 'r')
@@ -897,12 +1011,18 @@ def xm_uptime(args):
         if short_mode:
             now = datetime.datetime.now()
             upstring = now.strftime(" %H:%M:%S") + " up " + upstring
-            upstring += ", " + d['name'] + " (" + str(d['dom']) + ")"
+            upstring += ", " + d['name'] + " (" + str(d['domid']) + ")"
         else:
             upstring += ':%(seconds)02d' % vars()
-            upstring = ("%(name)-32s %(dom)3d " % d) + upstring
+            upstring = ("%(name)-32s %(domid)3d " % d) + upstring
 
         print upstring
+
+def xm_sysrq(args):
+    arg_check(args, "sysrq", 2)
+    dom = args[0]
+    req = args[1]
+    server.xend.domain.send_sysrq(dom, req)    
 
 def xm_top(args):
     arg_check(args, "top", 0)
@@ -925,8 +1045,11 @@ its contents if the [-c|--clear] flag is
     myargs = args
     myargs.insert(0, 'dmesg')
     gopts.parse(myargs)
-    if not (1 <= len(myargs) <= 2):
+    
+    if len(myargs) not in (1, 2):
         err('Invalid arguments: ' + str(myargs))
+        usage('dmesg')
+        sys.exit(1)
 
     if not gopts.vals.clear:
         print server.xend.node.dmesg.info()
@@ -944,7 +1067,7 @@ def xm_serve(args):
     from fcntl import fcntl, F_SETFL
     
     s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-    s.connect(xen.xend.XendClient.XML_RPC_SOCKET)
+    s.connect(XendClient.XML_RPC_SOCKET)
     fcntl(sys.stdin, F_SETFL, os.O_NONBLOCK)
 
     while True:
@@ -1090,7 +1213,7 @@ def parse_block_configuration(args):
         cls = 'tap'
     else:
         cls = 'vbd'
-        
+
     vbd = [cls,
            ['uname', args[1]],
            ['dev',   args[2]],
@@ -1099,19 +1222,12 @@ def parse_block_configuration(args):
         vbd.append(['backend', args[4]])
 
     # verify that policy permits attaching this resource
-    try:
-        if security.on():
-            dominfo = server.xend.domain(dom)
-            label = security.get_security_printlabel(dominfo)
-        else:
-            label = None
-        security.res_security_check(args[1], label)
-    except security.ACMError, e:
-        print e.value
-        sys.exit(1)
-    except:
-        traceback.print_exc(limit=1)
-        sys.exit(1)
+    if security.on():
+        dominfo = server.xend.domain(dom)
+        label = security.get_security_printlabel(dominfo)
+    else:
+        label = None
+    security.res_security_check(args[1], label)
 
     return (dom, vbd)
 
@@ -1211,11 +1327,12 @@ commands = {
     "domid": xm_domid,
     "domname": xm_domname,
     "dump-core": xm_dump_core,
+    "reboot": xm_reboot,    
     "rename": xm_rename,
     "restore": xm_restore,
     "save": xm_save,
-    "reboot": xm_reboot,
     "shutdown": xm_shutdown,
+    "sysrq": xm_sysrq,
     "uptime": xm_uptime,
     "list": xm_list,
     # memory commands
@@ -1254,24 +1371,23 @@ commands = {
     }
 
 ## The commands supported by a separate argument parser in xend.xm.
-subcommands = [
+IMPORTED_COMMANDS = [
     'create',
     'migrate',
-    'sysrq',
     'labels',
     'addlabel',
+    'cfgbootpolicy',
+    'makepolicy',
+    'loadpolicy',
+    'dumppolicy',
     'rmlabel',
     'getlabel',
     'dry-run',
     'resources',
-    'cfgbootpolicy',
-    'makepolicy',
-    'loadpolicy',
-    'dumppolicy'
     ]
 
-for c in subcommands:
-    commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
+for c in IMPORTED_COMMANDS:
+    commands[c] = eval('lambda args: xm_importcommand("%s", args)' % c)
 
 aliases = {
     "balloon": "mem-set",
@@ -1289,11 +1405,18 @@ def xm_lookup_cmd(cmd):
     elif aliases.has_key(cmd):
         deprecated(cmd,aliases[cmd])
         return commands[aliases[cmd]]
-    else:
-        if len( cmd ) > 1:
-            matched_commands = filter( lambda (command, func): command[ 
0:len(cmd) ] == cmd, commands.iteritems() )
-            if len( matched_commands ) == 1:
-                       return matched_commands[0][1]
+    elif cmd == 'help':
+        longHelp()
+        sys.exit(0)
+    else:
+        # simulate getopt's prefix matching behaviour
+        if len(cmd) > 1:
+            same_prefix_cmds = [commands[c] for c in commands.keys() \
+                                if c[:len(cmd)] == cmd]
+            # only execute if there is only 1 match
+            if len(same_prefix_cmds) == 1:
+                return same_prefix_cmds[0]
+            
         err('Sub Command %s not found!' % cmd)
         usage()
 
@@ -1301,27 +1424,18 @@ def deprecated(old,new):
     print >>sys.stderr, (
         "Command %s is deprecated.  Please use xm %s instead." % (old, new))
 
-def usage(cmd=None):
-    if cmd == 'create':
-        mycmd = xm_lookup_cmd(cmd)
-        mycmd( ['--help'] )
-        sys.exit(1)
-    if help.has_key(cmd):
-        print "   " + help[cmd]
-    else:
-        print shorthelp
-    sys.exit(1)
-
 def main(argv=sys.argv):
     if len(argv) < 2:
         usage()
-    
-    if re.compile('-*help').match(argv[1]):
-       if len(argv) > 2:
-           usage(argv[2])
-       else:
-           usage()
-       sys.exit(0)
+
+    # intercept --help(-h) and output our own help
+    for help in ['--help', '-h']:
+        if help in argv[1:]:
+            if help == argv[1]:
+                longHelp()
+            else:
+                usage(argv[1])
+            sys.exit(0)
 
     cmd = xm_lookup_cmd(argv[1])
 
@@ -1334,9 +1448,9 @@ def main(argv=sys.argv):
                 usage()
         except socket.error, ex:
             if os.geteuid() != 0:
-                err("Most commands need root access.  Please try again as 
root.")
+                err("Most commands need root access. Please try again as 
root.")
             else:
-                err("Error connecting to xend: %s.  Is xend running?" % ex[1])
+                err("Unable to connect to xend: %s. Is xend running?" % ex[1])
             sys.exit(1)
         except KeyboardInterrupt:
             print "Interrupted."
@@ -1345,16 +1459,16 @@ def main(argv=sys.argv):
             if os.geteuid() != 0:
                 err("Most commands need root access.  Please try again as 
root.")
             else:
-                err("Error connecting to xend: %s." % ex[1])
+                err("Unable to connect to xend: %s." % ex[1])
             sys.exit(1)
         except SystemExit:
             sys.exit(1)
         except xmlrpclib.Fault, ex:
-            if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN:
-                print  >>sys.stderr, (
-                    "Error: the domain '%s' does not exist." % ex.faultString)
+            if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
+                err("Domain '%s' does not exist." % ex.faultString)
             else:
-                print  >>sys.stderr, "Error: %s" % ex.faultString
+                err(ex.faultString)
+            usage(argv[1])
             sys.exit(1)
         except xmlrpclib.ProtocolError, ex:
             if ex.errcode == -1:
@@ -1369,6 +1483,15 @@ def main(argv=sys.argv):
         except (ValueError, OverflowError):
             err("Invalid argument.")
             usage(argv[1])
+            sys.exit(1)
+        except OptionError, e:
+            err(str(e))
+            usage(argv[1])
+            print e.usage()
+            sys.exit(1)
+        except security.ACMError, e:
+            err(str(e))
+            sys.exit(1)
         except:
             print "Unexpected error:", sys.exc_info()[0]
             print
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/makepolicy.py Wed Oct 11 13:04:07 2006 -0400
@@ -20,7 +20,7 @@ import sys
 import sys
 import traceback
 from xen.util.security import ACMError, err, make_policy
-
+from xen.xm.opts import OptionError
 
 def usage():
     print "\nUsage: xm makepolicy <policy>\n"
@@ -29,22 +29,17 @@ def usage():
     err("Usage")
 
 
+def main(argv):
+    if len(argv) != 2:
+        raise OptionError('No XML policy file specified')
 
-def main(argv):
+    make_policy(argv[1])
+
+if __name__ == '__main__':
     try:
-        if len(argv) != 2:
-            usage()
-        make_policy(argv[1])
-
-    except ACMError:
-        sys.exit(-1)
-    except:
-        traceback.print_exc(limit=1)
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
         sys.exit(-1)
 
 
-
-if __name__ == '__main__':
-    main(sys.argv)
-
-
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/migrate.py    Wed Oct 11 13:04:07 2006 -0400
@@ -46,19 +46,17 @@ gopts.opt('resource', short='r', val='MB
           fn=set_int, default=0,
           use="Set level of resource usage for migration.")
 
-def help(argv):
-    gopts.argv = argv
-    gopts.usage()
+def help():
+    return str(gopts)
     
 def main(argv):
     opts = gopts
     args = opts.parse(argv)
-    if opts.vals.help:
-        opts.usage()
-        return
+    
     if len(args) != 2:
-        opts.usage()
-        sys.exit(1)
+        raise OptionError('Invalid number of arguments')
+
     dom = args[0]
     dst = args[1]
-    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, 
opts.vals.port)
+    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
+                               opts.vals.port)
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/opts.py
--- a/tools/python/xen/xm/opts.py       Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/opts.py       Wed Oct 11 13:04:07 2006 -0400
@@ -23,6 +23,42 @@ import os.path
 import os.path
 import sys
 import types
+
+def _line_wrap(text, width = 70):
+    lines = []
+    current_line = ''
+    words = text.strip().split()
+    while words:
+        word = words.pop(0)
+        if len(current_line) + len(word) + 1 < width:
+            current_line += word + ' '
+        else:
+            lines.append(current_line.strip())
+            current_line = word + ' '
+            
+    if current_line:
+        lines.append(current_line.strip())
+    return lines
+
+def wrap(text, width = 70):
+    """ Really basic textwrap. Useful because textwrap is not available
+    for Python 2.2, and textwrap.wrap ignores newlines in Python 2.3+.
+    """
+    if len(text) < width:
+        return [text]
+    
+    lines = []
+    for line in text.split('\n'):
+        lines += _line_wrap(line, width)
+    return lines
+
+class OptionError(Exception):
+    """Denotes an error in option parsing."""
+    def __init__(self, message, usage = ''):
+        self.message = message
+        self.usage = usage
+    def __str__(self):
+        return self.message
 
 class Opt:
     """An individual option.
@@ -72,7 +108,21 @@ class Opt:
     def __repr__(self):
         return self.name + '=' + str(self.specified_val)
 
-    __str__ = __repr__
+    def __str__(self):
+        """ Formats the option into:
+        '-k, --key     description'
+        """
+        PARAM_WIDTH = 20
+        if self.val:
+            keys = ', '.join(['%s=%s' % (k, self.val) for k in self.optkeys])
+        else:
+            keys = ', '.join(self.optkeys)
+        desc = wrap(self.use, 55)
+        if len(keys) > PARAM_WIDTH:
+            desc = [''] + desc
+            
+        wrapped = ('\n' + ' ' * (PARAM_WIDTH + 1)).join(desc)
+        return keys.ljust(PARAM_WIDTH + 1) + wrapped
 
     def set(self, value):
         """Set the option value.
@@ -243,8 +293,24 @@ class Opts:
     def __repr__(self):
         return '\n'.join(map(str, self.options))
 
-    __str__ = __repr__
-
+    def __str__(self):
+        options = [s for s in self.options if s.optkeys[0][0] == '-']
+        output = ''
+        if options:
+            output += '\nOptions:\n\n'
+            output += '\n'.join([str(o) for o in options])
+            output += '\n'
+        return output
+
+    def val_usage(self):
+        optvals = [s for s in self.options if s.optkeys[0][0] != '-']
+        output = ''
+        if optvals:
+            output += '\nValues:\n\n'
+            output += '\n'.join([str(o) for o in optvals])
+            output += '\n'
+        return output
+    
     def opt(self, name, **args):
         """Add an option.
 
@@ -338,14 +404,14 @@ class Opts:
                                               self.short_opts(),
                                               self.long_opts())
             except getopt.GetoptError, err:
-                self.err(str(err))
+                raise OptionError(str(err), self.use)
+            #self.err(str(err))
                 
             for (k, v) in xvals:
                 for opt in self.options:
                     if opt.specify(k, v): break
                 else:
-                    print >>sys.stderr, "Error: Unknown option:", k
-                    self.usage()
+                    raise OptionError('Unknown option: %s' % k, self.use)
 
             if not args:
                 break
@@ -390,10 +456,10 @@ class Opts:
     def usage(self):
         print 'Usage: ', self.argv[0], self.use or 'OPTIONS'
         print
-        for opt in self.options:
-            opt.show()
-            print
         if self.options:
+            for opt in self.options:
+                opt.show()
+                print
             print
 
     def var_usage(self):
@@ -427,7 +493,9 @@ class Opts:
                 self.load(p, help)
                 break
         else:
-            self.err('Cannot open config file "%s"' % self.vals.defconfig)
+            raise OptionError('Unable to open config file: %s' % \
+                              self.vals.defconfig,
+                              self.use)
 
     def load(self, defconfig, help):
         """Load a defconfig file. Local variables in the file
@@ -478,9 +546,9 @@ def set_bool(opt, k, v):
 def set_bool(opt, k, v):
     """Set a boolean option.
     """
-    if v in ['yes']:
+    if v in ('yes', 'y'):
         opt.set(1)
-    elif v in ['no']:
+    elif v in ('no', 'n'):
         opt.set(0)
     else:
         opt.opts.err('Invalid value:' +v)
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/resources.py
--- a/tools/python/xen/xm/resources.py  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/resources.py  Wed Oct 11 13:04:07 2006 -0400
@@ -21,13 +21,12 @@ import sys
 import sys
 from xen.util import dictio
 from xen.util import security
+from xen.xm.opts import OptionError
 
-def usage():
-    print "\nUsage: xm resource\n"
-    print "  This program lists information for each resource in the"
-    print "  global resource label file\n"
-    security.err("Usage")
-
+def help():
+    return """
+    This program lists information for each resource in the
+    global resource label file."""
 
 def print_resource_data(access_control):
     """Prints out a resource dictionary to stdout
@@ -38,24 +37,21 @@ def print_resource_data(access_control):
         print "    policy: "+policy
         print "    label:  "+label
 
+def main (argv):
+    if len(argv) > 1:
+        raise OptionError("No arguments required")
+    
+    try:
+        filename = security.res_label_filename
+        access_control = dictio.dict_read("resources", filename)
+    except:
+        raise OptionError("Resource file not found")
 
-def main (argv):
-    try:
-        if len(argv) != 1:
-            usage()
-
-        try:
-            file = security.res_label_filename
-            access_control = dictio.dict_read("resources", file)
-        except:
-            security.err("Error reading resource file.")
-
-        print_resource_data(access_control)
-
-    except security.ACMError:
-        sys.exit(-1)
+    print_resource_data(access_control)
 
 if __name__ == '__main__':
-    main(sys.argv)
-
-
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)    
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/rmlabel.py    Wed Oct 11 13:04:07 2006 -0400
@@ -21,15 +21,17 @@ import sys, os, re
 import sys, os, re
 from xen.util import dictio
 from xen.util import security
+from xen.xm.opts import OptionError
 
-def usage():
-    print "\nUsage: xm rmlabel dom <configfile>"
-    print "       xm rmlabel res <resource>\n"
-    print "  This program removes an acm_label entry from the 'configfile'"
-    print "  for a domain or from the global resource label file for a"
-    print "  resource. If the label does not exist for the given domain or"
-    print "  resource, then rmlabel fails.\n"
-    security.err("Usage")
+def help():
+    return """
+    Example: xm rmlabel dom <configfile>
+             xm rmlabel res <resource>
+
+    This program removes an acm_label entry from the 'configfile'
+    for a domain or from the global resource label file for a
+    resource. If the label does not exist for the given domain or
+    resource, then rmlabel fails."""
 
 
 def rm_resource_label(resource):
@@ -40,14 +42,14 @@ def rm_resource_label(resource):
     try:
         access_control = dictio.dict_read("resources", file)
     except:
-        security.err("Resource file not found, cannot remove label!")
+        raise security.ACMError("Resource file not found, cannot remove 
label!")
 
     # remove the entry and update file
     if access_control.has_key(resource):
         del access_control[resource]
         dictio.dict_write(access_control, "resources", file)
     else:
-        security.err("Resource not labeled.")
+        raise security.ACMError("Resource not labeled")
 
 
 def rm_domain_label(configfile):
@@ -55,7 +57,8 @@ def rm_domain_label(configfile):
     fd = None
     file = None
     if configfile[0] == '/':
-        fd = open(configfile, "rb")
+        file = configfile
+        fd = open(file, "rb")
     else:
         for prefix in [".", "/etc/xen"]:
             file = prefix + "/" + configfile
@@ -63,8 +66,8 @@ def rm_domain_label(configfile):
                 fd = open(file, "rb")
                 break
     if not fd:
-        security.err("Configuration file '"+configfile+"' not found.")
-
+        raise OptionError("Configuration file '%s' not found." % configfile)
+        
     # read in the domain config file, removing label
     ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE)
     ac_exit_re = re.compile(".*'\].*")
@@ -84,7 +87,7 @@ def rm_domain_label(configfile):
 
     # send error message if we didn't find anything to remove
     if not removed:
-        security.err("Domain not labeled.")
+        raise security.ACMError('Domain not labeled')
 
     # write the data back out to the file
     fd = open(file, "wb")
@@ -93,24 +96,25 @@ def rm_domain_label(configfile):
 
 
 def main (argv):
-    try:
-        if len(argv) != 3:
-            usage()
 
-        if argv[1].lower() == "dom":
-            configfile = argv[2]
-            rm_domain_label(configfile)
-        elif argv[1].lower() == "res":
-            resource = argv[2]
-            rm_resource_label(resource)
-        else:
-            usage()
+    if len(argv) != 3:
+        raise OptionError('Requires 2 arguments')
+    
+    if argv[1].lower() not in ('dom', 'res'):
+        raise OptionError('Unrecognised type argument: %s' % argv[1])
 
-    except security.ACMError:
-        sys.exit(-1)
-
+    if argv[1].lower() == "dom":
+        configfile = argv[2]
+        rm_domain_label(configfile)
+    elif argv[1].lower() == "res":
+        resource = argv[2]
+        rm_resource_label(resource)
 
 if __name__ == '__main__':
-    main(sys.argv)
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)    
 
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/python/xen/xm/shutdown.py   Wed Oct 11 13:04:07 2006 -0400
@@ -120,7 +120,6 @@ def main(argv):
     opts = gopts
     args = opts.parse(argv)
     if opts.vals.help:
-        opts.usage()
         return
     if opts.vals.all:
         main_all(opts, args)
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/doc/man/vn.pod.1
--- a/tools/vnet/doc/man/vn.pod.1       Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/doc/man/vn.pod.1       Wed Oct 11 13:04:07 2006 -0400
@@ -105,7 +105,7 @@ the vnet device to it.
 =item B<-v | --vnetif> I<vnetifname>
 
 Use I<vnetifname> as the name for the vnet device. If this option
-is not specified the default isto  name the device vnifN where N
+is not specified the default is to name the device vnifN where N
 is the last field of the vnet id as 4 hex characters.
 For example vnif0004. Network device names can be at
 most 14 characters.
@@ -173,4 +173,4 @@ This library is free software; you can r
 This library is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
\ No newline at end of file
+(at your option) any later version.
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/libxutil/Makefile
--- a/tools/vnet/libxutil/Makefile      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/libxutil/Makefile      Wed Oct 11 13:04:07 2006 -0400
@@ -30,6 +30,8 @@ PIC_OBJS := $(LIB_SRCS:.c=.opic)
 PIC_OBJS := $(LIB_SRCS:.c=.opic)
 
 CFLAGS   += -Werror -fno-strict-aliasing
+CFLAGS   += -O3
+#CFLAGS   += -g
 
 # Get gcc to generate the dependencies for us.
 CFLAGS   += -Wp,-MD,.$(@F).d
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/libxutil/hash_table.c
--- a/tools/vnet/libxutil/hash_table.c  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/libxutil/hash_table.c  Wed Oct 11 13:04:07 2006 -0400
@@ -116,7 +116,7 @@ acceptable.  Do NOT use for cryptographi
 --------------------------------------------------------------------
 */
 
-ub4 hash(const ub1 *k, ub4 length, ub4 initval)
+static inline ub4 _hash(const ub1 *k, ub4 length, ub4 initval)
 //register ub1 *k;        /* the key */
 //register ub4  length;   /* the length of the key */
 //register ub4  initval;    /* the previous hash, or an arbitrary value */
@@ -160,6 +160,11 @@ ub4 hash(const ub1 *k, ub4 length, ub4 i
    /*-------------------------------------------- report the result */
    return c;
 }
+
+ub4 hash(const ub1 *k, ub4 length, ub4 initval){
+    return _hash(k, length, initval);
+}
+
 
/*============================================================================*/
 
 /** Get the bucket for a hashcode in a hash table.
@@ -381,6 +386,9 @@ inline HTEntry * HashTable_find_entry(Ha
  * @return 1 if equal, 0 otherwise
  */
 inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){
+    if(table->key_size){
+        return memcmp(key1, key2, table->key_size) == 0;
+    }
     return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1 == 
key2);
 }
 
@@ -393,6 +401,9 @@ inline int HashTable_key_equal(HashTable
  * @return hashcode
  */
 inline Hashcode HashTable_key_hash(HashTable *table, void *key){
+    if(table->key_size){
+        return _hash(key, table->key_size, 0);
+    }
     return (table->key_hash_fn 
             ? table->key_hash_fn(key)
             : hash_hvoid(0, &key, sizeof(key)));
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/libxutil/hash_table.h
--- a/tools/vnet/libxutil/hash_table.h  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/libxutil/hash_table.h  Wed Oct 11 13:04:07 2006 -0400
@@ -96,6 +96,7 @@ struct HashTable {
     int buckets_n;
     /** Number of entries in the table. */
     int entry_count;
+    unsigned long key_size;
     /** Function to free keys and values in entries. */
     TableFreeFn *entry_free_fn;
     /** Function to hash keys. */
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/Makefile.ver
--- a/tools/vnet/vnet-module/Makefile.ver       Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/Makefile.ver       Wed Oct 11 13:04:07 2006 -0400
@@ -18,27 +18,32 @@
 # 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
 #============================================================================
 
-LINUX_SERIES ?=2.6
-KERNEL_MINOR ?=-xen0
+LINUX_SERIES?=2.6
+KERNEL_MINOR=-xen
 
-LINUX_VERSION ?= $(shell (/bin/ls -ld 
$(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \
+LINUX_VERSION?=$(shell (/bin/ls -d 
$(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \
                       sed -e 's!^.*linux-\(.\+\)!\1!' )
 
 ifeq ($(LINUX_VERSION),)
 $(error Kernel source for linux $(LINUX_SERIES) not found)
 endif
 
-KERNEL_VERSION =$(LINUX_VERSION)$(KERNEL_MINOR)
+KERNEL_VERSION=$(LINUX_VERSION)$(KERNEL_MINOR)
 
-KERNEL_SRC ?= $(XEN_ROOT)/linux-$(KERNEL_VERSION)
+KERNEL_SRC?=$(shell cd $(XEN_ROOT)/linux-$(KERNEL_VERSION) && pwd)
+
+ifeq ($(KERNEL_SRC),)
+$(error Kernel source for kernel $(KERNEL_VERSION) not found)
+endif
 
 # Get the full kernel release version from its makefile, as the source path
 # may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release 
2.6.12.6-xen0.
-KERNEL_RELEASE = $(shell make -s -C $(KERNEL_SRC) kernelrelease || \
-       make -f $(shell pwd)/Makefile.kver -s -C $(KERNEL_SRC) kernelrelease )
+KERNEL_RELEASE=$(shell make -s -C $(KERNEL_SRC) kernelrelease)
 
-KERNEL_MODULE_DIR = /lib/modules/$(KERNEL_RELEASE)/kernel
+KERNEL_MODULE_DIR=/lib/modules/$$(KERNEL_RELEASE)/kernel
 
-$(warning KERNEL_SRC     $(KERNEL_SRC))
-#$(warning KERNEL_VERSION $(KERNEL_VERSION))
-$(warning KERNEL_RELEASE $(KERNEL_RELEASE))
+$(warning KERNEL_SRC           $(KERNEL_SRC))
+$(warning LINUX_VERSION                $(LINUX_VERSION))
+$(warning KERNEL_VERSION       $(KERNEL_VERSION))
+$(warning KERNEL_RELEASE       $(KERNEL_RELEASE))
+$(warning KERNEL_ MODULE_DIR   $(KERNEL_MODULE_DIR))
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/esp.c
--- a/tools/vnet/vnet-module/esp.c      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/esp.c      Wed Oct 11 13:04:07 2006 -0400
@@ -104,7 +104,7 @@ void __exit esp_module_exit(void){
  * @param block size to round to a multiple of
  * @return rounded value
  */
-static inline int roundup(int n, int block){
+static inline int roundupto(int n, int block){
     if(block <= 1) return n;
     block--;
     return (n + block) & ~block;
@@ -312,9 +312,9 @@ static int esp_sa_send(SAState *sa, stru
     // header and IP header.
     plaintext_n = skb->len - ETH_HLEN - ip_n;
     // Add size of padding fields.
-    ciphertext_n = roundup(plaintext_n + ESP_PAD_N, esp->cipher.block_n);
+    ciphertext_n = roundupto(plaintext_n + ESP_PAD_N, esp->cipher.block_n);
     if(esp->cipher.pad_n > 0){
-        ciphertext_n = roundup(ciphertext_n, esp->cipher.pad_n);
+        ciphertext_n = roundupto(ciphertext_n, esp->cipher.pad_n);
     }
     extra_n = ciphertext_n - plaintext_n;
     iv_n = esp->cipher.iv_n;
@@ -502,9 +502,9 @@ static u32 esp_sa_size(SAState *sa, int 
     // Have to add some padding for alignment even if pad_n is zero.
     ESPState *esp = sa->data;
     
-    data_n = roundup(data_n + ESP_PAD_N, esp->cipher.block_n);
+    data_n = roundupto(data_n + ESP_PAD_N, esp->cipher.block_n);
     if(esp->cipher.pad_n > 0){
-        data_n = roundup(data_n, esp->cipher.pad_n);
+        data_n = roundupto(data_n, esp->cipher.pad_n);
     }
     data_n += esp->digest.icv_n;
     //data_n += esp->cipher.iv_n;
@@ -607,7 +607,7 @@ static int esp_cipher_init(SAState *sa, 
         err = -EINVAL;
         goto exit;
     }
-    esp->cipher.key_n = roundup(sa->cipher.bits, 8);
+    esp->cipher.key_n = roundupto(sa->cipher.bits, 8);
     // If cipher is null must use ECB because CBC algo does not support 
blocksize 1.
     if(strcmp(sa->cipher.name, "cipher_null")){
         cipher_mode = CRYPTO_TFM_MODE_ECB;
@@ -617,7 +617,7 @@ static int esp_cipher_init(SAState *sa, 
         err = -ENOMEM;
         goto exit;
     }
-    esp->cipher.block_n = roundup(crypto_tfm_alg_blocksize(esp->cipher.tfm), 
4);
+    esp->cipher.block_n = roundupto(crypto_tfm_alg_blocksize(esp->cipher.tfm), 
4);
     esp->cipher.iv_n = crypto_tfm_alg_ivsize(esp->cipher.tfm);
     esp->cipher.pad_n = 0;
     if(esp->cipher.iv_n){
@@ -643,7 +643,7 @@ static int esp_digest_init(SAState *sa, 
     
     dprintf(">\n");
     esp->digest.key = sa->digest.key;
-    esp->digest.key_n = bits_to_bytes(roundup(sa->digest.bits, 8));
+    esp->digest.key_n = bits_to_bytes(roundupto(sa->digest.bits, 8));
     esp->digest.tfm = crypto_alloc_tfm(sa->digest.name, 0);
     if(!esp->digest.tfm){
         err = -ENOMEM;
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/etherip.c
--- a/tools/vnet/vnet-module/etherip.c  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/etherip.c  Wed Oct 11 13:04:07 2006 -0400
@@ -128,9 +128,27 @@ static void etherip_tunnel_close(Tunnel 
 }
 
 
+static inline int skb_make_headroom(struct sk_buff **pskb, struct sk_buff 
*skb, int head_n){
+    int err = 0;
+    dprintf("> skb=%p headroom=%d head_n=%d\n", skb, skb_headroom(skb), 
head_n);
+    if(head_n > skb_headroom(skb) || skb_cloned(skb) || skb_shared(skb)){
+        // Expand header the way GRE does.
+        struct sk_buff *new_skb = skb_realloc_headroom(skb, head_n + 16);
+        if(!new_skb){
+            err = -ENOMEM;
+            goto exit;
+        }
+        kfree_skb(skb);
+        *pskb = new_skb;
+    } else {
+        *pskb = skb;
+    }
+  exit:
+    return err;
+}
+    
 /** Send a packet via an etherip tunnel.
- * Adds etherip header, new ip header, new ethernet header around
- * ethernet frame.
+ * Adds etherip header and new ip header around ethernet frame.
  *
  * @param tunnel tunnel
  * @param skb packet
@@ -150,7 +168,7 @@ static int etherip_tunnel_send(Tunnel *t
     if(etherip_in_udp){
         head_n += vnet_n + udp_n;
     }
-    err = skb_make_room(&skb, skb, head_n, 0);
+    err = skb_make_headroom(&skb, skb, head_n);
     if(err) goto exit;
 
     // Null the pointer as we are pushing a new IP header.
@@ -219,6 +237,20 @@ int etherip_tunnel_create(VnetId *vnet, 
     return Tunnel_create(etherip_tunnel_type, vnet, addr, base, tunnel);
 }
 
+#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER)
+/** We need our own copy of this as it is no longer exported from the bridge 
module.
+ */
+static inline void _nf_bridge_save_header(struct sk_buff *skb){
+    int header_size = 16;
+    
+    // Were using this modified to use h_proto instead of skb->protocol.
+    if(skb->protocol == htons(ETH_P_8021Q)){
+        header_size = 18;
+    }
+    memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
+}
+#endif
+
 /** Do etherip receive processing.
  * Strips the etherip header to extract the ethernet frame, sets
  * the vnet from the header and re-receives the frame.
@@ -320,10 +352,9 @@ int etherip_protocol_recv(struct sk_buff
     skb->dst = NULL;
     nf_reset(skb);
 #ifdef CONFIG_BRIDGE_NETFILTER
-    // Stop the eth header being clobbered by nf_bridge_maybe_copy_header().
-    // Were using this modified to use h_proto instead of skb->protocol.
     if(skb->nf_bridge){
-        nf_bridge_save_header(skb);
+        // Stop the eth header being clobbered by 
nf_bridge_maybe_copy_header().
+        _nf_bridge_save_header(skb);
     }
 #endif
 #endif // __KERNEL__
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/tunnel.c
--- a/tools/vnet/vnet-module/tunnel.c   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/tunnel.c   Wed Oct 11 13:04:07 2006 -0400
@@ -50,6 +50,12 @@ rwlock_t tunnel_table_lock = RW_LOCK_UNL
 #define tunnel_read_unlock(flags)  read_unlock_irqrestore(&tunnel_table_lock, 
(flags))
 #define tunnel_write_lock(flags)   write_lock_irqsave(&tunnel_table_lock, 
(flags))
 #define tunnel_write_unlock(flags) write_unlock_irqrestore(&tunnel_table_lock, 
(flags))
+
+void Tunnel_free(Tunnel *tunnel){
+    tunnel->type->close(tunnel);
+    Tunnel_decref(tunnel->base);
+    kfree(tunnel);
+}
 
 void Tunnel_print(Tunnel *tunnel){
     if(tunnel){
@@ -136,6 +142,7 @@ int Tunnel_init(void){
         goto exit;
     }
     tunnel_table->entry_free_fn = tunnel_table_entry_free_fn;
+    tunnel_table->key_size = sizeof(TunnelKey);
     tunnel_table->key_hash_fn = tunnel_table_key_hash_fn;
     tunnel_table->key_equal_fn = tunnel_table_key_equal_fn;
   exit:
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/tunnel.h
--- a/tools/vnet/vnet-module/tunnel.h   Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/tunnel.h   Wed Oct 11 13:04:07 2006 -0400
@@ -70,6 +70,8 @@ typedef struct Tunnel {
     struct Tunnel *base;
 } Tunnel;
 
+extern void Tunnel_free(struct Tunnel *tunnel);
+
 /** Decrement the reference count, freeing if zero.
  *
  * @param tunnel tunnel (may be null)
@@ -77,9 +79,7 @@ static inline void Tunnel_decref(struct 
 static inline void Tunnel_decref(struct Tunnel *tunnel){
     if(!tunnel) return;
     if(atomic_dec_and_test(&tunnel->refcount)){
-        tunnel->type->close(tunnel);
-        Tunnel_decref(tunnel->base);
-        kfree(tunnel);
+        Tunnel_free(tunnel);
     }
 }
 
@@ -87,7 +87,7 @@ static inline void Tunnel_decref(struct 
  *
  * @param tunnel tunnel (may be null)
  */
-static inline void Tunnel_incref(Tunnel *tunnel){
+static inline void Tunnel_incref(struct Tunnel *tunnel){
     if(!tunnel) return;
     atomic_inc(&tunnel->refcount);
 }
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/varp.c
--- a/tools/vnet/vnet-module/varp.c     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/varp.c     Wed Oct 11 13:04:07 2006 -0400
@@ -849,6 +849,7 @@ VarpTable * VarpTable_new(void){
     if(!vtable) goto exit;
     vtable->table = HashTable_new(VARP_TABLE_BUCKETS);
     if(!vtable->table) goto exit;
+    vtable->table->key_size = sizeof(VarpKey);
     vtable->table->key_equal_fn = varp_key_equal_fn;
     vtable->table->key_hash_fn = varp_key_hash_fn;
     vtable->table->entry_free_fn = varp_entry_free_fn;
@@ -1529,8 +1530,12 @@ void varp_exit(void){
     dprintf("<\n");
 }
 
+#ifdef MODULE_PARM
 MODULE_PARM(varp_mcaddr, "s");
+MODULE_PARM(varp_device, "s");
+#else
+module_param(varp_mcaddr, charp, 0644);
+module_param(varp_device, charp, 0644);
+#endif
 MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address");
-
-MODULE_PARM(varp_device, "s");
 MODULE_PARM_DESC(varp_device, "VARP network device");
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/varp_socket.c
--- a/tools/vnet/vnet-module/varp_socket.c      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/varp_socket.c      Wed Oct 11 13:04:07 2006 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+ * Copyright (C) 2004, 2005, 2006 Mike Wray <mike.wray@xxxxxx>
  *
  * 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 
@@ -36,7 +36,7 @@
 
 /* Get macros needed to define system calls as functions in the kernel. */
 #define __KERNEL_SYSCALLS__
-static int errno;
+int errno=0;
 #include <linux/unistd.h>
 
 #define MODULE_NAME "VARP"
@@ -73,7 +73,13 @@ static inline _syscall3(int, fcntl,
 
 /* Replicate the user-space socket API.
  * The parts we need anyway.
- */
+ *
+ * Some architectures use socketcall() to multiplex the socket-related calls,
+ * but others define individual syscalls instead.
+ * Architectures using socketcall() define __ARCH_WANT_SYS_SOCKETCALL.
+ */
+
+#ifdef __ARCH_WANT_SYS_SOCKETCALL
 
 /* Define the socketcall() syscall.
  * Multiplexes all the socket-related calls.
@@ -179,6 +185,66 @@ int getsockname(int fd, struct sockaddr 
     args[2] = (unsigned long)usockaddr_len;
     return socketcall(SYS_GETSOCKNAME, args);
 }
+
+#else /* !__ARCH_WANT_SYS_SOCKETCALL */
+
+/* No socketcall - define the individual syscalls. */
+
+static inline _syscall3(int, socket,
+                        int, family,
+                        int, type,
+                        int, protocol);
+
+static inline _syscall3(int, bind,
+                        int, fd,
+                        struct sockaddr *, umyaddr,
+                        int, addrlen);
+
+static inline _syscall3(int, connect,
+                        int, fd,
+                        struct sockaddr *, uservaddr,
+                        int, addrlen);
+
+static inline _syscall6(int, sendto,
+                        int, fd,
+                        void *, buff,
+                        size_t, len,
+                        unsigned, flags,
+                        struct sockaddr *, addr,
+                        int, addr_len);
+
+static inline _syscall6(int, recvfrom,
+                        int, fd,
+                        void *, ubuf,
+                        size_t, size,
+                        unsigned, flags,
+                        struct sockaddr *, addr,
+                        int *, addr_len);
+
+static inline _syscall5(int, setsockopt,
+                        int, fd,
+                        int, level,
+                        int, optname,
+                        void *, optval,
+                        int, optlen);
+
+static inline _syscall5(int, getsockopt,
+                        int, fd,
+                        int, level,
+                        int, optname,
+                        void *, optval,
+                        int *, optlen);
+
+static inline _syscall2(int, shutdown,
+                        int, fd,
+                        int, how);
+
+static inline _syscall3(int, getsockname,
+                        int, fd,
+                        struct sockaddr *, usockaddr,
+                        int *, usockaddr_len);
+
+#endif /* __ARCH_WANT_SYS_SOCKETCALL */
 
 
/*============================================================================*/
 /** Socket flags. */
@@ -418,9 +484,7 @@ int varp_ucast_open(uint32_t addr, u16 p
  * an error.
  */
 static int handle_varp_skb(struct sk_buff *skb){
-    static int count = 0;
-    int err = 0;
-    count++;
+    int err = 0;
     switch(skb->pkt_type){
     case PACKET_BROADCAST:
     case PACKET_MULTICAST:
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vif.c
--- a/tools/vnet/vnet-module/vif.c      Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/vif.c      Wed Oct 11 13:04:07 2006 -0400
@@ -366,6 +366,7 @@ int vif_init(void){
         goto exit;
     }
     vif_table->entry_free_fn = vif_entry_free_fn;
+    vif_table->key_size = sizeof(VifKey);
     vif_table->key_hash_fn   = vif_key_hash_fn;
     vif_table->key_equal_fn  = vif_key_equal_fn;
 
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet.c
--- a/tools/vnet/vnet-module/vnet.c     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/vnet.c     Wed Oct 11 13:04:07 2006 -0400
@@ -318,6 +318,7 @@ int vnet_table_init(void){
         err = -ENOMEM;
         goto exit;
     }
+    vnet_table->key_size = sizeof(VnetId);
     vnet_table->key_equal_fn = vnet_key_equal_fn;
     vnet_table->key_hash_fn = vnet_key_hash_fn;
     vnet_table->entry_free_fn = vnet_entry_free_fn;
@@ -431,14 +432,14 @@ inline int _skb_xmit(struct sk_buff *skb
 
     ip_send_check(skb->nh.iph);
 
-    if(1){
+#if 1
         // Output to skb destination. Will use ip_output(), which fragments.
         // Slightly slower than neigh_compat_output() (marginal - 1%).
         err = dst_output(skb); 
-    } else {
+#else
         // Sends direct to device via dev_queue_xmit(). No fragmentation?
         err = neigh_compat_output(skb);
-    }
+#endif
 
 #if 0
     if(needs_frags){
@@ -447,6 +448,7 @@ inline int _skb_xmit(struct sk_buff *skb
         err = ip_finish_output(skb);
     }
 #endif
+
   exit:
     dprintf("< err=%d\n", err);
     return err;
@@ -691,7 +693,12 @@ module_exit(vnet_module_exit);
 module_exit(vnet_module_exit);
 MODULE_LICENSE("GPL");
 
+#ifdef MODULE_PARM
 MODULE_PARM(vnet_encaps, "s");
+#else
+module_param(vnet_encaps, charp, 0644);
+#endif
+
 MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp.");
 
 #endif
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet_dev.c
--- a/tools/vnet/vnet-module/vnet_dev.c Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/vnet_dev.c Wed Oct 11 13:04:07 2006 -0400
@@ -49,8 +49,12 @@
 #undef DEBUG
 #include "debug.h"
 
-#ifndef CONFIG_BRIDGE
-#warning Should configure ethernet bridging in kernel Network Options
+#if !defined(CONFIG_BRIDGE) && !defined(CONFIG_BRIDGE_MODULE)
+#warning Should configure Ethernet Bridging in kernel Network Options
+#endif
+
+#ifndef CONFIG_BRIDGE_NETFILTER
+#warning Should configure CONFIG_BRIDGE_NETFILTER in kernel
 #endif
 
 static void vnet_dev_destructor(struct net_device *dev){
@@ -254,7 +258,7 @@ static int vnet_dev_setup(Vnet *vnet, st
     return err;
 }
 
-static inline int roundup(int n, int k){
+static inline int roundupto(int n, int k){
     return k * ((n + k - 1) / k);
 }
 
@@ -275,7 +279,7 @@ int vnet_dev_add(Vnet *vnet){
         vnet->header_n += sizeof(struct VnetMsgHdr);
         vnet->header_n += sizeof(struct udphdr);
     }
-    vnet->header_n = roundup(vnet->header_n, 4);
+    vnet->header_n = roundupto(vnet->header_n, 4);
     dev = alloc_netdev(0, vnet->device, vnet_dev_init);
     if(!dev){
         err = -ENOMEM;
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet_eval.c
--- a/tools/vnet/vnet-module/vnet_eval.c        Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/vnet_eval.c        Wed Oct 11 13:04:07 2006 -0400
@@ -188,7 +188,7 @@ int eval_vnet_add(Sxpr exp, IOStream *ou
     if(err) goto exit;
     child_string(exp, ovnetif, &device);
     if(!device){
-        snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[7]));
+        snprintf(dev, IFNAMSIZ-1, "vnif%04x", 
ntohs(vnet.u.vnet16[VNETID_SIZE16 - 1]));
         device = dev;
     }
     csecurity = sxpr_child_value(exp, osecurity, intern("none"));
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnet-module/vnet_forward.c
--- a/tools/vnet/vnet-module/vnet_forward.c     Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnet-module/vnet_forward.c     Wed Oct 11 13:04:07 2006 -0400
@@ -370,6 +370,7 @@ int vnet_forward_init(void){
         err = -ENOMEM;
         goto exit;
     }
+    vnet_peer_table->key_size = sizeof(struct VarpAddr);
     vnet_peer_table->key_equal_fn = peer_key_equal_fn;
     vnet_peer_table->key_hash_fn = peer_key_hash_fn;
     vnet_peer_table->entry_free_fn = peer_entry_free_fn;
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnetd/Makefile
--- a/tools/vnet/vnetd/Makefile Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnetd/Makefile Wed Oct 11 13:04:07 2006 -0400
@@ -24,7 +24,8 @@ all: vnetd
 
 #----------------------------------------------------------------------------
 
-include $(XEN_ROOT)/tools/Rules.mk
+# Comment out when outside xen.
+#include $(XEN_ROOT)/tools/Rules.mk
 
 VNETD_INSTALL_DIR = /usr/sbin
 
@@ -43,6 +44,7 @@ CPPFLAGS += -D __ARCH_I386_ATOMIC__
 CPPFLAGS += -D __ARCH_I386_ATOMIC__
 
 #----------------------------------------------------------------------------
+CFLAGS += -O3
 CFLAGS += $(INCLUDES) $(LIBS)
 
 LDFLAGS += $(LIBS)
diff -r e7cb3aefc233 -r b53c343b47ae tools/vnet/vnetd/vnetd.c
--- a/tools/vnet/vnetd/vnetd.c  Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/vnet/vnetd/vnetd.c  Wed Oct 11 13:04:07 2006 -0400
@@ -196,7 +196,7 @@ int vnet_dev_add(struct Vnet *vnet){
     if(err){
         wprintf("> Unable to open tap device.\n"
                 "The tun module must be loaded and\n"
-                "the vnet kernel module must not be loaded.");
+                "the vnet kernel module must not be loaded.\n");
         deallocate(dev);
         goto exit;
     }
@@ -764,7 +764,7 @@ static int vnetd_getopts(Vnetd *vnetd, i
  *
  * @param vnetd vnetd
  */
-int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){
+static int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){
     int err = 0;
 
     // Use etherip-in-udp encapsulation.
@@ -791,7 +791,7 @@ int vnetd_init(Vnetd *vnetd, int argc, c
     return err;
 }
 
-void vnet_select(Vnetd *vnetd, SelectSet *set){
+static void vnet_select(Vnetd *vnetd, SelectSet *set){
     HashTable_for_decl(entry);
 
     HashTable_for_each(entry, vnetd->vnet_table){
@@ -803,7 +803,7 @@ void vnet_select(Vnetd *vnetd, SelectSet
     }
 }
 
-void vnet_handle(Vnetd *vnetd, SelectSet *set){
+static void vnet_handle(Vnetd *vnetd, SelectSet *set){
     HashTable_for_decl(entry);
 
     HashTable_for_each(entry, vnetd->vnet_table){
@@ -820,7 +820,7 @@ void vnet_handle(Vnetd *vnetd, SelectSet
     }
 }
 
-int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
+static int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
     int err = 0, n = 0;
     struct sockaddr_in peer, dest;
     socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest);
@@ -851,7 +851,7 @@ int vnetd_handle_udp(Vnetd *vnetd, struc
     return err;
 }
 
-int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
+static int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int 
sock){
     int err = 0, n = 0;
     struct sockaddr_in peer, dest;
     socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest);
@@ -883,7 +883,7 @@ typedef struct ConnClient {
     Parser *parser;
 } ConnClient;
 
-int conn_handle_fn(Conn *conn, int mode){
+static int conn_handle_fn(Conn *conn, int mode){
     int err;
     ConnClient *client = conn->data;
     char data[1024] = {};
@@ -923,12 +923,12 @@ int conn_handle_fn(Conn *conn, int mode)
     return (err < 0 ? err : 0);
 }
 
-int vnetd_handle_unix(Vnetd *vnetd, int sock){
+static int vnetd_handle_unix(Vnetd *vnetd, int sock){
     int err;
     ConnClient *client = NULL;
     Conn *conn = NULL;
     struct sockaddr_un peer = {};
-    int peer_n = sizeof(peer);
+    socklen_t peer_n = sizeof(peer);
     int peersock;
 
     peersock = accept(sock, (struct sockaddr *)&peer, &peer_n);
@@ -956,7 +956,7 @@ int vnetd_handle_unix(Vnetd *vnetd, int 
     return err;
 }
 
-void vnetd_select(Vnetd *vnetd, SelectSet *set){
+static void vnetd_select(Vnetd *vnetd, SelectSet *set){
     SelectSet_add(set, vnetd->unix_sock, SELECT_READ);
     SelectSet_add(set, vnetd->udp_sock, SELECT_READ);
     SelectSet_add(set, vnetd->mcast_sock, SELECT_READ);
@@ -967,7 +967,7 @@ void vnetd_select(Vnetd *vnetd, SelectSe
     ConnList_select(vnetd->conns, set);
 }
 
-void vnetd_handle(Vnetd *vnetd, SelectSet *set){
+static void vnetd_handle(Vnetd *vnetd, SelectSet *set){
     if(SelectSet_in_read(set, vnetd->unix_sock)){
         vnetd_handle_unix(vnetd, vnetd->unix_sock);
     }
@@ -995,7 +995,7 @@ void vnetd_handle(Vnetd *vnetd, SelectSe
  */
 static unsigned timer_alarms = 0;
 
-int vnetd_main(Vnetd *vnetd){
+static int vnetd_main(Vnetd *vnetd){
     int err = 0;
     SelectSet _set = {}, *set = &_set;
     struct timeval _timeout = {}, *timeout = &_timeout;
@@ -1030,12 +1030,12 @@ int vnetd_main(Vnetd *vnetd){
     return err;
 }
 
-int getsockaddr(int sock, struct sockaddr_in *addr){
+static int getsockaddr(int sock, struct sockaddr_in *addr){
     socklen_t addr_n = sizeof(struct sockaddr_in);
     return getsockname(sock, (struct sockaddr*)addr, &addr_n);
 }
 
-int vnetd_etherip_sock(Vnetd *vnetd){
+static int vnetd_etherip_sock(Vnetd *vnetd){
     int err = 0;
 
     if(!vnetd->etherip) goto exit;
@@ -1051,7 +1051,7 @@ int vnetd_etherip_sock(Vnetd *vnetd){
     return err;
 }
 
-int vnetd_udp_sock(Vnetd *vnetd){
+static int vnetd_udp_sock(Vnetd *vnetd){
     int err;
     uint32_t mcaddr = vnetd_mcast_addr(vnetd);
 
@@ -1087,7 +1087,7 @@ int vnetd_udp_sock(Vnetd *vnetd){
     return err;
 }
 
-int vnetd_raw_sock(Vnetd *vnetd){
+static int vnetd_raw_sock(Vnetd *vnetd){
     int err;
 
     err = vnetd_raw_socket(vnetd, IPPROTO_RAW,
@@ -1101,7 +1101,7 @@ int vnetd_raw_sock(Vnetd *vnetd){
     return err;
 }
 
-int vnetd_unix_sock(Vnetd *vnetd){
+static int vnetd_unix_sock(Vnetd *vnetd){
     int err = 0;
     struct sockaddr_un addr = { .sun_family = AF_UNIX };
     socklen_t addr_n;
diff -r e7cb3aefc233 -r b53c343b47ae tools/xm-test/tests/vtpm/vtpm_utils.py
--- a/tools/xm-test/tests/vtpm/vtpm_utils.py    Wed Oct 11 13:01:31 2006 -0400
+++ b/tools/xm-test/tests/vtpm/vtpm_utils.py    Wed Oct 11 13:04:07 2006 -0400
@@ -8,12 +8,10 @@ if ENABLE_HVM_SUPPORT:
 if ENABLE_HVM_SUPPORT:
     SKIP("vtpm tests not supported for HVM domains")
 
-if not os.path.exists("/dev/tpm0"):
-    SKIP("This machine has no hardware TPM; cannot run this test")
-
 status, output = traceCommand("ps aux | grep vtpm_manager | grep -v grep")
 if output == "":
-    FAIL("virtual TPM manager must be started to run this test")
+    SKIP("virtual TPM manager must be started to run this test; might "
+         "need /dev/tpm0")
 
 def vtpm_cleanup(domName):
     traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
diff -r e7cb3aefc233 -r b53c343b47ae 
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Wed Oct 11 
13:01:31 2006 -0400
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Wed Oct 11 
13:04:07 2006 -0400
@@ -231,11 +231,13 @@ static int __devinit platform_pci_init(s
        return ret;
 }
 
-#define XEN_PLATFORM_VENDOR_ID 0xfffd
-#define XEN_PLATFORM_DEVICE_ID 0x0101
+#define XEN_PLATFORM_VENDOR_ID 0x5853
+#define XEN_PLATFORM_DEVICE_ID 0x0001
 static struct pci_device_id platform_pci_tbl[] __devinitdata = {
        {XEN_PLATFORM_VENDOR_ID, XEN_PLATFORM_DEVICE_ID,
         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       /* Continue to recognise the old ID for now */
+       {0xfffd, 0x0101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0,}
 };
 
diff -r e7cb3aefc233 -r b53c343b47ae xen/Makefile
--- a/xen/Makefile      Wed Oct 11 13:01:31 2006 -0400
+++ b/xen/Makefile      Wed Oct 11 13:04:07 2006 -0400
@@ -123,19 +123,29 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
 
 SUBDIRS = acm arch/$(TARGET_ARCH) common drivers 
 define all_sources
-    ( find include/asm-$(TARGET_ARCH) -name SCCS -prune -o -name '*.h' -print; 
\
-      find include -type d -name SCCS -prune -o \( -name "asm-*" -o \
-            -name config \) -prune -o -name '*.h' -print; \
-      find $(SUBDIRS) -name SCCS -prune -o -name '*.[chS]' -print )
+    ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
+      find include -name 'asm-*' -prune -o -name '*.h' -print; \
+      find $(SUBDIRS) -name '*.[chS]' -print )
+endef
+
+define set_exuberant_flags
+    exuberant_flags=`$1 --version 2>/dev/null | grep -iq exuberant && \
+       echo "-I __initdata,__exitdata,__acquires,__releases \
+           -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
+           --extra=+f --c-kinds=+px"`
 endef
 
 .PHONY: _TAGS
 _TAGS: 
-       rm -f TAGS && $(all_sources) | xargs etags -a
+       rm -f TAGS; \
+       $(call set_exuberant_flags,etags); \
+       $(all_sources) | xargs etags $$exuberant_flags -a
 
 .PHONY: _tags
 _tags: 
-       rm -f TAGS && $(all_sources) | xargs ctags -a
+       rm -f tags; \
+       $(call set_exuberant_flags,ctags); \
+       $(all_sources) | xargs ctags $$exuberant_flags -a
 
 .PHONY: _cscope
 _cscope:
diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile    Wed Oct 11 13:01:31 2006 -0400
+++ b/xen/arch/ia64/Makefile    Wed Oct 11 13:04:07 2006 -0400
@@ -4,22 +4,27 @@ subdir-y += linux-xen
 subdir-y += linux-xen
 
 $(TARGET)-syms: linux-xen/head.o $(ALL_OBJS) xen.lds.s
+       $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o
        $(LD) $(LDFLAGS) -T xen.lds.s -N \
-               -Map map.out linux-xen/head.o $(ALL_OBJS) -o $@
+               -Map map.out linux-xen/head.o $(ALL_OBJS) \
+               $(BASEDIR)/common/symbols-dummy.o -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols > $(BASEDIR)/xen-syms.S
        $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o
        $(LD) $(LDFLAGS) -T xen.lds.s -N \
-               -Map map.out linux-xen/head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o 
-o $@
+               -Map map.out linux-xen/head.o $(ALL_OBJS) \
+               $(BASEDIR)/xen-syms.o -o $@
        $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
        $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/xen-syms.o
        $(LD) $(LDFLAGS) -T xen.lds.s -N \
-               -Map map.out linux-xen/head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o 
-o $@
+               -Map map.out linux-xen/head.o $(ALL_OBJS) \
+               $(BASEDIR)/xen-syms.o -o $@
        rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o
 
 $(TARGET): $(TARGET)-syms
        $(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $@
-       $(NM) -n $(TARGET)-syms | grep -v '\( [aUw] \)\|\(__crc_\)\|\( 
\$[adt]\)'\
-                > $(BASEDIR)/System.map
+       $(NM) -n $(TARGET)-syms | \
+               grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' \
+               > $(BASEDIR)/System.map
 
 # Headers do not depend on auto-generated header, but object files do.
 HDRS    := $(subst $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h,,$(HDRS))
diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Wed Oct 11 13:01:31 2006 -0400
+++ b/xen/arch/ia64/xen/domain.c        Wed Oct 11 13:04:07 2006 -0400
@@ -54,7 +54,6 @@ static unsigned int dom0_max_vcpus = 1;
 static unsigned int dom0_max_vcpus = 1;
 integer_param("dom0_max_vcpus", dom0_max_vcpus); 
 
-extern int opt_dom0_vcpus_pin;
 extern unsigned long running_on_sim;
 
 extern char dom0_command_line[];
@@ -1021,12 +1020,9 @@ int construct_dom0(struct domain *d,
            dom0_max_vcpus = MAX_VIRT_CPUS;
        
        printf ("Dom0 max_vcpus=%d\n", dom0_max_vcpus);
-       for ( i = 1; i < dom0_max_vcpus; i++ ) {
+       for ( i = 1; i < dom0_max_vcpus; i++ )
            if (alloc_vcpu(d, i, i) == NULL)
                printf ("Cannot allocate dom0 vcpu %d\n", i);
-           else if (opt_dom0_vcpus_pin)
-               d->vcpu[i]->cpu_affinity = cpumask_of_cpu(i);
-       }
 
        /* Copy the OS image. */
        loaddomainelfimage(d,image_start);
diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Wed Oct 11 13:01:31 2006 -0400
+++ b/xen/arch/ia64/xen/xensetup.c      Wed Oct 11 13:04:07 2006 -0400
@@ -18,6 +18,7 @@
 #include <xen/domain.h>
 #include <xen/serial.h>
 #include <xen/trace.h>
+#include <xen/keyhandler.h>
 #include <asm/meminit.h>
 #include <asm/page.h>
 #include <asm/setup.h>
@@ -38,7 +39,6 @@ int find_max_pfn (unsigned long, unsigne
 int find_max_pfn (unsigned long, unsigned long, void *);
 
 /* FIXME: which header these declarations should be there ? */
-extern void initialize_keytable(void);
 extern long is_platform_hp_ski(void);
 extern void early_setup_arch(char **);
 extern void late_setup_arch(char **);
@@ -48,10 +48,6 @@ extern void mem_init(void);
 extern void mem_init(void);
 extern void init_IRQ(void);
 extern void trap_init(void);
-
-/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
-unsigned int opt_dom0_vcpus_pin = 0;
-boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
 
 /* opt_nosmp: If true, secondary processors are ignored. */
 static int opt_nosmp = 0;
@@ -521,10 +517,6 @@ printk("num_online_cpus=%d, max_cpus=%d\
                        0) != 0)
         panic("Could not set up DOM0 guest OS\n");
 
-    /* PIN domain0 VCPU 0 on CPU 0. */
-    if (opt_dom0_vcpus_pin)
-        dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
-
     if (!running_on_sim)  // slow on ski and pages are pre-initialized to zero
        scrub_heap_pages();
 
diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Wed Oct 11 13:01:31 2006 -0400
+++ b/xen/arch/powerpc/Makefile Wed Oct 11 13:04:07 2006 -0400
@@ -100,7 +100,8 @@ TARGET_OPTS += start.o $(ALL_OBJS)
 TARGET_OPTS += start.o $(ALL_OBJS)
 
 .xen-syms: start.o $(ALL_OBJS) xen.lds
-       $(CC) $(CFLAGS) $(TARGET_OPTS) -o $@
+       $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o
+       $(CC) $(CFLAGS) $(TARGET_OPTS) $(BASEDIR)/common/symbols-dummy.o -o $@
 
 NM=$(CROSS_COMPILE)nm
 new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; 
then echo y; else echo n; fi)
diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Wed Oct 11 13:01:31 2006 -0400
+++ b/xen/arch/powerpc/setup.c  Wed Oct 11 13:04:07 2006 -0400
@@ -88,9 +88,6 @@ struct ns16550_defaults ns16550;
 
 extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[];
 
-/* move us to a header file */
-extern void initialize_keytable(void);
-
 volatile struct processor_area * volatile global_cpu_table[NR_CPUS];
 
 int is_kernel_text(unsigned long addr)
diff -r e7cb3aefc233 -r b53c343b47ae xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Wed Oct 11 13:01:31 2006 -0400
+++ b/xen/arch/x86/Makefile     Wed Oct 11 13:04:07 2006 -0400
@@ -46,20 +46,25 @@ obj-$(crash_debug) += gdbstub.o
 
 $(TARGET): $(TARGET)-syms boot/mkelf32
        ./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
-       `$(NM) $(TARGET)-syms | sort | tail -n 1 | sed -e 's/^\([^ 
]*\).*/0x\1/'`

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

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [xenppc-unstable] [POWERPC] merge with xen-unstable f7d65fb7299b, Xen patchbot-xenppc-unstable <=