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

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



# 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


 


Rackspace

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