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

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 432f978d1cd1351c5da6b5b15ff516ec9c07fa3c
# Parent  da942e577e5e965275644909d91d4a26528c9dba
# Parent  c4f3f719d997522ae82e065d4f93d5af6494a750
merge with xen-unstable.hg
---
 patches/linux-2.6.16.13/blktap-aio-16_03_06.patch                              
          |  274 -
 patches/linux-2.6.16.13/device_bind.patch                                      
          |   14 
 patches/linux-2.6.16.13/fix-hz-suspend.patch                                   
          |   25 
 patches/linux-2.6.16.13/fix-ide-cd-pio-mode.patch                              
          |   13 
 patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch                           
          |   35 
 patches/linux-2.6.16.13/ipv6-no-autoconf.patch                                 
          |   22 
 patches/linux-2.6.16.13/net-csum.patch                                         
          |   57 
 patches/linux-2.6.16.13/net-gso-0-base.patch                                   
          | 2510 ----------
 patches/linux-2.6.16.13/net-gso-1-check-dodgy.patch                            
          |   22 
 patches/linux-2.6.16.13/net-gso-2-checksum-fix.patch                           
          |  400 -
 patches/linux-2.6.16.13/net-gso-3-fix-errorcheck.patch                         
          |   13 
 patches/linux-2.6.16.13/net-gso-4-kill-warnon.patch                            
          |   18 
 patches/linux-2.6.16.13/pmd-shared.patch                                       
          |  100 
 patches/linux-2.6.16.13/rcu_needs_cpu.patch                                    
          |   31 
 patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch     
          |   26 
 patches/linux-2.6.16.13/series                                                 
          |   23 
 patches/linux-2.6.16.13/smp-alts.patch                                         
          |  540 --
 patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch                                
          | 1381 -----
 patches/linux-2.6.16.13/x86-elfnote-as-preprocessor-macro.patch                
          |   28 
 patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch              
          |   73 
 
patches/linux-2.6.16.13/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
    |  168 
 
patches/linux-2.6.16.13/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
 |   71 
 patches/linux-2.6.16.13/xen-hotplug.patch                                      
          |    9 
 patches/linux-2.6.16.13/xenoprof-generic.patch                                 
          |  568 --
 tools/python/xen/xm/sysrq.py                                                   
          |   31 
 xen/arch/powerpc/dom0_ops.c                                                    
          |  138 
 .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 
 buildconfigs/mk.linux-2.6-xen                                                  
          |    2 
 extras/mini-os/arch/x86/setup.c                                                
          |  108 
 extras/mini-os/events.c                                                        
          |   33 
 extras/mini-os/include/events.h                                                
          |    7 
 extras/mini-os/include/x86/os.h                                                
          |    5 
 extras/mini-os/include/x86/x86_32/hypercall-x86_32.h                           
          |    6 
 extras/mini-os/kernel.c                                                        
          |   67 
 linux-2.6-xen-sparse/arch/i386/Kconfig                                         
          |    3 
 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c                              
          |   46 
 linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c                             
          |   91 
 linux-2.6-xen-sparse/arch/ia64/Kconfig                                         
          |    3 
 linux-2.6-xen-sparse/arch/ia64/dig/setup.c                                     
          |   23 
 linux-2.6-xen-sparse/arch/x86_64/Kconfig                                       
          |    2 
 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S                            
          |    7 
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c                            
          |   49 
 linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c                            
          |    5 
 linux-2.6-xen-sparse/drivers/char/tty_io.c                                     
          |   14 
 linux-2.6-xen-sparse/drivers/serial/Kconfig                                    
          |    1 
 linux-2.6-xen-sparse/drivers/xen/console/console.c                             
          |   36 
 linux-2.6-xen-sparse/include/xen/xencons.h                                     
          |    3 
 linux-2.6-xen-sparse/mm/Kconfig                                                
          |    2 
 linux-2.6-xen-sparse/mm/page_alloc.c                                           
          |    3 
 patches/linux-2.6.16.29/blktap-aio-16_03_06.patch                              
          |  161 
 patches/linux-2.6.16.29/device_bind.patch                                      
          |    9 
 patches/linux-2.6.16.29/fix-hz-suspend.patch                                   
          |    9 
 patches/linux-2.6.16.29/fix-ide-cd-pio-mode.patch                              
          |   13 
 patches/linux-2.6.16.29/i386-mach-io-check-nmi.patch                           
          |   30 
 patches/linux-2.6.16.29/ipv6-no-autoconf.patch                                 
          |   16 
 patches/linux-2.6.16.29/net-csum.patch                                         
          |   40 
 patches/linux-2.6.16.29/net-gso-0-base.patch                                   
          | 1906 +++++++
 patches/linux-2.6.16.29/net-gso-1-check-dodgy.patch                            
          |   16 
 patches/linux-2.6.16.29/net-gso-2-checksum-fix.patch                           
          |  311 +
 patches/linux-2.6.16.29/net-gso-3-fix-errorcheck.patch                         
          |   13 
 patches/linux-2.6.16.29/net-gso-4-kill-warnon.patch                            
          |   26 
 patches/linux-2.6.16.29/pci-mmconfig-fix-from-2.6.17.patch                     
          |  143 
 patches/linux-2.6.16.29/pmd-shared.patch                                       
          |   57 
 patches/linux-2.6.16.29/rcu_needs_cpu.patch                                    
          |   18 
 patches/linux-2.6.16.29/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch     
          |   26 
 patches/linux-2.6.16.29/series                                                 
          |   24 
 patches/linux-2.6.16.29/smp-alts.patch                                         
          |  330 +
 patches/linux-2.6.16.29/tpm_plugin_2.6.17.patch                                
          |  703 ++
 patches/linux-2.6.16.29/x86-elfnote-as-preprocessor-macro.patch                
          |   25 
 patches/linux-2.6.16.29/x86-increase-interrupt-vector-range.patch              
          |   73 
 
patches/linux-2.6.16.29/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
    |   39 
 
patches/linux-2.6.16.29/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
 |   63 
 patches/linux-2.6.16.29/xen-hotplug.patch                                      
          |   10 
 patches/linux-2.6.16.29/xenoprof-generic.patch                                 
          |  268 +
 tools/check/check_python                                                       
          |    2 
 tools/console/daemon/io.c                                                      
          |   10 
 tools/debugger/gdb/gdbbuild                                                    
          |    2 
 tools/examples/locking.sh                                                      
          |    2 
 tools/firmware/vmxassist/machine.h                                             
          |    1 
 tools/firmware/vmxassist/vm86.c                                                
          |   87 
 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/target-i386-dm/helper2.c                                           
          |    4 
 tools/ioemu/usb-linux.c                                                        
          |    1 
 tools/ioemu/vl.c                                                               
          |    6 
 tools/ioemu/vl.h                                                               
          |    1 
 tools/ioemu/vnc.c                                                              
          |  256 -
 tools/libxc/powerpc64/Makefile                                                 
          |    3 
 tools/libxc/powerpc64/flatdevtree.c                                            
          |  636 ++
 tools/libxc/powerpc64/flatdevtree.h                                            
          |  106 
 tools/libxc/powerpc64/flatdevtree_env.h                                        
          |   94 
 tools/libxc/powerpc64/xc_linux_build.c                                         
          |  200 
 tools/libxc/powerpc64/xc_memory.c                                              
          |   42 
 tools/libxc/xc_ptrace.c                                                        
          |   11 
 tools/pygrub/Makefile                                                          
          |    2 
 tools/pygrub/src/fsys/ext2/__init__.py                                         
          |    2 
 tools/pygrub/src/fsys/reiser/__init__.py                                       
          |    1 
 tools/python/xen/util/blkif.py                                                 
          |    4 
 tools/python/xen/xend/XendBootloader.py                                        
          |    3 
 tools/python/xen/xend/XendDomain.py                                            
          |   28 
 tools/python/xen/xend/XendDomainInfo.py                                        
          |   50 
 tools/python/xen/xend/image.py                                                 
          |    4 
 tools/python/xen/xend/server/DevController.py                                  
          |    2 
 tools/python/xen/xend/server/blkif.py                                          
          |    6 
 tools/python/xen/xend/server/tpmif.py                                          
          |    2 
 tools/python/xen/xm/addlabel.py                                                
          |   37 
 tools/python/xen/xm/cfgbootpolicy.py                                           
          |   25 
 tools/python/xen/xm/console.py                                                 
          |    2 
 tools/python/xen/xm/create.py                                                  
          |   81 
 tools/python/xen/xm/dry-run.py                                                 
          |   19 
 tools/python/xen/xm/dumppolicy.py                                              
          |   11 
 tools/python/xen/xm/getlabel.py                                                
          |   36 
 tools/python/xen/xm/labels.py                                                  
          |   77 
 tools/python/xen/xm/loadpolicy.py                                              
          |   19 
 tools/python/xen/xm/main.py                                                    
          |  707 +-
 tools/python/xen/xm/makepolicy.py                                              
          |   10 
 tools/python/xen/xm/migrate.py                                                 
          |   16 
 tools/python/xen/xm/opts.py                                                    
          |   92 
 tools/python/xen/xm/resources.py                                               
          |   25 
 tools/python/xen/xm/rmlabel.py                                                 
          |   32 
 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/xenmon/xenmon.py                                                         
          |    5 
 tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py                              
          |    2 
 tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py                                   
          |    2 
 tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py                                   
          |    2 
 unmodified_drivers/linux-2.6/mkbuildtree                                       
          |    6 
 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c                       
          |   11 
 xen/Makefile                                                                   
          |   27 
 xen/arch/ia64/xen/mm.c                                                         
          |   95 
 xen/arch/ia64/xen/xensetup.c                                                   
          |    1 
 xen/arch/powerpc/0opt.c                                                        
          |    4 
 xen/arch/powerpc/Makefile                                                      
          |    4 
 xen/arch/powerpc/backtrace.c                                                   
          |   17 
 xen/arch/powerpc/boot_of.c                                                     
          |  192 
 xen/arch/powerpc/dart.c                                                        
          |   23 
 xen/arch/powerpc/domain.c                                                      
          |   87 
 xen/arch/powerpc/domctl.c                                                      
          |  118 
 xen/arch/powerpc/elf32.c                                                       
          |    2 
 xen/arch/powerpc/exceptions.c                                                  
          |   45 
 xen/arch/powerpc/exceptions.h                                                  
          |    1 
 xen/arch/powerpc/external.c                                                    
          |    9 
 xen/arch/powerpc/hcalls.c                                                      
          |    3 
 xen/arch/powerpc/iommu.c                                                       
          |    2 
 xen/arch/powerpc/mm.c                                                          
          |  263 -
 xen/arch/powerpc/mpic_init.c                                                   
          |   61 
 xen/arch/powerpc/of-devtree.h                                                  
          |   17 
 xen/arch/powerpc/of_handler/xencomm.c                                          
          |   10 
 xen/arch/powerpc/ofd_fixup.c                                                   
          |   31 
 xen/arch/powerpc/oftree.h                                                      
          |    2 
 xen/arch/powerpc/papr/xlate.c                                                  
          |   79 
 xen/arch/powerpc/powerpc64/Makefile                                            
          |    3 
 xen/arch/powerpc/powerpc64/domain.c                                            
          |   55 
 xen/arch/powerpc/powerpc64/exceptions.S                                        
          |   67 
 xen/arch/powerpc/powerpc64/io.S                                                
          |   26 
 xen/arch/powerpc/powerpc64/ppc970.c                                            
          |  212 
 xen/arch/powerpc/powerpc64/ppc970_machinecheck.c                               
          |  120 
 xen/arch/powerpc/powerpc64/ppc970_scom.c                                       
          |  117 
 xen/arch/powerpc/setup.c                                                       
          |   50 
 xen/arch/powerpc/shadow.c                                                      
          |    5 
 xen/arch/powerpc/smp-tbsync.c                                                  
          |  186 
 xen/arch/powerpc/sysctl.c                                                      
          |   65 
 xen/arch/powerpc/time.c                                                        
          |   36 
 xen/arch/powerpc/usercopy.c                                                    
          |   53 
 xen/arch/x86/Rules.mk                                                          
          |    3 
 xen/arch/x86/acpi/boot.c                                                       
          |   81 
 xen/arch/x86/apic.c                                                            
          |   95 
 xen/arch/x86/boot/x86_64.S                                                     
          |   49 
 xen/arch/x86/domain_build.c                                                    
          |   17 
 xen/arch/x86/domctl.c                                                          
          |   58 
 xen/arch/x86/flushtlb.c                                                        
          |  101 
 xen/arch/x86/hvm/hvm.c                                                         
          |    1 
 xen/arch/x86/hvm/i8259.c                                                       
          |   46 
 xen/arch/x86/hvm/platform.c                                                    
          |   10 
 xen/arch/x86/hvm/svm/svm.c                                                     
          |  189 
 xen/arch/x86/hvm/vioapic.c                                                     
          |   32 
 xen/arch/x86/hvm/vlapic.c                                                      
          |   39 
 xen/arch/x86/hvm/vmx/io.c                                                      
          |    8 
 xen/arch/x86/hvm/vmx/vmx.c                                                     
          |  139 
 xen/arch/x86/io_apic.c                                                         
          |    8 
 xen/arch/x86/mm.c                                                              
          |  361 -
 xen/arch/x86/mm/shadow/common.c                                                
          |   30 
 xen/arch/x86/mm/shadow/multi.c                                                 
          |   16 
 xen/arch/x86/mpparse.c                                                         
          |   61 
 xen/arch/x86/oprofile/nmi_int.c                                                
          |   25 
 xen/arch/x86/oprofile/xenoprof.c                                               
          |  103 
 xen/arch/x86/setup.c                                                           
          |    3 
 xen/arch/x86/smpboot.c                                                         
          |    2 
 xen/arch/x86/traps.c                                                           
          |   44 
 xen/arch/x86/x86_32/entry.S                                                    
          |    2 
 xen/arch/x86/x86_64/entry.S                                                    
          |    2 
 xen/arch/x86/x86_64/mm.c                                                       
          |   20 
 xen/arch/x86/x86_64/traps.c                                                    
          |    6 
 xen/common/domctl.c                                                            
          |   43 
 xen/common/gdbstub.c                                                           
          |   52 
 xen/common/sched_credit.c                                                      
          |   99 
 xen/common/sched_sedf.c                                                        
          |   15 
 xen/common/schedule.c                                                          
          |   50 
 xen/drivers/acpi/tables.c                                                      
          |  473 -
 xen/drivers/char/console.c                                                     
          |   36 
 xen/drivers/video/vga.c                                                        
          |   11 
 xen/include/asm-ia64/mm.h                                                      
          |    8 
 xen/include/asm-powerpc/cache.h                                                
          |   11 
 xen/include/asm-powerpc/config.h                                               
          |    3 
 xen/include/asm-powerpc/current.h                                              
          |    2 
 xen/include/asm-powerpc/debugger.h                                             
          |   19 
 xen/include/asm-powerpc/domain.h                                               
          |    5 
 xen/include/asm-powerpc/flushtlb.h                                             
          |    3 
 xen/include/asm-powerpc/guest_access.h                                         
          |    2 
 xen/include/asm-powerpc/io.h                                                   
          |    2 
 xen/include/asm-powerpc/mm.h                                                   
          |   29 
 xen/include/asm-powerpc/page.h                                                 
          |   19 
 xen/include/asm-powerpc/percpu.h                                               
          |   16 
 xen/include/asm-powerpc/powerpc64/ppc970-hid.h                                 
          |  105 
 xen/include/asm-powerpc/powerpc64/procarea.h                                   
          |    1 
 xen/include/asm-powerpc/powerpc64/processor.h                                  
          |   35 
 xen/include/asm-powerpc/processor.h                                            
          |   19 
 xen/include/asm-powerpc/reg_defs.h                                             
          |    5 
 xen/include/asm-powerpc/shadow.h                                               
          |   13 
 xen/include/asm-powerpc/smp.h                                                  
          |    8 
 xen/include/asm-powerpc/system.h                                               
          |    4 
 xen/include/asm-powerpc/time.h                                                 
          |   45 
 xen/include/asm-x86/apicdef.h                                                  
          |    1 
 xen/include/asm-x86/flushtlb.h                                                 
          |    7 
 xen/include/asm-x86/hvm/hvm.h                                                  
          |    7 
 xen/include/asm-x86/hvm/svm/emulate.h                                          
          |   32 
 xen/include/asm-x86/hvm/vlapic.h                                               
          |   30 
 xen/include/asm-x86/hvm/vmx/vmcs.h                                             
          |    3 
 xen/include/asm-x86/hvm/vmx/vmx.h                                              
          |   44 
 xen/include/asm-x86/io_apic.h                                                  
          |    1 
 xen/include/asm-x86/mm.h                                                       
          |   72 
 xen/include/asm-x86/shadow.h                                                   
          |   14 
 xen/include/asm-x86/x86_32/page-3level.h                                       
          |    2 
 xen/include/asm-x86/x86_64/page.h                                              
          |   15 
 xen/include/public/xen.h                                                       
          |   50 
 xen/include/public/xenoprof.h                                                  
          |   15 
 xen/include/xen/compiler.h                                                     
          |    5 
 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                                                        
          |   17 
 xen/tools/figlet/figlet.c                                                      
          |    5 
 283 files changed, 10510 insertions(+), 9668 deletions(-)

diff -r da942e577e5e -r 432f978d1cd1 .hgignore
--- a/.hgignore Thu Sep 21 15:35:45 2006 -0600
+++ b/.hgignore Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Thu Sep 21 15:35:45 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64    Thu Sep 21 15:35:45 2006 -0600
+++ b/buildconfigs/linux-defconfig_xenU_ia64    Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Thu Sep 21 15:35:45 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_ia64     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Thu Sep 21 15:35:45 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Thu Sep 21 15:35:45 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Thu Sep 21 15:35:45 2006 -0600
+++ b/buildconfigs/mk.linux-2.6-xen     Sun Sep 24 13:10:13 2006 -0600
@@ -1,5 +1,5 @@ LINUX_SERIES = 2.6
 LINUX_SERIES = 2.6
-LINUX_VER    = 2.6.16.13
+LINUX_VER    = 2.6.16.29
 
 EXTRAVERSION ?= xen
 
diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/events.c
--- a/extras/mini-os/events.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/extras/mini-os/events.c   Sun Sep 24 13:10:13 2006 -0600
@@ -88,19 +88,18 @@ void unbind_evtchn(evtchn_port_t port )
 
 int bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
 {
-       evtchn_op_t op;
+       evtchn_bind_virq_t op;
 
        /* Try to bind the virq to a port */
-       op.cmd = EVTCHNOP_bind_virq;
-       op.u.bind_virq.virq = virq;
-       op.u.bind_virq.vcpu = smp_processor_id();
+       op.virq = virq;
+       op.vcpu = smp_processor_id();
 
-       if ( HYPERVISOR_event_channel_op(&op) != 0 )
+       if ( HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op) != 0 )
        {
                printk("Failed to bind virtual IRQ %d\n", virq);
                return 1;
     }
-    bind_evtchn(op.u.bind_virq.port, handler, data);
+    bind_evtchn(op.port, handler, data);
        return 0;
 }
 
@@ -151,14 +150,13 @@ int evtchn_alloc_unbound(domid_t pal, ev
 int evtchn_alloc_unbound(domid_t pal, evtchn_handler_t handler,
                                                 void *data, evtchn_port_t 
*port)
 {
-    evtchn_op_t op;
-    op.cmd = EVTCHNOP_alloc_unbound;
-    op.u.alloc_unbound.dom = DOMID_SELF;
-    op.u.alloc_unbound.remote_dom = pal;
-    int err = HYPERVISOR_event_channel_op(&op);
+    evtchn_alloc_unbound_t op;
+    op.dom = DOMID_SELF;
+    op.remote_dom = pal;
+    int err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
     if (err)
                return err;
-    *port = bind_evtchn(op.u.alloc_unbound.port, handler, data);
+    *port = bind_evtchn(op.port, handler, data);
     return err;
 }
 
@@ -169,14 +167,13 @@ int evtchn_bind_interdomain(domid_t pal,
                            evtchn_handler_t handler, void *data,
                            evtchn_port_t *local_port)
 {
-    evtchn_op_t op;
-    op.cmd = EVTCHNOP_bind_interdomain;
-    op.u.bind_interdomain.remote_dom = pal;
-    op.u.bind_interdomain.remote_port = remote_port;
-    int err = HYPERVISOR_event_channel_op(&op);
+    evtchn_bind_interdomain_t op;
+    op.remote_dom = pal;
+    op.remote_port = remote_port;
+    int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
     if (err)
                return err;
-       evtchn_port_t port = op.u.bind_interdomain.local_port;
+       evtchn_port_t port = op.local_port;
     clear_evtchn(port);              /* Without, handler gets invoked now! */
     *local_port = bind_evtchn(port, handler, data);
     return err;
diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h   Thu Sep 21 15:35:45 2006 -0600
+++ b/extras/mini-os/include/events.h   Sun Sep 24 13:10:13 2006 -0600
@@ -39,10 +39,9 @@ int evtchn_bind_interdomain(domid_t pal,
 
 static inline int notify_remote_via_evtchn(evtchn_port_t port)
 {
-    evtchn_op_t op;
-    op.cmd = EVTCHNOP_send;
-    op.u.send.port = port;
-    return HYPERVISOR_event_channel_op(&op);
+    evtchn_send_t op;
+    op.port = port;
+    return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op);
 }
 
 
diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/include/x86/os.h
--- a/extras/mini-os/include/x86/os.h   Thu Sep 21 15:35:45 2006 -0600
+++ b/extras/mini-os/include/x86/os.h   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 
extras/mini-os/include/x86/x86_32/hypercall-x86_32.h
--- a/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h      Thu Sep 21 
15:35:45 2006 -0600
+++ b/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h      Sun Sep 24 
13:10:13 2006 -0600
@@ -238,9 +238,9 @@ HYPERVISOR_update_va_mapping(
 
 static inline int
 HYPERVISOR_event_channel_op(
-       void *op)
-{
-       return _hypercall1(int, event_channel_op, op);
+       int cmd, void *op)
+{
+       return _hypercall2(int, event_channel_op, cmd, op);
 }
 
 static inline int
diff -r da942e577e5e -r 432f978d1cd1 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/extras/mini-os/kernel.c   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig    Thu Sep 21 15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig    Sun Sep 24 13:10:13 2006 -0600
@@ -789,6 +789,9 @@ config DOUBLEFAULT
 
 endmenu
 
+config ARCH_ENABLE_MEMORY_HOTPLUG
+       def_bool y
+       depends on HIGHMEM
 
 menu "Power management options (ACPI, APM)"
        depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)
diff -r da942e577e5e -r 432f978d1cd1 
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Thu Sep 21 15:35:45 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Sun Sep 24 13:10:13 
2006 -0600
@@ -65,6 +65,7 @@
 #include <xen/interface/physdev.h>
 #include <xen/interface/memory.h>
 #include <xen/features.h>
+#include <xen/xencons.h>
 #include "setup_arch_pre.h"
 #include <bios_ebda.h>
 
@@ -155,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 *);
@@ -1450,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;
@@ -1460,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)
@@ -1485,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
@@ -1665,33 +1667,15 @@ void __init setup_arch(char **cmdline_p)
                screen_info.orig_video_cols = 80;
                screen_info.orig_video_ega_bx = 3;
                screen_info.orig_video_points = 16;
+               screen_info.orig_y = screen_info.orig_video_lines - 1;
                if (xen_start_info->console.dom0.info_size >=
                    sizeof(struct dom0_vga_console_info)) {
                        const struct dom0_vga_console_info *info =
                                (struct dom0_vga_console_info *)(
                                        (char *)xen_start_info +
                                        xen_start_info->console.dom0.info_off);
-                       screen_info.orig_video_mode = info->txt_mode;
-                       screen_info.orig_video_isVGA = info->video_type;
-                       screen_info.orig_video_lines = info->video_height;
-                       screen_info.orig_video_cols = info->video_width;
-                       screen_info.orig_video_points = info->txt_points;
-                       screen_info.lfb_width = info->video_width;
-                       screen_info.lfb_height = info->video_height;
-                       screen_info.lfb_depth = info->lfb_depth;
-                       screen_info.lfb_base = info->lfb_base;
-                       screen_info.lfb_size = info->lfb_size;
-                       screen_info.lfb_linelength = info->lfb_linelen;
-                       screen_info.red_size = info->red_size;
-                       screen_info.red_pos = info->red_pos;
-                       screen_info.green_size = info->green_size;
-                       screen_info.green_pos = info->green_pos;
-                       screen_info.blue_size = info->blue_size;
-                       screen_info.blue_pos = info->blue_pos;
-                       screen_info.rsvd_size = info->rsvd_size;
-                       screen_info.rsvd_pos = info->rsvd_pos;
-               }
-               screen_info.orig_y = screen_info.orig_video_lines - 1;
+                       dom0_init_screen_info(info);
+               }
                xen_start_info->console.domU.mfn = 0;
                xen_start_info->console.domU.evtchn = 0;
        } else
diff -r da942e577e5e -r 432f978d1cd1 
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Thu Sep 21 
15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Sun Sep 24 
13:10:13 2006 -0600
@@ -32,6 +32,8 @@
 #include <../../../drivers/oprofile/cpu_buffer.h>
 #include <../../../drivers/oprofile/event_buffer.h>
 
+#define MAX_XENOPROF_SAMPLES 16
+
 static int xenoprof_start(void);
 static void xenoprof_stop(void);
 
@@ -43,7 +45,7 @@ static int active_defined;
 /* sample buffers shared with Xen */
 xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
 /* Shared buffer area */
-char * shared_buffer;
+char * shared_buffer = NULL;
 /* Number of buffers in shared area (one per VCPU) */
 int nbuf;
 /* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
@@ -233,13 +235,57 @@ static int bind_virq(void)
 }
 
 
+static int map_xenoprof_buffer(int max_samples)
+{
+       struct xenoprof_get_buffer get_buffer;
+       struct xenoprof_buf *buf;
+       int npages, ret, i;
+       struct vm_struct *area;
+
+       if ( shared_buffer )
+               return 0;
+
+       get_buffer.max_samples = max_samples;
+
+       if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, &get_buffer)) )
+               return ret;
+
+       nbuf = get_buffer.nbuf;
+       npages = (get_buffer.bufsize * nbuf - 1) / PAGE_SIZE + 1;
+
+       area = alloc_vm_area(npages * PAGE_SIZE);
+       if (area == NULL)
+               return -ENOMEM;
+
+       if ( (ret = direct_kernel_remap_pfn_range(
+                     (unsigned long)area->addr,
+                     get_buffer.buf_maddr >> PAGE_SHIFT,
+                     npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), DOMID_SELF)) 
) {
+               vunmap(area->addr);
+               return ret;
+       }
+
+       shared_buffer = area->addr;
+       for (i=0; i< nbuf; i++) {
+               buf = (struct xenoprof_buf*) 
+                       &shared_buffer[i * get_buffer.bufsize];
+               BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
+               xenoprof_buf[buf->vcpu_id] = buf;
+       }
+
+       return 0;
+}
+
+
 static int xenoprof_setup(void)
 {
        int ret;
        int i;
 
-       ret = bind_virq();
-       if (ret)
+       if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) )
+               return ret;
+
+       if ( (ret = bind_virq()) )
                return ret;
 
        if (is_primary) {
@@ -482,50 +528,18 @@ int __init oprofile_arch_init(struct opr
 int __init oprofile_arch_init(struct oprofile_operations * ops)
 {
        struct xenoprof_init init;
-       struct xenoprof_buf *buf;
-       int npages, ret, i;
-       struct vm_struct *area;
-
-       init.max_samples = 16;
+       int ret, i;
+
        ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
 
        if (!ret) {
-               pgprot_t prot = __pgprot(_KERNPG_TABLE);
-
                num_events = init.num_events;
                is_primary = init.is_primary;
-               nbuf = init.nbuf;
 
                /* just in case - make sure we do not overflow event list 
-                   (i.e. counter_config list) */
+                  (i.e. counter_config list) */
                if (num_events > OP_MAX_COUNTER)
                        num_events = OP_MAX_COUNTER;
-
-               npages = (init.bufsize * nbuf - 1) / PAGE_SIZE + 1;
-
-               area = alloc_vm_area(npages * PAGE_SIZE);
-               if (area == NULL) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               ret = direct_kernel_remap_pfn_range(
-                       (unsigned long)area->addr,
-                       init.buf_maddr >> PAGE_SHIFT,
-                       npages * PAGE_SIZE, prot, DOMID_SELF);
-               if (ret) {
-                       vunmap(area->addr);
-                       goto out;
-               }
-
-               shared_buffer = area->addr;
-
-               for (i=0; i< nbuf; i++) {
-                       buf = (struct xenoprof_buf*) 
-                               &shared_buffer[i * init.bufsize];
-                       BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
-                       xenoprof_buf[buf->vcpu_id] = buf;
-               }
 
                /*  cpu_type is detected by Xen */
                cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
@@ -541,7 +555,6 @@ int __init oprofile_arch_init(struct opr
 
                active_defined = 0;
        }
- out:
        printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, "
               "is_primary %d\n", ret, num_events, is_primary);
        return ret;
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Thu Sep 21 15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Sun Sep 24 13:10:13 2006 -0600
@@ -276,6 +276,9 @@ config HOTPLUG_CPU
          can be controlled through /sys/devices/system/cpu/cpu#.
          Say N if you want to disable CPU hotplug.
 
+config ARCH_ENABLE_MEMORY_HOTPLUG
+       def_bool y
+
 config SCHED_SMT
        bool "SMT scheduler support"
        depends on SMP
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/ia64/dig/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/dig/setup.c        Thu Sep 21 15:35:45 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/dig/setup.c        Sun Sep 24 13:10:13 
2006 -0600
@@ -24,6 +24,8 @@
 #include <asm/io.h>
 #include <asm/machvec.h>
 #include <asm/system.h>
+
+#include <xen/xencons.h>
 
 void __init
 dig_setup (char **cmdline_p)
@@ -78,27 +80,8 @@ dig_setup (char **cmdline_p)
                        (struct dom0_vga_console_info *)(
                                (char *)xen_start_info +
                                xen_start_info->console.dom0.info_off);
-               screen_info.orig_video_mode = info->txt_mode;
-               screen_info.orig_video_isVGA = info->video_type;
-               screen_info.orig_video_lines = info->video_height;
-               screen_info.orig_video_cols = info->video_width;
-               screen_info.orig_video_points = info->txt_points;
-               screen_info.lfb_width = info->video_width;
-               screen_info.lfb_height = info->video_height;
-               screen_info.lfb_depth = info->lfb_depth;
-               screen_info.lfb_base = info->lfb_base;
-               screen_info.lfb_size = info->lfb_size;
-               screen_info.lfb_linelength = info->lfb_linelen;
-               screen_info.red_size = info->red_size;
-               screen_info.red_pos = info->red_pos;
-               screen_info.green_size = info->green_size;
-               screen_info.green_pos = info->green_pos;
-               screen_info.blue_size = info->blue_size;
-               screen_info.blue_pos = info->blue_pos;
-               screen_info.rsvd_size = info->rsvd_size;
-               screen_info.rsvd_pos = info->rsvd_pos;
+               dom0_init_screen_info(info);
        }
-       screen_info.orig_y = screen_info.orig_video_lines - 1;
        xen_start_info->console.domU.mfn = 0;
        xen_start_info->console.domU.evtchn = 0;
 #endif
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/arch/x86_64/Kconfig
--- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig  Thu Sep 21 15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig  Sun Sep 24 13:10:13 2006 -0600
@@ -368,6 +368,8 @@ config HOTPLUG_CPU
                can be controlled through /sys/devices/system/cpu/cpu#.
                Say N if you want to disable CPU hotplug.
 
+config ARCH_ENABLE_MEMORY_HOTPLUG
+       def_bool y
 
 config HPET_TIMER
        bool
diff -r da942e577e5e -r 432f978d1cd1 
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Thu Sep 21 
15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Sun Sep 24 
13:10:13 2006 -0600
@@ -316,12 +316,7 @@ tracesys:
        ja  1f
        movq %r10,%rcx  /* fixup for C */
        call *sys_call_table(,%rax,8)
-       movq %rax,RAX-ARGOFFSET(%rsp)
-1:     SAVE_REST
-       movq %rsp,%rdi
-       call syscall_trace_leave
-       RESTORE_TOP_OF_STACK %rbx
-       RESTORE_REST
+1:     movq %rax,RAX-ARGOFFSET(%rsp)
        /* Use IRET because user could have changed frame */
        jmp int_ret_from_sys_call
        CFI_ENDPROC
diff -r da942e577e5e -r 432f978d1cd1 
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       Thu Sep 21 
15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Sun Sep 24 
13:10:13 2006 -0600
@@ -74,6 +74,7 @@
 #include <asm/hypervisor.h>
 #include <xen/interface/nmi.h>
 #include <xen/features.h>
+#include <xen/xencons.h>
 #define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
 #include <asm/mach-xen/setup_arch_post.h>
@@ -143,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;
 
@@ -625,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
@@ -645,33 +648,15 @@ void __init setup_arch(char **cmdline_p)
                screen_info.orig_video_cols = 80;
                screen_info.orig_video_ega_bx = 3;
                screen_info.orig_video_points = 16;
+               screen_info.orig_y = screen_info.orig_video_lines - 1;
                if (xen_start_info->console.dom0.info_size >=
                    sizeof(struct dom0_vga_console_info)) {
                        const struct dom0_vga_console_info *info =
                                (struct dom0_vga_console_info *)(
                                        (char *)xen_start_info +
                                        xen_start_info->console.dom0.info_off);
-                       screen_info.orig_video_mode = info->txt_mode;
-                       screen_info.orig_video_isVGA = info->video_type;
-                       screen_info.orig_video_lines = info->video_height;
-                       screen_info.orig_video_cols = info->video_width;
-                       screen_info.orig_video_points = info->txt_points;
-                       screen_info.lfb_width = info->video_width;
-                       screen_info.lfb_height = info->video_height;
-                       screen_info.lfb_depth = info->lfb_depth;
-                       screen_info.lfb_base = info->lfb_base;
-                       screen_info.lfb_size = info->lfb_size;
-                       screen_info.lfb_linelength = info->lfb_linelen;
-                       screen_info.red_size = info->red_size;
-                       screen_info.red_pos = info->red_pos;
-                       screen_info.green_size = info->green_size;
-                       screen_info.green_pos = info->green_pos;
-                       screen_info.blue_size = info->blue_size;
-                       screen_info.blue_pos = info->blue_pos;
-                       screen_info.rsvd_size = info->rsvd_size;
-                       screen_info.rsvd_pos = info->rsvd_pos;
-               }
-               screen_info.orig_y = screen_info.orig_video_lines - 1;
+                       dom0_init_screen_info(info);
+               }
                xen_start_info->console.domU.mfn = 0;
                xen_start_info->console.domU.evtchn = 0;
        } else
@@ -936,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);
@@ -959,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 da942e577e5e -r 432f978d1cd1 
linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c       Thu Sep 21 
15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c       Sun Sep 24 
13:10:13 2006 -0600
@@ -30,6 +30,7 @@
 #include <linux/moduleparam.h>
 #include <linux/nmi.h>
 #include <linux/kprobes.h>
+#include <linux/kexec.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -438,6 +439,8 @@ void __kprobes __die(const char * str, s
        printk(KERN_ALERT "RIP ");
        printk_address(regs->rip); 
        printk(" RSP <%016lx>\n", regs->rsp); 
+       if (kexec_should_crash(current))
+               crash_kexec(regs);
 }
 
 void die(const char * str, struct pt_regs * regs, long err)
@@ -461,6 +464,8 @@ void __kprobes die_nmi(char *str, struct
         */
        printk(str, safe_smp_processor_id());
        show_registers(regs);
+       if (kexec_should_crash(current))
+               crash_kexec(regs);
        if (panic_on_timeout || panic_on_oops)
                panic("nmi watchdog");
        printk("console shuts up ...\n");
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/drivers/char/tty_io.c
--- a/linux-2.6-xen-sparse/drivers/char/tty_io.c        Thu Sep 21 15:35:45 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tty_io.c        Sun Sep 24 13:10:13 
2006 -0600
@@ -2761,7 +2761,7 @@ static void flush_to_ldisc(void *private
        struct tty_struct *tty = (struct tty_struct *) private_;
        unsigned long   flags;
        struct tty_ldisc *disc;
-       struct tty_buffer *tbuf;
+       struct tty_buffer *tbuf, *head;
        int count;
        char *char_buf;
        unsigned char *flag_buf;
@@ -2778,7 +2778,9 @@ static void flush_to_ldisc(void *private
                goto out;
        }
        spin_lock_irqsave(&tty->buf.lock, flags);
-       while((tbuf = tty->buf.head) != NULL) {
+       head = tty->buf.head;
+       tty->buf.head = NULL;
+       while((tbuf = head) != NULL) {
                while ((count = tbuf->commit - tbuf->read) != 0) {
                        char_buf = tbuf->char_buf_ptr + tbuf->read;
                        flag_buf = tbuf->flag_buf_ptr + tbuf->read;
@@ -2787,10 +2789,12 @@ static void flush_to_ldisc(void *private
                        disc->receive_buf(tty, char_buf, flag_buf, count);
                        spin_lock_irqsave(&tty->buf.lock, flags);
                }
-               if (tbuf->active)
+               if (tbuf->active) {
+                       tty->buf.head = head;
                        break;
-               tty->buf.head = tbuf->next;
-               if (tty->buf.head == NULL)
+               }
+               head = tbuf->next;
+               if (head == NULL)
                        tty->buf.tail = NULL;
                tty_buffer_free(tty, tbuf);
        }
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/drivers/serial/Kconfig
--- a/linux-2.6-xen-sparse/drivers/serial/Kconfig       Thu Sep 21 15:35:45 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/serial/Kconfig       Sun Sep 24 13:10:13 
2006 -0600
@@ -821,6 +821,7 @@ config SERIAL_ICOM
        tristate "IBM Multiport Serial Adapter"
        depends on PCI && (PPC_ISERIES || PPC_PSERIES)
        select SERIAL_CORE
+       select FW_LOADER
        help
          This driver is for a family of multiport serial adapters
          including 2 port RVX, 2 port internal modem, 4 port internal
diff -r da942e577e5e -r 432f978d1cd1 
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c        Thu Sep 21 
15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c        Sun Sep 24 
13:10:13 2006 -0600
@@ -49,6 +49,7 @@
 #include <linux/console.h>
 #include <linux/bootmem.h>
 #include <linux/sysrq.h>
+#include <linux/screen_info.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -262,6 +263,41 @@ void xencons_force_flush(void)
                sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
                if (sent > 0)
                        wc += sent;
+       }
+}
+
+
+void dom0_init_screen_info(const struct dom0_vga_console_info *info)
+{
+       switch (info->video_type) {
+       case XEN_VGATYPE_TEXT_MODE_3:
+               screen_info.orig_video_mode = 3;
+               screen_info.orig_video_ega_bx = 3;
+               screen_info.orig_video_isVGA = 1;
+               screen_info.orig_video_lines = info->u.text_mode_3.rows;
+               screen_info.orig_video_cols = info->u.text_mode_3.columns;
+               screen_info.orig_x = info->u.text_mode_3.cursor_x;
+               screen_info.orig_y = info->u.text_mode_3.cursor_y;
+               screen_info.orig_video_points =
+                       info->u.text_mode_3.font_height;
+               break;
+       case XEN_VGATYPE_VESA_LFB:
+               screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB;
+               screen_info.lfb_width = info->u.vesa_lfb.width;
+               screen_info.lfb_height = info->u.vesa_lfb.height;
+               screen_info.lfb_depth = info->u.vesa_lfb.bits_per_pixel;
+               screen_info.lfb_base = info->u.vesa_lfb.lfb_base;
+               screen_info.lfb_size = info->u.vesa_lfb.lfb_size;
+               screen_info.lfb_linelength = info->u.vesa_lfb.bytes_per_line;
+               screen_info.red_size = info->u.vesa_lfb.red_size;
+               screen_info.red_pos = info->u.vesa_lfb.red_pos;
+               screen_info.green_size = info->u.vesa_lfb.green_size;
+               screen_info.green_pos = info->u.vesa_lfb.green_pos;
+               screen_info.blue_size = info->u.vesa_lfb.blue_size;
+               screen_info.blue_pos = info->u.vesa_lfb.blue_pos;
+               screen_info.rsvd_size = info->u.vesa_lfb.rsvd_size;
+               screen_info.rsvd_pos = info->u.vesa_lfb.rsvd_pos;
+               break;
        }
 }
 
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/include/xen/xencons.h
--- a/linux-2.6-xen-sparse/include/xen/xencons.h        Thu Sep 21 15:35:45 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/xencons.h        Sun Sep 24 13:10:13 
2006 -0600
@@ -1,5 +1,8 @@
 #ifndef __ASM_XENCONS_H__
 #define __ASM_XENCONS_H__
+
+struct dom0_vga_console_info;
+void dom0_init_screen_info(const struct dom0_vga_console_info *info);
 
 void xencons_force_flush(void);
 void xencons_resume(void);
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/mm/Kconfig
--- a/linux-2.6-xen-sparse/mm/Kconfig   Thu Sep 21 15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/mm/Kconfig   Sun Sep 24 13:10:13 2006 -0600
@@ -115,7 +115,7 @@ config SPARSEMEM_EXTREME
 # eventually, we can have this option just 'select SPARSEMEM'
 config MEMORY_HOTPLUG
        bool "Allow for memory hot-add"
-       depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND
+       depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && 
ARCH_ENABLE_MEMORY_HOTPLUG
 
 comment "Memory hotplug is currently incompatible with Software Suspend"
        depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
diff -r da942e577e5e -r 432f978d1cd1 linux-2.6-xen-sparse/mm/page_alloc.c
--- a/linux-2.6-xen-sparse/mm/page_alloc.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/linux-2.6-xen-sparse/mm/page_alloc.c      Sun Sep 24 13:10:13 2006 -0600
@@ -951,7 +951,8 @@ restart:
                alloc_flags |= ALLOC_HARDER;
        if (gfp_mask & __GFP_HIGH)
                alloc_flags |= ALLOC_HIGH;
-       alloc_flags |= ALLOC_CPUSET;
+       if (wait)
+               alloc_flags |= ALLOC_CPUSET;
 
        /*
         * Go through the zonelist again. Let __GFP_HIGH and allocations
diff -r da942e577e5e -r 432f978d1cd1 tools/check/check_python
--- a/tools/check/check_python  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/check/check_python  Sun Sep 24 13:10:13 2006 -0600
@@ -7,4 +7,4 @@ function error {
     exit 1
 }
 
-python -V 2>&1 | cut -d ' ' -f 2 | grep -q -E '^2.2|^2.3|^2.4' || error
+python -V 2>&1 | cut -d ' ' -f 2 | grep -q '^2.[2345]' || error
diff -r da942e577e5e -r 432f978d1cd1 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/console/daemon/io.c Sun Sep 24 13:10:13 2006 -0600
@@ -293,12 +293,14 @@ static bool watch_domain(struct domain *
        bool success;
 
        sprintf(domid_str, "dom%u", dom->domid);
-       if (watch)
+       if (watch) {
                success = xs_watch(xs, dom->conspath, domid_str);
-       else
+               if (success)
+                       domain_create_ring(dom);
+       } else {
                success = xs_unwatch(xs, dom->conspath, domid_str);
-       if (success)
-               domain_create_ring(dom);
+       }
+
        return success;
 }
 
diff -r da942e577e5e -r 432f978d1cd1 tools/debugger/gdb/gdbbuild
--- a/tools/debugger/gdb/gdbbuild       Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/debugger/gdb/gdbbuild       Sun Sep 24 13:10:13 2006 -0600
@@ -1,4 +1,6 @@
 #!/bin/sh
+
+set -e
 
 [ "$GDB_MIRROR" ] || GDB_MIRROR="ftp://ftp.gnu.org/gnu/gdb/";
 
diff -r da942e577e5e -r 432f978d1cd1 tools/examples/locking.sh
--- a/tools/examples/locking.sh Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/examples/locking.sh Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/firmware/vmxassist/machine.h
--- a/tools/firmware/vmxassist/machine.h        Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/firmware/vmxassist/machine.h        Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/firmware/vmxassist/vm86.c   Sun Sep 24 13:10:13 2006 -0600
@@ -52,29 +52,74 @@ 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 *)gcr3)[(base >> 22) & 0x3ff];
+
+               if (oldctx.cr4 & CR4_PSE || l1_mfn & PDE_PS) {
+                        /* 1 level page table */
+                       l0_mfn = l1_mfn;
+                       if (!(l0_mfn & PT_ENTRY_PRESENT))
+                               panic("l1 entry not present\n");
+
+                       l0_mfn &= 0xffc00000;
+                       return l0_mfn + (base & 0x3fffff);
+               }
+
+               if (!(l1_mfn & PT_ENTRY_PRESENT))
+                       panic("l2 entry not present\n");
+
+               l1_mfn &= 0xfffff000;
+               l0_mfn = ((uint32_t *)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 if (oldctx.cr4 & CR4_PAE && !(oldctx.cr4 & CR4_PSE)) {
+               l2_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3];
+               if (!(l2_mfn & PT_ENTRY_PRESENT))
+                       panic("l3 entry not present\n");
+               l2_mfn &= 0x3fffff000ULL;
+
+               l1_mfn = ((uint64_t *)l2_mfn)[(base >> 21) & 0x1ff];
+               if (!(l1_mfn & PT_ENTRY_PRESENT))
+                       panic("l2 entry not present\n");
+               l1_mfn &= 0x3fffff000ULL;
+
+               l0_mfn = ((uint64_t *)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);
+       } else { /* oldctx.cr4 & CR4_PAE && oldctx.cr4 & CR4_PSE */
+               l1_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3];
+               if (!(l1_mfn & PT_ENTRY_PRESENT))
+                       panic("l2 entry not present\n");
+               l1_mfn &= 0x3fffff000ULL;
+
+               l0_mfn = ((uint64_t *)l1_mfn)[(base >> 21) & 0x1ff];
+               if (!(l0_mfn & PT_ENTRY_PRESENT))
+                       panic("l1 entry not present\n");
+               l0_mfn &= 0x3ffe00000ULL;
+
+               return l0_mfn + (base & 0x1fffff);
+       }
 }
 
 static unsigned
@@ -95,7 +140,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 +826,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)
diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/hw/vga.c      Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/hw/xen_platform.c
--- a/tools/ioemu/hw/xen_platform.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/hw/xen_platform.c     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/domain-timeoffset
--- a/tools/ioemu/patches/domain-timeoffset     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/domain-timeoffset     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-bootorder
--- a/tools/ioemu/patches/qemu-bootorder        Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/qemu-bootorder        Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-daemonize
--- a/tools/ioemu/patches/qemu-daemonize        Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/qemu-daemonize        Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-pci
--- a/tools/ioemu/patches/qemu-pci      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/qemu-pci      Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/qemu-target-i386-dm
--- a/tools/ioemu/patches/qemu-target-i386-dm   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/qemu-target-i386-dm   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/series
--- a/tools/ioemu/patches/series        Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/series        Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-access-monitor-vt
--- a/tools/ioemu/patches/vnc-access-monitor-vt Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/vnc-access-monitor-vt Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-cleanup
--- a/tools/ioemu/patches/vnc-cleanup   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/vnc-cleanup   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-display-find-unused
--- a/tools/ioemu/patches/vnc-display-find-unused       Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/ioemu/patches/vnc-display-find-unused       Sun Sep 24 13:10:13 
2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-fixes
--- a/tools/ioemu/patches/vnc-fixes     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/vnc-fixes     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-start-vncviewer
--- a/tools/ioemu/patches/vnc-start-vncviewer   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/vnc-start-vncviewer   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/vnc-title-domain-name
--- a/tools/ioemu/patches/vnc-title-domain-name Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/vnc-title-domain-name Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/xen-platform-device
--- a/tools/ioemu/patches/xen-platform-device   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/patches/xen-platform-device   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 
tools/ioemu/patches/xen-support-buffered-ioreqs
--- a/tools/ioemu/patches/xen-support-buffered-ioreqs   Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/ioemu/patches/xen-support-buffered-ioreqs   Sun Sep 24 13:10:13 
2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 
tools/ioemu/patches/xenstore-block-device-config
--- a/tools/ioemu/patches/xenstore-block-device-config  Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/ioemu/patches/xenstore-block-device-config  Sun Sep 24 13:10:13 
2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/patches/xenstore-write-vnc-port
--- a/tools/ioemu/patches/xenstore-write-vnc-port       Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/ioemu/patches/xenstore-write-vnc-port       Sun Sep 24 13:10:13 
2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/target-i386-dm/helper2.c      Sun Sep 24 13:10:13 2006 -0600
@@ -520,8 +520,8 @@ int main_loop(void)
             }
         }
 
-        /* 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;
diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/usb-linux.c
--- a/tools/ioemu/usb-linux.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/usb-linux.c   Sun Sep 24 13:10:13 2006 -0600
@@ -26,7 +26,6 @@
 #if defined(__linux__)
 #include <dirent.h>
 #include <sys/ioctl.h>
-#include <linux/compiler.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/version.h>
 
diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/vl.c  Sun Sep 24 13:10:13 2006 -0600
@@ -723,6 +723,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_mod_timer(ts, expire_time);
 }
 
 /* modify the current timer so that it will be fired when current_time
diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/vl.h  Sun Sep 24 13:10:13 2006 -0600
@@ -405,6 +405,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;
diff -r da942e577e5e -r 432f978d1cd1 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/ioemu/vnc.c Sun Sep 24 13:10:13 2006 -0600
@@ -27,7 +27,19 @@
 #include "vl.h"
 #include "qemu_socket.h"
 
-#define VNC_REFRESH_INTERVAL (1000 / 30)
+/* 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 +76,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 +110,6 @@ struct VncState
     int visible_y;
     int visible_w;
     int visible_h;
-
-    int slow_client;
 
     int ctl_keys;               /* Ctrl+Alt starts calibration */
 };
@@ -380,7 +391,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 +401,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 +454,145 @@ 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. */
+           /* Note that there are bugs in xvncviewer which prevent
+              this from actually working.  Leave the code in place
+              for correct clients. */
+           vnc_write_u8(vs, 0);
+           vnc_write_u8(vs, 0);
+           vnc_write_u16(vs, 0);
+           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 +607,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 +668,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;
@@ -895,13 +937,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 +1059,7 @@ static int protocol_client_msg(VncState 
 {
     int i;
     uint16_t limit;
+    int64_t now;
 
     switch (data[0]) {
     case 0:
@@ -1055,12 +1099,18 @@ 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:
@@ -1086,6 +1136,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;
@@ -1269,7 +1321,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 da942e577e5e -r 432f978d1cd1 tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/libxc/powerpc64/Makefile    Sun Sep 24 13:10:13 2006 -0600
@@ -1,1 +1,4 @@ GUEST_SRCS-y += powerpc64/xc_linux_build
 GUEST_SRCS-y += powerpc64/xc_linux_build.c
+GUEST_SRCS-y += powerpc64/flatdevtree.c
+
+CTRL_SRCS-y += powerpc64/xc_memory.c
diff -r da942e577e5e -r 432f978d1cd1 tools/libxc/powerpc64/xc_linux_build.c
--- a/tools/libxc/powerpc64/xc_linux_build.c    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/libxc/powerpc64/xc_linux_build.c    Sun Sep 24 13:10:13 2006 -0600
@@ -27,14 +27,17 @@
 #include <sys/types.h>
 #include <inttypes.h>
 
+#include <xen/xen.h>
 #include <xen/memory.h>
 #include <xc_private.h>
 #include <xg_private.h>
 #include <xenctrl.h>
 
-/* XXX 64M hack */
-#define MEMSIZE (64UL << 20)
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+
 #define INITRD_ADDR (24UL << 20)
+#define DEVTREE_ADDR (16UL << 20)
 
 #define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
 
@@ -91,8 +94,8 @@ static int init_boot_vcpu(
     int xc_handle,
     int domid,
     struct domain_setup_info *dsi,
-    unsigned long dtb,
-    unsigned long kaddr)
+    unsigned long devtree_addr,
+    unsigned long kern_addr)
 {
     vcpu_guest_context_t ctxt;
     int rc;
@@ -101,15 +104,15 @@ static int init_boot_vcpu(
     ctxt.user_regs.pc = dsi->v_kernentry;
     ctxt.user_regs.msr = 0;
     ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
-    ctxt.user_regs.gprs[3] = dtb;
-    ctxt.user_regs.gprs[4] = kaddr;
+    ctxt.user_regs.gprs[3] = devtree_addr;
+    ctxt.user_regs.gprs[4] = kern_addr;
     ctxt.user_regs.gprs[5] = 0;
     /* There is a buggy kernel that does not zero the "local_paca", so
      * we must make sure this register is 0 */
     ctxt.user_regs.gprs[13] = 0;
 
     DPRINTF("xc_vcpu_setvcpucontext:\n"
-                 "  pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
+                 "  pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
                  "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
                  " %016"PRIx64"\n",
                  ctxt.user_regs.pc, ctxt.user_regs.msr,
@@ -156,31 +159,69 @@ static int install_image(
     return rc;
 }
 
-/* XXX be more flexible about placement in memory */
-static int load_dtb(
+static int load_devtree(
     int xc_handle,
     int domid,
-    const char *dtb_path,
-    unsigned long dtb_addr,
-    struct domain_setup_info *dsi,
-    xen_pfn_t *page_array)
-{
-    uint8_t *img;
-    unsigned long dtb_size;
+    xen_pfn_t *page_array,
+    void *devtree,
+    unsigned long devtree_addr,
+    uint64_t initrd_base,
+    unsigned long initrd_len,
+    start_info_t *si,
+    unsigned long si_addr)
+{
+    uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
+    struct boot_param_header *header;
+    void *chosen;
+    void *xen;
+    uint64_t initrd_end = initrd_base + initrd_len;
+    unsigned int devtree_size;
     int rc = 0;
 
-    img = load_file(dtb_path, &dtb_size);
-    if (img == NULL) {
-        rc = -1;
-        goto out;
-    }
-
-    DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size);
-    rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size);
-
-out:
-    free(img);
-    return rc;
+    DPRINTF("adding initrd props\n");
+
+    chosen = ft_find_node(devtree, "/chosen");
+    if (chosen == NULL) {
+        DPRINTF("couldn't find /chosen\n");
+        return -1;
+    }
+
+    xen = ft_find_node(devtree, "/xen");
+    if (xen == NULL) {
+        DPRINTF("couldn't find /xen\n");
+        return -1;
+    }
+
+    /* initrd-start */
+    rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
+            &initrd_base, sizeof(initrd_base));
+    if (rc < 0) {
+        DPRINTF("couldn't set /chosen/linux,initrd-start\n");
+        return rc;
+    }
+
+    /* initrd-end */
+    rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
+            &initrd_end, sizeof(initrd_end));
+    if (rc < 0) {
+        DPRINTF("couldn't set /chosen/linux,initrd-end\n");
+        return rc;
+    }
+
+    /* start-info (XXX being removed soon) */
+    rc = ft_set_prop(&devtree, xen, "start-info",
+            start_info, sizeof(start_info));
+    if (rc < 0) {
+        DPRINTF("couldn't set /xen/start-info\n");
+        return rc;
+    }
+
+    header = devtree;
+    devtree_size = header->totalsize;
+
+    DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, 
devtree_size);
+    return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
+                       devtree_size);
 }
 
 unsigned long spin_list[] = {
@@ -294,17 +335,16 @@ out:
 }
 
 static unsigned long create_start_info(start_info_t *si,
-        unsigned int console_evtchn, unsigned int store_evtchn)
-{
-    unsigned long eomem;
+        unsigned int console_evtchn, unsigned int store_evtchn,
+        unsigned long nr_pages)
+{
     unsigned long si_addr;
 
     memset(si, 0, sizeof(*si));
     snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
 
-    eomem = MEMSIZE;
-    si->nr_pages = eomem >> PAGE_SHIFT;
-    si->shared_info = eomem - (PAGE_SIZE * 1);
+    si->nr_pages = nr_pages;
+    si->shared_info = (nr_pages - 1) << PAGE_SHIFT;
     si->store_mfn = si->nr_pages - 2;
     si->store_evtchn = store_evtchn;
     si->console.domU.mfn = si->nr_pages - 3;
@@ -314,29 +354,34 @@ static unsigned long create_start_info(s
     return si_addr;
 }
 
-static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
-{
-    int nr_pages;
+static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
+                          unsigned long *nr_pages)
+{
     int rc;
 
     DPRINTF("xc_get_tot_pages\n");
-    nr_pages = xc_get_tot_pages(xc_handle, domid);
-    DPRINTF("  0x%x\n", nr_pages);
-
-    *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
+    *nr_pages = xc_get_tot_pages(xc_handle, domid);
+    DPRINTF("  0x%lx\n", *nr_pages);
+
+    *page_array = malloc(*nr_pages * sizeof(xen_pfn_t));
     if (*page_array == NULL) {
         perror("malloc");
         return -1;
     }
 
     DPRINTF("xc_get_pfn_list\n");
-    rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages);
-    if (rc != nr_pages) {
+    rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages);
+    if (rc != *nr_pages) {
         perror("Could not get the page frame list");
         return -1;
     }
 
     return 0;
+}
+
+static void free_page_array(xen_pfn_t *page_array)
+{
+    free(page_array);
 }
 
 
@@ -351,57 +396,70 @@ int xc_linux_build(int xc_handle,
                    unsigned int store_evtchn,
                    unsigned long *store_mfn,
                    unsigned int console_evtchn,
-                   unsigned long *console_mfn)
-{
+                   unsigned long *console_mfn,
+                   void *devtree)
+{
+    start_info_t si;
     struct domain_setup_info dsi;
     xen_pfn_t *page_array = NULL;
+    unsigned long nr_pages;
+    unsigned long devtree_addr = 0;
     unsigned long kern_addr;
-    unsigned long dtb_addr;
-    unsigned long si_addr;
     unsigned long initrd_base = 0;
     unsigned long initrd_len = 0;
-    start_info_t si;
+    unsigned long si_addr;
     int rc = 0;
 
-    if (get_page_array(xc_handle, domid, &page_array)) {
-        rc = -1;
-        goto out;
-    }
-
+    DPRINTF("%s\n", __func__);
+
+    if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) {
+        rc = -1;
+        goto out;
+    }
+
+    DPRINTF("loading image '%s'\n", image_name);
     if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
         rc = -1;
         goto out;
     }
     kern_addr = 0;
 
-    if (initrd_name && initrd_name[0] != '\0' &&
-        load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base,
-                &initrd_len)) {
-        rc = -1;
-        goto out;
-    }
-    /* XXX install initrd addr/len into device tree */
-
-    dtb_addr = (16 << 20);
-    if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, 
page_array)) {
-        dtb_addr = 0;
-    }
-
-    si_addr = create_start_info(&si, console_evtchn, store_evtchn);
+    if (initrd_name && initrd_name[0] != '\0') {
+        DPRINTF("loading initrd '%s'\n", initrd_name);
+        if (load_initrd(xc_handle, domid, page_array, initrd_name,
+                &initrd_base, &initrd_len)) {
+            rc = -1;
+            goto out;
+        }
+    }
+
+    /* start_info stuff: about to be removed  */
+    si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages);
     *console_mfn = page_array[si.console.domU.mfn];
     *store_mfn = page_array[si.store_mfn];
-    
     if (install_image(xc_handle, domid, page_array, &si, si_addr,
                 sizeof(start_info_t))) {
         rc = -1;
         goto out;
     }
 
-    if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) {
+    if (devtree) {
+        DPRINTF("loading flattened device tree\n");
+        devtree_addr = DEVTREE_ADDR;
+        if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
+                     initrd_base, initrd_len, &si, si_addr)) {
+            DPRINTF("couldn't load flattened device tree.\n");
+            rc = -1;
+            goto out;
+        }
+    }
+
+    if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
         rc = -1;
         goto out;
     }
 
 out:
-    return rc;
-}
+    free_page_array(page_array);
+    return rc;
+}
diff -r da942e577e5e -r 432f978d1cd1 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/libxc/xc_ptrace.c   Sun Sep 24 13:10:13 2006 -0600
@@ -611,17 +611,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 da942e577e5e -r 432f978d1cd1 tools/pygrub/Makefile
--- a/tools/pygrub/Makefile     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/pygrub/Makefile     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/pygrub/src/fsys/ext2/__init__.py
--- a/tools/pygrub/src/fsys/ext2/__init__.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/pygrub/src/fsys/ext2/__init__.py    Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/pygrub/src/fsys/reiser/__init__.py
--- a/tools/pygrub/src/fsys/reiser/__init__.py  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/pygrub/src/fsys/reiser/__init__.py  Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/util/blkif.py
--- a/tools/python/xen/util/blkif.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/util/blkif.py    Sun Sep 24 13:10:13 2006 -0600
@@ -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
@@ -65,7 +65,7 @@ def blkdev_uname_to_file(uname):
     fn = None
     if uname.find(":") != -1:
         (typ, fn) = uname.split(":")
-        if typ == "phy" and not fn.startswith("/dev/"):
+        if typ == "phy" and not fn.startswith("/"):
             fn = "/dev/%s" %(fn,)
     return fn
 
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xend/XendBootloader.py   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xend/XendDomain.py       Sun Sep 24 13:10:13 2006 -0600
@@ -390,6 +390,22 @@ class XendDomain:
         except Exception, ex:
             raise XendError(str(ex))
 
+    def domain_dump(self, domid, filename, live, crash):
+        """Dump domain core."""
+
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        if not dominfo:
+            raise XendInvalidDomain(str(domid))
+
+        if dominfo.getDomid() == PRIV_DOMAIN:
+            raise XendError("Cannot dump core for privileged domain %s" % 
domid)
+
+        try:
+            log.info("Domain core dump requested for domain %s (%d) live=%d 
crash=%d.",
+                     dominfo.getName(), dominfo.getDomid(), live, crash)
+            return dominfo.dumpCore(filename)
+        except Exception, ex:
+            raise XendError(str(ex))
 
     def domain_destroy(self, domid):
         """Terminate domain immediately."""
@@ -544,13 +560,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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py   Sun Sep 24 13:10:13 2006 -0600
@@ -86,6 +86,7 @@ STATE_DOM_SHUTDOWN = 2
 STATE_DOM_SHUTDOWN = 2
 
 SHUTDOWN_TIMEOUT = 30.0
+MIGRATE_TIMEOUT = 30.0
 
 ZOMBIE_PREFIX = 'Zombie-'
 
@@ -595,6 +596,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']
@@ -977,18 +980,26 @@ class XendDomainInfo:
         self.restart(True)
 
 
-    def dumpCore(self):
+    def dumpCore(self,corefile=None):
         """Create a core dump for this domain.  Nothrow guarantee."""
         
         try:
-            corefile = "/var/xen/dump/%s.%s.core" % (self.info['name'],
-                                                     self.domid)
+            if not corefile:
+                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:
 
@@ -996,6 +1007,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)
         
@@ -1088,15 +1102,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)
 
 
@@ -1531,14 +1546,19 @@ class XendDomainInfo:
         the device has shutdown correctly, i.e. all blocks are
         flushed to disk
         """
+        start = time.time()
         while True:
             test = 0
+            diff = time.time() - start
             for i in self.getDeviceController('vbd').deviceIDs():
                 test = 1
                 log.info("Dev %s still active, looping...", i)
                 time.sleep(0.1)
                 
             if test == 0:
+                break
+            if diff >= MIGRATE_TIMEOUT:
+                log.info("Dev still active but hit max loop timeout")
                 break
 
     def migrateDevices(self, network, dst, step, domName=''):
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xend/image.py    Sun Sep 24 13:10:13 2006 -0600
@@ -340,10 +340,6 @@ class HVMImageHandler(ImageHandler):
                            (nics, mac, model))
                 ret.append("-net")
                 ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
-            if name == 'vtpm':
-                instance = sxp.child_value(info, 'pref_instance')
-                ret.append("-instance")
-                ret.append("%s" % instance)
         return ret
 
     def configVNC(self, config):
diff -r da942e577e5e -r 432f978d1cd1 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/python/xen/xend/server/DevController.py     Sun Sep 24 13:10:13 
2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xend/server/blkif.py     Sun Sep 24 13:10:13 2006 -0600
@@ -64,10 +64,14 @@ class BlkifController(DevController):
             except ValueError:
                 (typ, params) = ("", "")
 
+        mode = sxp.child_value(config, 'mode', 'r')
+        if mode not in ('r', 'w', 'w!'):
+            raise VmError('Invalid mode')
+
         back = { 'dev'    : dev,
                  'type'   : typ,
                  'params' : params,
-                 'mode'   : sxp.child_value(config, 'mode', 'r')
+                 'mode'   : mode
                }
 
         if security.on():
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xend/server/tpmif.py     Sun Sep 24 13:10:13 2006 -0600
@@ -52,7 +52,7 @@ class TPMifController(DevController):
         if inst == -1:
             inst = int(sxp.child_value(config, 'instance' , '0'))
 
-        log.info("The domain has a TPM with instance %d and devid %d.",
+        log.info("The domain has a TPM with pref. instance %d and devid %d.",
                  inst, devid)
         back  = { 'pref_instance' : "%i" % inst,
                   'resume'        : "%s" % (self.vm.getResume()) }
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/addlabel.py
--- a/tools/python/xen/xm/addlabel.py   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/addlabel.py   Sun Sep 24 13:10:13 2006 -0600
@@ -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):
@@ -114,9 +118,8 @@ def main (argv):
 def main (argv):
     try:
         policyref = None
-        if len(argv) not in [4,5]:
-            usage()
-            return
+        if len(argv) not in (4, 5):
+            raise OptionError('Needs either 2 or 3 arguments')
 
         label = argv[1]
 
@@ -135,20 +138,20 @@ def main (argv):
                     if os.path.isfile(configfile):
                         break
             if not validate_config_file(configfile):
-                usage()
+                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:
-            usage()
-
+            raise OptionError('Need to specify either "dom" or "res" as object 
to add label to.')
+            
     except security.ACMError:
         sys.exit(-1)
 
-
 if __name__ == '__main__':
     main(sys.argv)
+    
 
 
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/cfgbootpolicy.py      Sun Sep 24 13:10:13 2006 -0600
@@ -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
@@ -152,7 +149,7 @@ def main(argv):
             policy = argv[1]
             user_kver = argv[2]
         else:
-            usage()
+            raise OptionError('Invalid number of arguments')
 
         if not policy_name_re.match(policy):
             err("Illegal policy name \'" + policy + "\'")
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/console.py
--- a/tools/python/xen/xm/console.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/console.py    Sun Sep 24 13:10:13 2006 -0600
@@ -18,9 +18,7 @@
 
 XENCONSOLE = "xenconsole"
 
-
 import xen.util.auxbin
-
 
 def execConsole(domid):
     xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/create.py     Sun Sep 24 13:10:13 2006 -0600
@@ -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,
@@ -439,7 +438,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.
@@ -490,7 +488,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:
@@ -851,7 +848,6 @@ def choose_vnc_display():
         if port in ports: continue
         return d
     return None
-
 vncpid = None
 
 def daemonize(prog, args):
@@ -885,7 +881,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())
@@ -904,6 +899,7 @@ def spawn_vnc(display):
     vncpid = daemonize("vncviewer", vncargs)
     if vncpid == 0:
         return 0
+
     return VNC_BASE_PORT + display
 
 def preprocess_vnc(vals):
@@ -1019,11 +1015,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:
@@ -1091,7 +1086,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.
@@ -1145,7 +1139,6 @@ def config_security_check(config, verbos
 
     return answer
 
-
 def create_security_check(config):
     passed = 0
     try:
@@ -1158,7 +1151,9 @@ def create_security_check(config):
         sys.exit(-1)
 
     return passed
-
+  
+def help():
+    return str(gopts)
 
 def main(argv):
     try:
@@ -1176,11 +1171,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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/dry-run.py
--- a/tools/python/xen/xm/dry-run.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/dry-run.py    Sun Sep 24 13:10:13 2006 -0600
@@ -22,20 +22,19 @@ 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()
+            raise OptionError('Invalid number of arguments')
 
         passed = 0
         (opts, config) = create.parseCommandLine(argv)
@@ -44,7 +43,7 @@ def main (argv):
                 passed = 1
         else:
             print "Checking resources: (skipped)"
-
+                
         if passed:
             print "Dry Run: PASSED"
         else:
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/dumppolicy.py
--- a/tools/python/xen/xm/dumppolicy.py Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/dumppolicy.py Sun Sep 24 13:10:13 2006 -0600
@@ -21,12 +21,10 @@ from xen.util.security import ACMError, 
 from xen.util.security import ACMError, err, dump_policy
 
 
-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):
     try:
@@ -34,7 +32,6 @@ def main(argv):
             usage()
 
         dump_policy()
-
     except ACMError:
         sys.exit(-1)
 
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/getlabel.py
--- a/tools/python/xen/xm/getlabel.py   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/getlabel.py   Sun Sep 24 13:10:13 2006 -0600
@@ -21,13 +21,13 @@ 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>\n"
+    This program shows the label for a domain or resource."""
 
 def get_resource_label(resource):
     """Gets the resource label
@@ -90,21 +90,17 @@ def get_domain_label(configfile):
 
 
 def main (argv):
-    try:
-        if len(argv) != 3:
-            usage()
+    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)
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/labels.py
--- a/tools/python/xen/xm/labels.py     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/labels.py     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/loadpolicy.py Sun Sep 24 13:10:13 2006 -0600
@@ -21,26 +21,23 @@ 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):
+    if len(argv) != 2:
+        raise OptionError('No policy defined')
+    
     try:
-        if len(argv) != 2:
-            usage()
         load_policy(argv[1])
 
     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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/main.py       Sun Sep 24 13:10:13 2006 -0600
@@ -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,152 @@ 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"
-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",
+    "dump-core",
     "help",
     "list",
     "mem-set",
@@ -159,8 +217,8 @@ domain_commands = [
     "destroy",
     "domid",
     "domname",
+    "dump-core",
     "list",
-    "list_label",
     "mem-max",
     "mem-set",
     "migrate",
@@ -218,67 +276,105 @@ 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."""
+    
+    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)
 
 
 ####################################################################
@@ -293,7 +389,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:
@@ -340,14 +436,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)
@@ -361,9 +462,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)
 
@@ -373,9 +474,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:
@@ -392,7 +495,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)
@@ -407,7 +510,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),
@@ -423,7 +526,7 @@ def parse_sedf_info(info):
         return t(sxp.child_value(info, n, d))
 
     return {
-        'dom'      : get_info('domain',        int,   -1),
+        'domid'    : get_info('domid',         int,   -1),
         'period'   : get_info('period',        int,   -1),
         'slice'    : get_info('slice',         int,   -1),
         'latency'  : get_info('latency',       int,   -1),
@@ -431,34 +534,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):
@@ -469,7 +578,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):
@@ -563,10 +676,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)
@@ -590,32 +700,68 @@ def xm_unpause(args):
 
     server.xend.domain.unpause(dom)
 
+def xm_dump_core(args):
+    live = False
+    crash = False
+    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])
+    else:
+        filename = None
+
+    if not live:
+        server.xend.domain.pause(dom)
+
+    try:
+        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)
+        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:
+                cpus.append(int(c))
+        cpus.sort()
+        return cpus
 
     dom  = args[0]
     vcpu = int(args[1])
@@ -677,11 +823,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:
@@ -715,20 +862,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():
@@ -738,7 +890,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))
 
@@ -747,17 +899,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
@@ -774,20 +923,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)
@@ -806,6 +951,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):
@@ -862,6 +1009,12 @@ def xm_uptime(args):
 
         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)
 
@@ -883,8 +1036,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()
@@ -902,7 +1058,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:
@@ -1048,7 +1204,7 @@ def parse_block_configuration(args):
         cls = 'tap'
     else:
         cls = 'vbd'
-        
+
     vbd = [cls,
            ['uname', args[1]],
            ['dev',   args[2]],
@@ -1057,19 +1213,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
+    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)
 
     return (dom, vbd)
 
@@ -1168,11 +1317,13 @@ commands = {
     "destroy": xm_destroy,
     "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
@@ -1211,24 +1362,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",
@@ -1246,11 +1396,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()
 
@@ -1258,27 +1415,17 @@ 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 and output our own help
+    if '--help' in argv[1:]:
+        if '--help' == argv[1]:
+            longHelp()
+        else:
+            usage(argv[1])
+        sys.exit(0)
 
     cmd = xm_lookup_cmd(argv[1])
 
@@ -1291,9 +1438,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."
@@ -1302,16 +1449,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:
@@ -1326,6 +1473,10 @@ def main(argv=sys.argv):
         except (ValueError, OverflowError):
             err("Invalid argument.")
             usage(argv[1])
+        except OptionError, e:
+            err(str(e))
+            usage(argv[1])
+            print e.usage()
         except:
             print "Unexpected error:", sys.exc_info()[0]
             print
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/makepolicy.py Sun Sep 24 13:10:13 2006 -0600
@@ -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,13 +29,12 @@ def usage():
     err("Usage")
 
 
+def main(argv):
+    if len(argv) != 2:
+        raise OptionError('No XML policy file specified')
 
-def main(argv):
     try:
-        if len(argv) != 2:
-            usage()
         make_policy(argv[1])
-
     except ACMError:
         sys.exit(-1)
     except:
@@ -43,7 +42,6 @@ def main(argv):
         sys.exit(-1)
 
 
-
 if __name__ == '__main__':
     main(sys.argv)
 
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/migrate.py    Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/opts.py
--- a/tools/python/xen/xm/opts.py       Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/opts.py       Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/resources.py
--- a/tools/python/xen/xm/resources.py  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/resources.py  Sun Sep 24 13:10:13 2006 -0600
@@ -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 """Usage: xm resource
+    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,11 +37,16 @@ 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:
-        if len(argv) != 1:
-            usage()
+        filename = security.res_label_filename
+        access_control = dictio.dict_read("resources", filename)
+    except:
+        print "Resource file not found."
+        return
 
         try:
             file = security.res_label_filename
@@ -52,9 +56,6 @@ def main (argv):
 
         print_resource_data(access_control)
 
-    except security.ACMError:
-        sys.exit(-1)
-
 if __name__ == '__main__':
     main(sys.argv)
 
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/rmlabel.py    Sun Sep 24 13:10:13 2006 -0600
@@ -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):
@@ -93,22 +95,22 @@ def rm_domain_label(configfile):
 
 
 def main (argv):
+
+    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])
+
     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()
-
     except security.ACMError:
         sys.exit(-1)
-
 
 if __name__ == '__main__':
     main(sys.argv)
diff -r da942e577e5e -r 432f978d1cd1 tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/python/xen/xm/shutdown.py   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/doc/man/vn.pod.1
--- a/tools/vnet/doc/man/vn.pod.1       Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/doc/man/vn.pod.1       Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/libxutil/Makefile
--- a/tools/vnet/libxutil/Makefile      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/libxutil/Makefile      Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/libxutil/hash_table.c
--- a/tools/vnet/libxutil/hash_table.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/libxutil/hash_table.c  Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/libxutil/hash_table.h
--- a/tools/vnet/libxutil/hash_table.h  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/libxutil/hash_table.h  Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/Makefile.ver
--- a/tools/vnet/vnet-module/Makefile.ver       Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/Makefile.ver       Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/esp.c
--- a/tools/vnet/vnet-module/esp.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/esp.c      Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/etherip.c
--- a/tools/vnet/vnet-module/etherip.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/etherip.c  Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/tunnel.c
--- a/tools/vnet/vnet-module/tunnel.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/tunnel.c   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/tunnel.h
--- a/tools/vnet/vnet-module/tunnel.h   Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/tunnel.h   Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/varp.c
--- a/tools/vnet/vnet-module/varp.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/varp.c     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/varp_socket.c
--- a/tools/vnet/vnet-module/varp_socket.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/varp_socket.c      Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vif.c
--- a/tools/vnet/vnet-module/vif.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/vif.c      Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet.c
--- a/tools/vnet/vnet-module/vnet.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/vnet.c     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet_dev.c
--- a/tools/vnet/vnet-module/vnet_dev.c Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/vnet_dev.c Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet_eval.c
--- a/tools/vnet/vnet-module/vnet_eval.c        Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/vnet_eval.c        Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnet-module/vnet_forward.c
--- a/tools/vnet/vnet-module/vnet_forward.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnet-module/vnet_forward.c     Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnetd/Makefile
--- a/tools/vnet/vnetd/Makefile Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnetd/Makefile Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/vnet/vnetd/vnetd.c
--- a/tools/vnet/vnetd/vnetd.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/vnet/vnetd/vnetd.c  Sun Sep 24 13:10:13 2006 -0600
@@ -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 da942e577e5e -r 432f978d1cd1 tools/xenmon/xenmon.py
--- a/tools/xenmon/xenmon.py    Thu Sep 21 15:35:45 2006 -0600
+++ b/tools/xenmon/xenmon.py    Sun Sep 24 13:10:13 2006 -0600
@@ -675,6 +675,11 @@ def main():
     if options.mspersample < 0:
         parser.error("option --ms_per_sample: invalid negative value: '%d'" %
                      options.mspersample)
+    # If --ms_per_sample= is too large, no data may be logged.
+    if not options.live and options.duration != 0 and \
+       options.mspersample > options.duration * 1000:
+        parser.error("option --ms_per_sample: too large (> %d ms)" %
+                     (options.duration * 1000))
     
     start_xenbaked()
     if options.live:
diff -r da942e577e5e -r 432f978d1cd1 
tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py
--- a/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Sun Sep 24 13:10:13 
2006 -0600
@@ -42,7 +42,7 @@ except ConsoleError, e:
     FAIL("Error while creating /dev/tpm0")
 
 try:
-    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > seq; cat seq > /dev/tpm0")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
diff -r da942e577e5e -r 432f978d1cd1 
tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py
--- a/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py      Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py      Sun Sep 24 13:10:13 
2006 -0600
@@ -43,7 +43,7 @@ except ConsoleError, e:
     FAIL("Error while creating /dev/tpm0")
 
 try:
-    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > seq; cat seq > /dev/tpm0")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
diff -r da942e577e5e -r 432f978d1cd1 
tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py
--- a/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py      Thu Sep 21 15:35:45 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py      Sun Sep 24 13:10:13 
2006 -0600
@@ -43,7 +43,7 @@ except ConsoleError, e:
     FAIL("Error while creating /dev/tpm0")
 
 try:
-    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > seq; cat seq > /dev/tpm0")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
diff -r da942e577e5e -r 432f978d1cd1 unmodified_drivers/linux-2.6/mkbuildtree
--- a/unmodified_drivers/linux-2.6/mkbuildtree  Thu Sep 21 15:35:45 2006 -0600
+++ b/unmodified_drivers/linux-2.6/mkbuildtree  Sun Sep 24 13:10:13 2006 -0600
@@ -42,6 +42,12 @@ i[34567]86)
        ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm
        ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm
        ;;
+"ia64")
+       ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm
+       ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm
+       ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm
+       ln -sf ${XL}/include/asm-ia64/maddr.h include/asm
+       ;;
 *)
        echo unknown architecture $uname
        exit 1
diff -r da942e577e5e -r 432f978d1cd1 
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Thu Sep 21 
15:35:45 2006 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Sun Sep 24 
13:10:13 2006 -0600
@@ -117,6 +117,7 @@ unsigned long alloc_xen_mmio(unsigned lo
        return addr;
 }
 
+#ifndef __ia64__
 /* Lifted from hvmloader.c */
 static int get_hypercall_stubs(void)
 {
@@ -162,6 +163,9 @@ static int get_hypercall_stubs(void)
 
        return 0;
 }
+#else /* __ia64__ */
+#define get_hypercall_stubs()  (0)
+#endif
 
 static int __devinit platform_pci_init(struct pci_dev *pdev,
                                       const struct pci_device_id *ent)
@@ -207,7 +211,6 @@ static int __devinit platform_pci_init(s
        if (ret < 0)
                goto out;
 
-       
        if ((ret = init_xen_info()))
                goto out;
 
@@ -228,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 da942e577e5e -r 432f978d1cd1 xen/Makefile
--- a/xen/Makefile      Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/Makefile      Sun Sep 24 13:10:13 2006 -0600
@@ -90,10 +90,9 @@ include/xen/acm_policy.h:
          echo "#endif") >$@
 
 # compile.h contains dynamic build info. Rebuilt on every 'make' invocation.
-include/xen/compile.h: LANG=C
 include/xen/compile.h: include/xen/compile.h.in
-       @sed -e 's/@@date@@/$(shell date)/g' \
-           -e 's/@@time@@/$(shell date +%T)/g' \
+       @sed -e 's/@@date@@/$(shell LC_ALL=C date)/g' \
+           -e 's/@@time@@/$(shell LC_ALL=C date +%T)/g' \
            -e 's/@@whoami@@/$(shell whoami)/g' \
            -e 's/@@domain@@/$(shell ([ -x /bin/dnsdomainname ] && 
/bin/dnsdomainname) || ([ -x /bin/domainname ] && /bin/domainname || echo 
[unknown]))/g' \
            -e 's/@@hostname@@/$(shell hostname)/g' \
@@ -124,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 da942e577e5e -r 432f978d1cd1 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/ia64/xen/mm.c    Sun Sep 24 13:10:13 2006 -0600
@@ -1627,13 +1627,6 @@ void put_page_type(struct page_info *pag
                 nx &= ~PGT_validated;
             }
         }
-        else if ( unlikely(((nx & (PGT_pinned | PGT_count_mask)) ==
-                            (PGT_pinned | 1)) &&
-                           ((nx & PGT_type_mask) != PGT_writable_page)) )
-        {
-            /* Page is now only pinned. Make the back pointer mutable again. */
-            nx |= PGT_va_mutable;
-        }
     }
     while ( unlikely((y = cmpxchg_rel(&page->u.inuse.type_info, x, nx)) != x) 
);
 }
@@ -1642,6 +1635,8 @@ int get_page_type(struct page_info *page
 int get_page_type(struct page_info *page, u32 type)
 {
     u32 nx, x, y = page->u.inuse.type_info;
+
+    ASSERT(!(type & ~PGT_type_mask));
 
  again:
     do {
@@ -1654,29 +1649,25 @@ int get_page_type(struct page_info *page
         }
         else if ( unlikely((x & PGT_count_mask) == 0) )
         {
-            if ( (x & (PGT_type_mask|PGT_va_mask)) != type )
+            if ( (x & PGT_type_mask) != type )
             {
-                if ( (x & PGT_type_mask) != (type & PGT_type_mask) )
+                /*
+                 * On type change we check to flush stale TLB entries. This 
+                 * may be unnecessary (e.g., page was GDT/LDT) but those 
+                 * circumstances should be very rare.
+                 */
+                cpumask_t mask =
+                    page_get_owner(page)->domain_dirty_cpumask;
+                tlbflush_filter(mask, page->tlbflush_timestamp);
+
+                if ( unlikely(!cpus_empty(mask)) )
                 {
-                    /*
-                     * On type change we check to flush stale TLB
-                     * entries. This may be unnecessary (e.g., page
-                     * was GDT/LDT) but those circumstances should be
-                     * very rare.
-                     */
-                    cpumask_t mask =
-                        page_get_owner(page)->domain_dirty_cpumask;
-                    tlbflush_filter(mask, page->tlbflush_timestamp);
-
-                    if ( unlikely(!cpus_empty(mask)) )
-                    {
-                        perfc_incrc(need_flush_tlb_flush);
-                        flush_tlb_mask(mask);
-                    }
+                    perfc_incrc(need_flush_tlb_flush);
+                    flush_tlb_mask(mask);
                 }
 
                 /* We lose existing type, back pointer, and validity. */
-                nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated);
+                nx &= ~(PGT_type_mask | PGT_validated);
                 nx |= type;
 
                 /* No special validation needed for writable pages. */
@@ -1685,46 +1676,22 @@ int get_page_type(struct page_info *page
                     nx |= PGT_validated;
             }
         }
-        else
+        else if ( unlikely((x & PGT_type_mask) != type) )
         {
-            if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) )
-            {
-                if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
-                {
-                    if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
-                         ((type & PGT_type_mask) != PGT_l1_page_table) )
-                        MEM_LOG("Bad type (saw %08x != exp %08x) "
-                                "for mfn %016lx (pfn %016lx)",
-                                x, type, page_to_mfn(page),
-                                get_gpfn_from_mfn(page_to_mfn(page)));
-                    return 0;
-                }
-                else if ( (x & PGT_va_mask) == PGT_va_mutable )
-                {
-                    /* The va backpointer is mutable, hence we update it. */
-                    nx &= ~PGT_va_mask;
-                    nx |= type; /* we know the actual type is correct */
-                }
-                else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
-                          ((type & PGT_va_mask) != (x & PGT_va_mask)) )
-                {
-#ifdef CONFIG_X86_PAE
-                    /* We use backptr as extra typing. Cannot be unknown. */
-                    if ( (type & PGT_type_mask) == PGT_l2_page_table )
-                        return 0;
-#endif
-                    /* This table is possibly mapped at multiple locations. */
-                    nx &= ~PGT_va_mask;
-                    nx |= PGT_va_unknown;
-                }
-            }
-            if ( unlikely(!(x & PGT_validated)) )
-            {
-                /* Someone else is updating validation of this page. Wait... */
-                while ( (y = page->u.inuse.type_info) == x )
-                    cpu_relax();
-                goto again;
-            }
+            if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
+                 (type != PGT_l1_page_table) )
+                MEM_LOG("Bad type (saw %08x != exp %08x) "
+                        "for mfn %016lx (pfn %016lx)",
+                        x, type, page_to_mfn(page),
+                        get_gpfn_from_mfn(page_to_mfn(page)));
+            return 0;
+        }
+        else if ( unlikely(!(x & PGT_validated)) )
+        {
+            /* Someone else is updating validation of this page. Wait... */
+            while ( (y = page->u.inuse.type_info) == x )
+                cpu_relax();
+            goto again;
         }
     }
     while ( unlikely((y = cmpxchg_acq(&page->u.inuse.type_info, x, nx)) != x) 
);
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/ia64/xen/xensetup.c      Sun Sep 24 13:10:13 2006 -0600
@@ -38,7 +38,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 **);
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/0opt.c
--- a/xen/arch/powerpc/0opt.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/0opt.c   Sun Sep 24 13:10:13 2006 -0600
@@ -19,10 +19,10 @@
  */
 
 #include <xen/config.h>
-#include <asm/misc.h>
+#include <xen/lib.h>
 
 extern void __cmpxchg_called_with_bad_pointer(void);
 void __cmpxchg_called_with_bad_pointer(void)
 {
-    trap();
+    BUG();
 }
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/Makefile Sun Sep 24 13:10:13 2006 -0600
@@ -13,7 +13,7 @@ obj-y += dart_u3.o
 obj-y += dart_u3.o
 obj-y += dart_u4.o
 obj-y += delay.o
-obj-y += dom0_ops.o
+obj-y += domctl.o
 obj-y += domain_build.o
 obj-y += domain.o
 obj-y += exceptions.o
@@ -36,6 +36,8 @@ obj-y += setup.o
 obj-y += setup.o
 obj-y += shadow.o
 obj-y += smp.o
+obj-y += smp-tbsync.o
+obj-y += sysctl.o
 obj-y += time.o
 obj-y += usercopy.o
 
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/backtrace.c
--- a/xen/arch/powerpc/backtrace.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/backtrace.c      Sun Sep 24 13:10:13 2006 -0600
@@ -191,3 +191,20 @@ void show_backtrace(ulong sp, ulong lr, 
     backtrace(sp, lr, pc);
     console_end_sync();
 }
+
+void __warn(char *file, int line)
+{
+    ulong sp;
+    ulong lr;
+
+    console_start_sync();
+    printk("WARN at %s:%d\n", file, line);
+
+    sp = (ulong)__builtin_frame_address(0);
+    lr = (ulong)__builtin_return_address(0);
+
+    backtrace(sp, lr, lr);
+    console_end_sync();
+}
+
+    
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c        Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/boot_of.c        Sun Sep 24 13:10:13 2006 -0600
@@ -31,6 +31,7 @@
 #include <asm/io.h>
 #include "exceptions.h"
 #include "of-devtree.h"
+#include "oftree.h"
 
 /* Secondary processors use this for handshaking with main processor.  */
 volatile unsigned int __spin_ack;
@@ -38,7 +39,6 @@ static ulong of_vec;
 static ulong of_vec;
 static ulong of_msr;
 static int of_out;
-static ofdn_t boot_cpu;
 static char bootargs[256];
 
 #define COMMAND_LINE_SIZE 512
@@ -669,7 +669,7 @@ static int boot_of_fixup_chosen(void *me
             dn = ofd_node_find(mem, ofpath);
             if (dn <= 0) of_panic("no node for: %s\n", ofpath);
 
-            boot_cpu = dn;
+            ofd_boot_cpu = dn;
             val = dn;
 
             dn = ofd_node_find(mem, "/chosen");
@@ -681,7 +681,7 @@ static int boot_of_fixup_chosen(void *me
         } else {
             of_printf("*** can't find path to booting cpu, "
                     "SMP is disabled\n");
-            boot_cpu = -1;
+            ofd_boot_cpu = -1;
         }
     }
     return rc;
@@ -773,7 +773,7 @@ static void __init boot_of_fix_maple(voi
     }
 }
     
-static int __init boot_of_serial(void *oftree)
+static int __init boot_of_serial(void *oft)
 {
     int n;
     int p;
@@ -805,7 +805,7 @@ static int __init boot_of_serial(void *o
             continue;
 
         of_printf("pruning `%s' from devtree\n", buf);
-        rc = ofd_prune_path(oftree, buf);
+        rc = ofd_prune_path(oft, buf);
         if (rc < 0)
             of_panic("prune of `%s' failed\n", buf);
     }
@@ -858,8 +858,8 @@ static void boot_of_module(ulong r3, ulo
 static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
 {
     static module_t mods[3];
-    void *oftree;
-    ulong oftree_sz = 48 * PAGE_SIZE;
+    void *oft;
+    ulong oft_sz = 48 * PAGE_SIZE;
     ulong mod0_start;
     ulong mod0_size;
     static const char sepr[] = " -- ";
@@ -922,28 +922,28 @@ static void boot_of_module(ulong r3, ulo
     }
 
     /* snapshot the tree */
-    oftree = (void*)find_space(oftree_sz, PAGE_SIZE, mbi);
-    if (oftree == 0)
+    oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi);
+    if (oft == 0)
         of_panic("Could not allocate OFD tree\n");
 
-    of_printf("creating oftree\n");
+    of_printf("creating oft\n");
     of_test("package-to-path");
-    oftree = ofd_create(oftree, oftree_sz);
-    pkg_save(oftree);
-
-    if (ofd_size(oftree) > oftree_sz)
+    oft = ofd_create(oft, oft_sz);
+    pkg_save(oft);
+
+    if (ofd_size(oft) > oft_sz)
          of_panic("Could not fit all of native devtree\n");
 
-    boot_of_fixup_refs(oftree);
-    boot_of_fixup_chosen(oftree);
-
-    if (ofd_size(oftree) > oftree_sz)
+    boot_of_fixup_refs(oft);
+    boot_of_fixup_chosen(oft);
+
+    if (ofd_size(oft) > oft_sz)
          of_panic("Could not fit all devtree fixups\n");
 
-    ofd_walk(oftree, OFD_ROOT, /* add_hype_props */ NULL, 2);
-
-    mods[1].mod_start = (ulong)oftree;
-    mods[1].mod_end = mods[1].mod_start + oftree_sz;
+    ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2);
+
+    mods[1].mod_start = (ulong)oft;
+    mods[1].mod_end = mods[1].mod_start + oft_sz;
     of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__,
               mods[1].mod_start, mods[1].mod_end);
 
@@ -952,26 +952,36 @@ static void boot_of_module(ulong r3, ulo
     mbi->mods_count = 2;
     mbi->mods_addr = (u32)mods;
 
-    boot_of_serial(oftree);
+    boot_of_serial(oft);
 }
 
 static int __init boot_of_cpus(void)
 {
-    int cpus;
-    int cpu, bootcpu, logical;
+    int cpus_node;
+    int cpu_node, bootcpu_node, logical;
     int result;
+    s32 cpuid;
     u32 cpu_clock[2];
-
-    cpus = of_finddevice("/cpus");
-    cpu = of_getchild(cpus);
-    result = of_getprop(cpu, "timebase-frequency", &timebase_freq,
+    extern uint cpu_hard_id[NR_CPUS];
+
+    /* Look up which CPU we are running on right now and get all info
+     * from there */
+    result = of_getprop(bof_chosen, "cpu",
+                        &bootcpu_node, sizeof (bootcpu_node));
+    if (result == OF_FAILURE)
+        of_panic("Failed to look up boot cpu\n");
+
+    cpu_node = bootcpu_node;
+
+    result = of_getprop(cpu_node, "timebase-frequency", &timebase_freq,
             sizeof(timebase_freq));
     if (result == OF_FAILURE) {
         of_panic("Couldn't get timebase frequency!\n");
     }
     of_printf("OF: timebase-frequency = %d Hz\n", timebase_freq);
 
-    result = of_getprop(cpu, "clock-frequency", &cpu_clock, sizeof(cpu_clock));
+    result = of_getprop(cpu_node, "clock-frequency",
+                        &cpu_clock, sizeof(cpu_clock));
     if (result == OF_FAILURE || (result !=4 && result != 8)) {
         of_panic("Couldn't get clock frequency!\n");
     }
@@ -983,69 +993,79 @@ static int __init boot_of_cpus(void)
     cpu_khz /= 1000;
     of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz);
 
-    /* Look up which CPU we are running on right now.  */
-    result = of_getprop(bof_chosen, "cpu", &bootcpu, sizeof (bootcpu));
-    if (result == OF_FAILURE)
-        of_panic("Failed to look up boot cpu\n");
-
-    cpu = of_getpeer(cpu);
-
-    /* We want a continuous logical cpu number space.  */
+    /* We want a continuous logical cpu number space and we'll make
+     * the booting CPU logical 0.  */
     cpu_set(0, cpu_present_map);
     cpu_set(0, cpu_online_map);
     cpu_set(0, cpu_possible_map);
 
-    /* Spin up all CPUS, even if there are more than NR_CPUS, because
-     * Open Firmware has them spinning on cache lines which will
-     * eventually be scrubbed, which could lead to random CPU activation.
+    result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+    cpu_hard_id[0] = cpuid;
+
+    /* Spin up all CPUS, even if there are more than NR_CPUS or we are
+     * runnign nosmp, because Open Firmware has them spinning on cache
+     * lines which will eventually be scrubbed, which could lead to
+     * random CPU activation.
      */
-    for (logical = 1; cpu > 0; logical++) {
-        unsigned int cpuid, ping, pong;
+
+    /* Find the base of the multi-CPU package node */
+    cpus_node = of_finddevice("/cpus");
+    if (cpus_node <= 0) {
+        of_printf("Single Processor System\n");
+        return 1;
+    }
+    /* Start with the first child */
+    cpu_node = of_getchild(cpus_node);
+
+    for (logical = 1; cpu_node > 0; logical++) {
+        unsigned int ping, pong;
         unsigned long now, then, timeout;
-
-        if (cpu == bootcpu) {
-            of_printf("skipping boot cpu!\n");
-            continue;
-        }
-
-        result = of_getprop(cpu, "reg", &cpuid, sizeof(cpuid));
-        if (result == OF_FAILURE)
-            of_panic("cpuid lookup failed\n");
-
-        of_printf("spinning up secondary processor #%d: ", logical);
-
-        __spin_ack = ~0x0;
-        ping = __spin_ack;
-        pong = __spin_ack;
-        of_printf("ping = 0x%x: ", ping);
-
-        mb();
-        result = of_start_cpu(cpu, (ulong)spin_start, logical);
-        if (result == OF_FAILURE)
-            of_panic("start cpu failed\n");
-
-        /* We will give the secondary processor five seconds to reply.  */
-        then = mftb();
-        timeout = then + (5 * timebase_freq);
-
-        do {
-            now = mftb();
-            if (now >= timeout) {
-                of_printf("BROKEN: ");
-                break;
+        
+        if (cpu_node == bootcpu_node) {
+            /* same CPU as boot CPU shich we have already made 0 so
+             * reduce the logical count */
+            --logical;
+        } else {
+            result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+            if (result == OF_FAILURE)
+                of_panic("cpuid lookup failed\n");
+
+            cpu_hard_id[logical] = cpuid;
+
+            of_printf("spinning up secondary processor #%d: ", logical);
+
+            __spin_ack = ~0x0;
+            ping = __spin_ack;
+            pong = __spin_ack;
+            of_printf("ping = 0x%x: ", ping);
+
+            mb();
+            result = of_start_cpu(cpu_node, (ulong)spin_start, logical);
+            if (result == OF_FAILURE)
+                of_panic("start cpu failed\n");
+
+            /* We will give the secondary processor five seconds to reply.  */
+            then = mftb();
+            timeout = then + (5 * timebase_freq);
+
+            do {
+                now = mftb();
+                if (now >= timeout) {
+                    of_printf("BROKEN: ");
+                    break;
+                }
+
+                mb();
+                pong = __spin_ack;
+            } while (pong == ping);
+            of_printf("pong = 0x%x\n", pong);
+
+            if (pong != ping) {
+                cpu_set(logical, cpu_present_map);
+                cpu_set(logical, cpu_possible_map);
             }
-
-            mb();
-            pong = __spin_ack;
-        } while (pong == ping);
-        of_printf("pong = 0x%x\n", pong);
-
-        if (pong != ping) {
-            cpu_set(logical, cpu_present_map);
-            cpu_set(logical, cpu_possible_map);
-        }
-
-        cpu = of_getpeer(cpu);
+        }
+        cpu_node = of_getpeer(cpu_node);
     }
     return 1;
 }
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/dart.c
--- a/xen/arch/powerpc/dart.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/dart.c   Sun Sep 24 13:10:13 2006 -0600
@@ -114,7 +114,7 @@ static void dart_fill(ulong index, int p
         ++rpg;
         if (i == num_pg) break;
 
-        if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) {
+        if ((((ulong)&entry[i]) % cpu_caches.dline_size) == 0) {
             last_flush = (ulong)&entry[i - 1];
             dcbst(last_flush);
         }
@@ -134,7 +134,7 @@ static void dart_clear(ulong index, ulon
         ++i;
         if (i == num_pg) break;
 
-        if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) {
+        if ((((ulong)&entry[i]) % cpu_caches.dline_size) == 0) {
             last_flush = (ulong)&entry[i - 1];
             dcbst(last_flush);
         }
@@ -207,16 +207,17 @@ static int find_dart(struct dart_info *d
     if (rc <= 0)
         return -1;
 
+    if (ofd_strstr(compat, rc, "u4"))
+        di->di_model = DART_U4;
+    else if (ofd_strstr(compat, rc, "u3"))
+        di->di_model = DART_U3;
+    else {
+        DBG("%s: not a U3 or U4\n", __func__);
+        return -1;
+    }
+        
     di->di_base = DART_DEF_BASE;
 
-    if (strstr(compat, "u3")) {
-        di->di_model = DART_U3;
-    } else if (strstr(compat, "u4")) {
-        di->di_model = DART_U4;
-    } else {
-        DBG("%s: not a U3 or U4\n", __func__);
-        return -1;
-    }
     /* FIXME: this should actually be the HT reg value */
     di->di_window.dw_liobn = 0;
     di->di_window.dw_base_hi = 0;
@@ -263,7 +264,7 @@ static int init_dart(void)
     /* Linux uses a dummy page, filling "empty" DART entries with a
        reference to this page to capture stray DMA's */
     dummy_page = (ulong)alloc_xenheap_pages(1);
-    memset((void *)dummy_page, 0, PAGE_SIZE);
+    clear_page((void *)dummy_page);
     dummy_page >>= PAGE_SHIFT;
 
     printk("Initializing DART 0x%lx: tbl: %p[0x%lx] entries: 0x%lx\n",
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/domain.c Sun Sep 24 13:10:13 2006 -0600
@@ -29,11 +29,10 @@
 #include <xen/shutdown.h>
 #include <xen/shadow.h>
 #include <xen/mm.h>
+#include <xen/softirq.h>
 #include <asm/htab.h>
 #include <asm/current.h>
 #include <asm/hcalls.h>
-
-extern void idle_loop(void);
 
 #define next_arg(fmt, args) ({                                              \
     unsigned long __arg;                                                    \
@@ -47,6 +46,7 @@ extern void idle_loop(void);
     }                                                                       \
     __arg;                                                                  \
 })
+extern void idle_loop(void);
 
 unsigned long hypercall_create_continuation(unsigned int op,
         const char *format, ...)
@@ -75,31 +75,12 @@ unsigned long hypercall_create_continuat
 
 int arch_domain_create(struct domain *d)
 {
-    unsigned long rma_base;
-    unsigned long rma_sz;
-    uint rma_order_pages;
-    int rc;
-
     if (d->domain_id == IDLE_DOMAIN_ID) {
         d->shared_info = (void *)alloc_xenheap_page();
         clear_page(d->shared_info);
 
         return 0;
     }
-
-    /* allocate the real mode area */
-    rma_order_pages = cpu_default_rma_order_pages();
-    d->max_pages = 1UL << rma_order_pages;
-    d->tot_pages = 0;
-
-    rc = allocate_rma(d, rma_order_pages);
-    if (rc)
-        return rc;
-    rma_base = page_to_maddr(d->arch.rma_page);
-    rma_sz = rma_size(rma_order_pages);
-
-    d->shared_info = (shared_info_t *)
-        (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base);
 
     d->arch.large_page_sizes = cpu_large_page_orders(
         d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order));
@@ -198,7 +179,6 @@ void dump_pageframe_info(struct domain *
     }
 }
 
-
 void context_switch(struct vcpu *prev, struct vcpu *next)
 {
     struct cpu_user_regs *stack_regs = guest_cpu_user_regs();
@@ -262,12 +242,73 @@ void sync_vcpu_execstate(struct vcpu *v)
     return;
 }
 
+static void relinquish_memory(struct domain *d, struct list_head *list)
+{
+    struct list_head *ent;
+    struct page_info  *page;
+
+    /* Use a recursive lock, as we may enter 'free_domheap_page'. */
+    spin_lock_recursive(&d->page_alloc_lock);
+
+    ent = list->next;
+    while ( ent != list )
+    {
+        page = list_entry(ent, struct page_info, list);
+
+        /* Grab a reference to the page so it won't disappear from under us. */
+        if ( unlikely(!get_page(page, d)) )
+        {
+            /* Couldn't get a reference -- someone is freeing this page. */
+            ent = ent->next;
+            continue;
+        }
+        if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
+            put_page_and_type(page);
+
+        if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
+            put_page(page);
+
+        /* Follow the list chain and /then/ potentially free the page. */
+        ent = ent->next;
+        put_page(page);
+    }
+    spin_unlock_recursive(&d->page_alloc_lock);
+}
+
 void domain_relinquish_resources(struct domain *d)
 {
-    free_domheap_pages(d->arch.rma_page, d->arch.rma_order);
+    relinquish_memory(d, &d->page_list);
     free_extents(d);
+    return;
 }
 
 void arch_dump_domain_info(struct domain *d)
 {
 }
+
+extern void sleep(void);
+static void safe_halt(void)
+{
+    int cpu = smp_processor_id();
+
+    while (!softirq_pending(cpu))
+        sleep();
+}
+
+static void default_idle(void)
+{
+    local_irq_disable();
+    if ( !softirq_pending(smp_processor_id()) )
+        safe_halt();
+    else
+        local_irq_enable();
+}
+
+void idle_loop(void)
+{
+    for ( ; ; ) {
+        page_scrub_schedule_work();
+        default_idle();
+        do_softirq();
+    }
+}
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/elf32.c
--- a/xen/arch/powerpc/elf32.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/elf32.c  Sun Sep 24 13:10:13 2006 -0600
@@ -1,5 +1,7 @@
 #define parseelfimage parseelfimage_32
 #define loadelfimage loadelfimage_32
+#define xen_elfnote_string xen_elfnote_string32
+#define xen_elfnote_numeric xen_elfnote_numeric32
 #define ELFSIZE 32
 #include "../../common/elf.c"
 
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/exceptions.c
--- a/xen/arch/powerpc/exceptions.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/exceptions.c     Sun Sep 24 13:10:13 2006 -0600
@@ -16,6 +16,7 @@
  * Copyright (C) IBM Corp. 2005, 2006
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
  */
 
 #include <xen/config.h>
@@ -23,11 +24,11 @@
 #include <xen/sched.h>
 #include <xen/serial.h>
 #include <xen/gdbstub.h>
-#include <public/xen.h>
+#include <xen/console.h>
 #include <asm/time.h>
+#include <asm/processor.h>
 
 #undef DEBUG
-#define HDEC_PREEMPT
 
 extern ulong ppc_do_softirq(ulong orig_msr);
 extern void do_timer(struct cpu_user_regs *regs);
@@ -38,31 +39,10 @@ int hdec_sample = 0;
 
 void do_timer(struct cpu_user_regs *regs)
 {
-    /* XXX this is just here to keep HDEC from firing until
-     * reprogram_ac_timer() sets the proper next-tick time */
-    mthdec(timebase_freq);
-
-#ifdef HDEC_PREEMPT
+    /* Set HDEC high so it stops firing and can be reprogrammed by
+     * set_preempt() */
+    mthdec(INT_MAX);
     raise_softirq(TIMER_SOFTIRQ);
-#endif
-#ifdef DEBUG
-    {
-        int d;
-        if (regs->msr & MSR_HV) {
-            d = -1;
-        } else {
-            d = get_current()->domain->domain_id;
-        }
-        extern char serial_getc_nb(int handle);
-        if (0 && serial_getc_nb(0) > 0) {
-            printk("H: pc: 0x%lx lr: 0x%lx \n", regs->pc, regs->lr);
-        }
-        if (hdec_sample)  {
-            printk("H: pc: 0x%lx lr: 0x%lx \n", regs->pc, regs->lr);
-            hdec_sample = 0;
-        }
-    }
-#endif
 }
 
 void do_dec(struct cpu_user_regs *regs)
@@ -79,11 +59,22 @@ void program_exception(struct cpu_user_r
 #ifdef CRASH_DEBUG
     __trap_to_gdb(regs, cookie);
 #else /* CRASH_DEBUG */
+    int recover = 0;
+
+    console_start_sync();
+
     show_registers(regs);
     printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
     printk("hid4 0x%016lx\n", regs->hid4);
     printk("---[ backtrace ]---\n");
     show_backtrace(regs->gprs[1], regs->lr, regs->pc);
-    panic("%s: 0x%lx\n", __func__, cookie);
+
+    if (cookie == 0x200)
+        recover = cpu_machinecheck(regs);
+
+    if (!recover)
+        panic("%s: 0x%lx\n", __func__, cookie);
+
+    console_end_sync();
 #endif /* CRASH_DEBUG */
 }
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/exceptions.h
--- a/xen/arch/powerpc/exceptions.h     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/exceptions.h     Sun Sep 24 13:10:13 2006 -0600
@@ -51,4 +51,5 @@ extern char exception_vectors[];
 extern char exception_vectors[];
 extern char exception_vectors_end[];
 extern int spin_start[];
+extern int secondary_cpu_init(int cpuid, unsigned long r4);
 #endif
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/external.c
--- a/xen/arch/powerpc/external.c       Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/external.c       Sun Sep 24 13:10:13 2006 -0600
@@ -75,6 +75,7 @@ void do_external(struct cpu_user_regs *r
 void do_external(struct cpu_user_regs *regs)
 {
     int vec;
+    static unsigned spur_count;
 
     BUG_ON(!(regs->msr & MSR_EE));
     BUG_ON(mfmsr() & MSR_EE);
@@ -87,6 +88,14 @@ void do_external(struct cpu_user_regs *r
         do_IRQ(regs);
 
         BUG_ON(mfmsr() & MSR_EE);
+        spur_count = 0;
+    } else {
+        ++spur_count;
+        if (spur_count > 100)
+            panic("Too many (%d) spurrious interrupts in a row\n"
+                  "  Known problem, please halt and let machine idle/cool "
+                  "  then reboot\n",
+                  100);
     }
 }
 
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/hcalls.c
--- a/xen/arch/powerpc/hcalls.c Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/hcalls.c Sun Sep 24 13:10:13 2006 -0600
@@ -112,9 +112,8 @@ static void do_ni_papr_hypercall(struct 
 {
     struct vcpu *v = get_current();
 
-    printk("unsupported hcall 0x%lx was called by dom0x%x\n",
+    printk("unsupported PAPR hcall 0x%lx was called by dom0x%x\n",
             regs->gprs[3], v->domain->domain_id);
-    debugger_trap_immediate();
 
     regs->gprs[3] = H_Parameter;
 }
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/iommu.c
--- a/xen/arch/powerpc/iommu.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/iommu.c  Sun Sep 24 13:10:13 2006 -0600
@@ -52,7 +52,7 @@ int iommu_put(u32 buid, ulong ioba, unio
 
         pfn = tce.tce_bits.tce_rpn;
         mfn = pfn2mfn(d, pfn, &mtype);
-        if (mfn > 0) {
+        if (mfn != INVALID_MFN) {
 #ifdef DEBUG
             printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__,
                    ioba, pfn, mfn);
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/mm.c     Sun Sep 24 13:10:13 2006 -0600
@@ -39,7 +39,6 @@
 
 /* Frame table and its size in pages. */
 struct page_info *frame_table;
-unsigned long frame_table_size;
 unsigned long max_page;
 unsigned long total_pages;
 
@@ -87,12 +86,6 @@ void put_page_type(struct page_info *pag
             /* Record TLB information for flush later. */
             page->tlbflush_timestamp = tlbflush_current_time();
         }
-        else if ( unlikely((nx & (PGT_pinned|PGT_type_mask|PGT_count_mask)) == 
-                           (PGT_pinned | 1)) )
-        {
-            /* Page is now only pinned. Make the back pointer mutable again. */
-            nx |= PGT_va_mutable;
-        }
     }
     while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
 }
@@ -101,6 +94,8 @@ int get_page_type(struct page_info *page
 int get_page_type(struct page_info *page, unsigned long type)
 {
     unsigned long nx, x, y = page->u.inuse.type_info;
+
+    ASSERT(!(type & ~PGT_type_mask));
 
  again:
     do {
@@ -113,29 +108,25 @@ int get_page_type(struct page_info *page
         }
         else if ( unlikely((x & PGT_count_mask) == 0) )
         {
-            if ( (x & (PGT_type_mask|PGT_va_mask)) != type )
+            if ( (x & PGT_type_mask) != type )
             {
-                if ( (x & PGT_type_mask) != (type & PGT_type_mask) )
+                /*
+                 * On type change we check to flush stale TLB entries. This 
+                 * may be unnecessary (e.g., page was GDT/LDT) but those 
+                 * circumstances should be very rare.
+                 */
+                cpumask_t mask =
+                    page_get_owner(page)->domain_dirty_cpumask;
+                tlbflush_filter(mask, page->tlbflush_timestamp);
+
+                if ( unlikely(!cpus_empty(mask)) )
                 {
-                    /*
-                     * On type change we check to flush stale TLB
-                     * entries. This may be unnecessary (e.g., page
-                     * was GDT/LDT) but those circumstances should be
-                     * very rare.
-                     */
-                    cpumask_t mask =
-                        page_get_owner(page)->domain_dirty_cpumask;
-                    tlbflush_filter(mask, page->tlbflush_timestamp);
-
-                    if ( unlikely(!cpus_empty(mask)) )
-                    {
-                        perfc_incrc(need_flush_tlb_flush);
-                        flush_tlb_mask(mask);
-                    }
+                    perfc_incrc(need_flush_tlb_flush);
+                    flush_tlb_mask(mask);
                 }
 
                 /* We lose existing type, back pointer, and validity. */
-                nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated);
+                nx &= ~(PGT_type_mask | PGT_validated);
                 nx |= type;
 
                 /* No special validation needed for writable pages. */
@@ -144,36 +135,16 @@ int get_page_type(struct page_info *page
                     nx |= PGT_validated;
             }
         }
-        else
-        {
-            if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) )
-            {
-                if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
-                {
-                    return 0;
-                }
-                else if ( (x & PGT_va_mask) == PGT_va_mutable )
-                {
-                    /* The va backpointer is mutable, hence we update it. */
-                    nx &= ~PGT_va_mask;
-                    nx |= type; /* we know the actual type is correct */
-                }
-                else if ( (type & PGT_va_mask) != PGT_va_mutable )
-                {
-                    ASSERT((type & PGT_va_mask) != (x & PGT_va_mask));
-
-                    /* This table is possibly mapped at multiple locations. */
-                    nx &= ~PGT_va_mask;
-                    nx |= PGT_va_unknown;
-                }
-            }
-            if ( unlikely(!(x & PGT_validated)) )
-            {
-                /* Someone else is updating validation of this page. Wait... */
-                while ( (y = page->u.inuse.type_info) == x )
-                    cpu_relax();
-                goto again;
-            }
+        else if ( unlikely((x & PGT_type_mask) != type) )
+        {
+            return 0;
+        }
+        if ( unlikely(!(x & PGT_validated)) )
+        {
+            /* Someone else is updating validation of this page. Wait... */
+            while ( (y = page->u.inuse.type_info) == x )
+                cpu_relax();
+            goto again;
         }
     }
     while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
@@ -190,33 +161,26 @@ void __init init_frametable(void)
 void __init init_frametable(void)
 {
     unsigned long p;
-
-    frame_table_size = PFN_UP(max_page * sizeof(struct page_info));
-
-    p = alloc_boot_pages(min(frame_table_size, 4UL << 20), 1);
+    unsigned long nr_pages;
+    int i;
+
+    nr_pages = PFN_UP(max_page * sizeof(struct page_info));
+    nr_pages = min(nr_pages, (4UL << (20 - PAGE_SHIFT)));
+    
+
+    p = alloc_boot_pages(nr_pages, 1);
     if (p == 0)
         panic("Not enough memory for frame table\n");
 
     frame_table = (struct page_info *)(p << PAGE_SHIFT);
-    frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
-
-    memset(frame_table, 0, frame_table_size);
+    for (i = 0; i < nr_pages; i += 1)
+        clear_page((void *)((p + i) << PAGE_SHIFT));
 }
 
 long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
 {
     printk("%s: no PPC specific memory ops\n", __func__);
     return -ENOSYS;
-}
-
-void clear_page(void *page)
-{
-    if (on_mambo()) {
-        extern void *mambo_memset(void *,int ,__kernel_size_t);
-        mambo_memset(page, 0, PAGE_SIZE);
-    } else {
-        memset(page, 0, PAGE_SIZE);
-    }
 }
 
 extern void copy_page(void *dp, void *sp)
@@ -227,16 +191,6 @@ extern void copy_page(void *dp, void *sp
     } else {
         memcpy(dp, sp, PAGE_SIZE);
     }
-}
-
-static int mfn_in_hole(ulong mfn)
-{
-    /* totally cheating */
-    if (mfn >= (0xf0000000UL >> PAGE_SHIFT) &&
-        mfn < (((1UL << 32) - 1) >> PAGE_SHIFT))
-        return 1;
-
-    return 0;
 }
 
 static uint add_extent(struct domain *d, struct page_info *pg, uint order)
@@ -301,70 +255,119 @@ uint allocate_extents(struct domain *d, 
 
     return total_nrpages;
 }
-        
-int allocate_rma(struct domain *d, unsigned int order_pages)
-{
+
+int allocate_rma(struct domain *d, unsigned int order)
+{
+    struct vcpu *v;
     ulong rma_base;
-    ulong rma_sz = rma_size(order_pages);
-
-    d->arch.rma_page = alloc_domheap_pages(d, order_pages, 0);
+    ulong rma_sz;
+    int i;
+
+    if (d->arch.rma_page)
+        return -EINVAL;
+
+    d->arch.rma_page = alloc_domheap_pages(d, order, 0);
     if (d->arch.rma_page == NULL) {
-        DPRINTK("Could not allocate order_pages=%d RMA for domain %u\n",
-                order_pages, d->domain_id);
+        DPRINTK("Could not allocate order=%d RMA for domain %u\n",
+                order, d->domain_id);
         return -ENOMEM;
     }
-    d->arch.rma_order = order_pages;
+    d->arch.rma_order = order;
 
     rma_base = page_to_maddr(d->arch.rma_page);
+    rma_sz = rma_size(d->arch.rma_order);
+
     BUG_ON(rma_base & (rma_sz - 1)); /* check alignment */
 
-    /* XXX */
-    printk("clearing RMA: 0x%lx[0x%lx]\n", rma_base, rma_sz);
-    memset((void *)rma_base, 0, rma_sz);
+    printk("allocated RMA for Dom[%d]: 0x%lx[0x%lx]\n",
+           d->domain_id, rma_base, rma_sz);
+
+    for (i = 0; i < (1 << d->arch.rma_order); i++ ) {
+        /* Add in any extra CPUs that need flushing because of this page. */
+        d->arch.rma_page[i].count_info |= PGC_page_RMA;
+        clear_page((void *)page_to_maddr(&d->arch.rma_page[i]));
+    }
+
+    d->shared_info = (shared_info_t *)
+        (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base);
+
+    /* if there are already running vcpus, adjust v->vcpu_info */
+    /* XXX untested */
+    for_each_vcpu(d, v) {
+        v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
+    }
 
     return 0;
 }
-
-ulong pfn2mfn(struct domain *d, long pfn, int *type)
+void free_rma_check(struct page_info *page)
+{
+    if (test_bit(_PGC_page_RMA, &page->count_info) &&
+        !test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags))
+        panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
+}
+
+
+ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
 {
     ulong rma_base_mfn = page_to_mfn(d->arch.rma_page);
     ulong rma_size_mfn = 1UL << d->arch.rma_order;
     struct page_extents *pe;
-
-    if (pfn < rma_size_mfn) {
-        if (type)
-            *type = PFN_TYPE_RMA;
-        return pfn + rma_base_mfn;
-    }
-
+    ulong mfn = INVALID_MFN;
+    int t = PFN_TYPE_NONE;
+
+    /* quick tests first */
     if (test_bit(_DOMF_privileged, &d->domain_flags) &&
-        mfn_in_hole(pfn)) {
-        if (type)
-            *type = PFN_TYPE_IO;
-        return pfn;
-    }
-
-    /* quick tests first */
-    list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
-        uint end_pfn = pe->pfn + (1 << pe->order);
-
-        if (pfn >= pe->pfn && pfn < end_pfn) {
-            if (type)
-                *type = PFN_TYPE_LOGICAL;
-            return page_to_mfn(pe->pg) + (pfn - pe->pfn);
-        }
-    }
-
-    /* This hack allows dom0 to map all memory, necessary to
-     * initialize domU state. */
-    if (test_bit(_DOMF_privileged, &d->domain_flags)) {
-        if (type)
-            *type = PFN_TYPE_REMOTE;
-        return pfn;
-    }
-
-    BUG();
-    return 0;
+        cpu_io_mfn(pfn)) {
+        t = PFN_TYPE_IO;
+        mfn = pfn;
+    } else {
+        if (pfn < rma_size_mfn) {
+            t = PFN_TYPE_RMA;
+            mfn = pfn + rma_base_mfn;
+        } else {
+            list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
+                uint end_pfn = pe->pfn + (1 << pe->order);
+
+                if (pfn >= pe->pfn && pfn < end_pfn) {
+                    t = PFN_TYPE_LOGICAL;
+                    mfn = page_to_mfn(pe->pg) + (pfn - pe->pfn);
+                    break;
+                }
+            }
+        }
+        BUG_ON(t != PFN_TYPE_NONE && page_get_owner(mfn_to_page(mfn)) != d);
+    }
+
+    if (t == PFN_TYPE_NONE) {
+        /* This hack allows dom0 to map all memory, necessary to
+         * initialize domU state. */
+        if (test_bit(_DOMF_privileged, &d->domain_flags) &&
+            mfn_valid(pfn)) {
+            struct page_info *pg;
+
+            /* page better be allocated to some domain but not the caller */
+            pg = mfn_to_page(pfn);
+            if (!(pg->count_info & PGC_allocated))
+                panic("Foreign page: 0x%lx is not owned by any domain\n",
+                      mfn);
+            if (page_get_owner(pg) == d)
+                panic("Foreign page: 0x%lx is owned by this domain\n",
+                      mfn);
+                
+            t = PFN_TYPE_FOREIGN;
+            mfn = pfn;
+        }
+    }
+
+    if (mfn == INVALID_MFN) {
+        printk("%s: Dom[%d] pfn 0x%lx is not a valid page\n",
+               __func__, d->domain_id, pfn);
+    }
+
+    if (type)
+        *type = t;
+
+    return mfn;
 }
 
 void guest_physmap_add_page(
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/mpic_init.c
--- a/xen/arch/powerpc/mpic_init.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/mpic_init.c      Sun Sep 24 13:10:13 2006 -0600
@@ -27,6 +27,8 @@
 #include "of-devtree.h"
 
 #undef DEBUG
+#define CONFIG_SHARE_MPIC
+
 #ifdef DEBUG
 #define DBG(fmt...) printk(fmt)
 #else
@@ -319,7 +321,42 @@ static int find_mpic(void)
     return rc;
 }
 
+#ifdef CONFIG_SHARE_MPIC
 static struct hw_interrupt_type hc_irq;
+
+static struct hw_interrupt_type *share_mpic(
+    struct hw_interrupt_type *mpic_irq,
+    struct hw_interrupt_type *xen_irq)
+{
+    hc_irq.startup = mpic_irq->startup;
+    mpic_irq->startup = xen_irq->startup;
+
+    hc_irq.enable = mpic_irq->enable;
+    mpic_irq->enable = xen_irq->enable;
+
+    hc_irq.disable = mpic_irq->disable;
+    mpic_irq->disable = xen_irq->disable;
+
+    hc_irq.shutdown = mpic_irq->shutdown;
+    mpic_irq->shutdown = xen_irq->shutdown;
+
+    hc_irq.ack = mpic_irq->ack;
+    mpic_irq->ack = xen_irq->ack;
+
+    hc_irq.end = mpic_irq->end;
+    mpic_irq->end = xen_irq->end;
+
+    hc_irq.set_affinity = mpic_irq->set_affinity;
+    mpic_irq->set_affinity = xen_irq->set_affinity;
+
+    return &hc_irq;
+}
+
+#else  /* CONFIG_SHARE_MPIC */
+
+#define share_mpic(M,X) (M)
+
+#endif
 
 struct hw_interrupt_type *xen_mpic_init(struct hw_interrupt_type *xen_irq)
 {
@@ -329,6 +366,7 @@ struct hw_interrupt_type *xen_mpic_init(
     unsigned int ipi_offset;
     unsigned char *senses;
     unsigned int senses_count;
+    struct hw_interrupt_type *hit;
 
     printk("%s: start\n", __func__);
 
@@ -356,29 +394,10 @@ struct hw_interrupt_type *xen_mpic_init(
     BUG_ON(mpic == NULL);
     mpic_init(mpic);
 
-    hc_irq.startup = mpic->hc_irq.startup;
-    mpic->hc_irq.startup = xen_irq->startup;
-
-    hc_irq.enable = mpic->hc_irq.enable;
-    mpic->hc_irq.enable = xen_irq->enable;
-
-    hc_irq.disable = mpic->hc_irq.disable;
-    mpic->hc_irq.disable = xen_irq->disable;
-
-    hc_irq.shutdown = mpic->hc_irq.shutdown;
-    mpic->hc_irq.shutdown = xen_irq->shutdown;
-
-    hc_irq.ack = mpic->hc_irq.ack;
-    mpic->hc_irq.ack = xen_irq->ack;
-
-    hc_irq.end = mpic->hc_irq.end;
-    mpic->hc_irq.end = xen_irq->end;
-
-    hc_irq.set_affinity = mpic->hc_irq.set_affinity;
-    mpic->hc_irq.set_affinity = xen_irq->set_affinity;
+    hit = share_mpic(&mpic->hc_irq, xen_irq);
 
     printk("%s: success\n", __func__);
-    return &hc_irq;
+    return hit;
 }
 
 int xen_mpic_get_irq(struct cpu_user_regs *regs)
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/of-devtree.h
--- a/xen/arch/powerpc/of-devtree.h     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/of-devtree.h     Sun Sep 24 13:10:13 2006 -0600
@@ -22,6 +22,7 @@
 #define _OF_DEVTREE_H
 
 #include <xen/types.h>
+#include <xen/string.h>
 #include <public/xen.h>
 
 enum {
@@ -136,4 +137,20 @@ extern ofdn_t ofd_node_find_prev(void *m
 extern ofdn_t ofd_node_find_prev(void *mem, ofdn_t n);
 extern void ofd_init(int (*write)(const char *, size_t len));
 
+static inline int ofd_strstr(const char *s, int len, const char *str)
+{
+    int l = strlen(str);
+    do {
+        int n;
+
+        if (len >= l && strstr(s, str))
+            return 1;
+
+        n = strnlen(s, len) + 1;
+        len -= strnlen(s, len) + 1;
+        s += n;
+    } while (len > 0);
+    return 0;
+}
+
 #endif /* _OF_DEVTREE_H */
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/of_handler/xencomm.c
--- a/xen/arch/powerpc/of_handler/xencomm.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/of_handler/xencomm.c     Sun Sep 24 13:10:13 2006 -0600
@@ -50,18 +50,18 @@ static void *__xencomm_alloc_mini(void *
 static void *__xencomm_alloc_mini(void *area, int arealen)
 {
     unsigned long base = (unsigned long)area;
-    unsigned int pageoffset;
+    unsigned int left_in_page;
 
-    pageoffset = base % PAGE_SIZE;
+    left_in_page = PAGE_SIZE - base % PAGE_SIZE;
 
     /* we probably fit right at the front of area */
-    if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini)) {
+    if (left_in_page >= sizeof(struct xencomm_mini)) {
         return area;
     }
 
     /* if not, see if area is big enough to advance to the next page */
-    if ((arealen - pageoffset) >= sizeof(struct xencomm_mini))
-        return (void *)(base + pageoffset);
+    if ((arealen - left_in_page) >= sizeof(struct xencomm_mini))
+        return (void *)(base + left_in_page);
 
     /* area was too small */
     return NULL;
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/ofd_fixup.c
--- a/xen/arch/powerpc/ofd_fixup.c      Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/ofd_fixup.c      Sun Sep 24 13:10:13 2006 -0600
@@ -28,6 +28,8 @@
 
 #undef RTAS
 
+ofdn_t ofd_boot_cpu;
+
 #ifdef PAPR_VTERM
 static ofdn_t ofd_vdevice_vty(void *m, ofdn_t p, struct domain *d)
 {
@@ -172,24 +174,21 @@ static ofdn_t ofd_cpus_props(void *m, st
 #endif
 
     c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu));
+    if (ofd_boot_cpu == -1)
+        ofd_boot_cpu = c;
     while (c > 0) {
-        ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;
-        ofd_prop_add(m, c, "ibm,pft-size",
-                     ibm_pft_size, sizeof (ibm_pft_size));
-
-        /* FIXME: Check the the "l2-cache" property who's
-         * contents is an orphaned phandle? */
+        /* Since we are not MP yet we prune all but the booting cpu */
+        if (c == ofd_boot_cpu) {
+            ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;
+            ofd_prop_add(m, c, "ibm,pft-size",
+                         ibm_pft_size, sizeof (ibm_pft_size));
+
+            /* FIXME: Check the the "l2-cache" property who's
+             * contents is an orphaned phandle? */
+        } else
+            ofd_node_prune(m, c);
+
         c = ofd_node_find_next(m, c);
-
-        /* Since we are not MP yet we can prune the rest of the CPUs */
-        while (c > 0) {
-            ofdn_t nc;
-
-            nc = ofd_node_find_next(m, c);
-            ofd_node_prune(m, c);
-
-            c = nc;
-        }
     }
 
     return n;
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/oftree.h
--- a/xen/arch/powerpc/oftree.h Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/oftree.h Sun Sep 24 13:10:13 2006 -0600
@@ -21,10 +21,12 @@
 #ifndef _OFTREE_H
 #define _OFTREE_H
 #include <xen/multiboot.h>
+#include "of-devtree.h"
 
 extern ulong oftree;
 extern ulong oftree_len;
 extern ulong oftree_end;
+extern ofdn_t ofd_boot_cpu;
 
 extern int ofd_dom0_fixup(struct domain *d, ulong mem, start_info_t *si);
 extern void ofd_memory_props(void *m, struct domain *d);
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/papr/xlate.c
--- a/xen/arch/powerpc/papr/xlate.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/papr/xlate.c     Sun Sep 24 13:10:13 2006 -0600
@@ -118,11 +118,14 @@ static void h_enter(struct cpu_user_regs
     int pgshift = PAGE_SHIFT;
     ulong idx;
     int limit = 0;                /* how many PTEs to examine in the PTEG */
-    ulong lpn;
-    ulong rpn;
+    ulong pfn;
+    ulong mfn;
     struct vcpu *v = get_current();
     struct domain *d = v->domain;
     int mtype;
+    struct page_info *pg = NULL;
+    struct domain *f = NULL;
+
 
     htab = &d->arch.htab;
     if (ptex > (1UL << htab->log_num_ptes)) {
@@ -160,17 +163,21 @@ static void h_enter(struct cpu_user_regs
     /* get the correct logical RPN in terms of 4K pages need to mask
      * off lp bits and unused arpn bits if this is a large page */
 
-    lpn = ~0ULL << (pgshift - PAGE_SHIFT);
-    lpn = pte.bits.rpn & lpn;
-
-    rpn = pfn2mfn(d, lpn, &mtype);
+    pfn = ~0ULL << (pgshift - PAGE_SHIFT);
+    pfn = pte.bits.rpn & pfn;
+
+    mfn = pfn2mfn(d, pfn, &mtype);
+    if (mfn == INVALID_MFN) {
+        regs->gprs[3] =  H_Parameter;
+        return;
+    }
 
     if (mtype == PFN_TYPE_IO) {
         /* only a privilaged dom can access outside IO space */
         if ( !test_bit(_DOMF_privileged, &d->domain_flags) ) {
             regs->gprs[3] =  H_Privilege;
-            printk("%s: unprivileged access to logical page: 0x%lx\n",
-                   __func__, lpn);
+            printk("%s: unprivileged access to physical page: 0x%lx\n",
+                   __func__, pfn);
             return;
         }
 
@@ -188,7 +195,7 @@ static void h_enter(struct cpu_user_regs
         }
     }
     /* fixup the RPN field of our local PTE copy */
-    pte.bits.rpn = rpn | lp_bits;
+    pte.bits.rpn = mfn | lp_bits;
 
     /* clear reserved bits in high word */
     pte.bits.lock = 0x0;
@@ -199,20 +206,44 @@ static void h_enter(struct cpu_user_regs
     pte.bits.ts = 0x0;
     pte.bits.res2 = 0x0;
 
+    if (mtype == PFN_TYPE_FOREIGN) {
+        pg = mfn_to_page(mfn);
+        f = page_get_owner(pg);
+        
+        BUG_ON(f == d);
+
+        if (unlikely(!get_domain(f))) {
+            regs->gprs[3] = H_Rescinded;
+            return;
+        }
+        if (unlikely(!get_page(pg, f))) {
+            put_domain(f);
+            regs->gprs[3] = H_Rescinded;
+            return;
+        }
+    }
+
     if ( !(flags & H_EXACT) ) {
         /* PTEG (not specific PTE); clear 3 lowest bits */
         ptex &= ~0x7UL;
         limit = 7;
     }
 
-        /* data manipulations should be done prior to the pte insertion. */
+    /* data manipulations should be done prior to the pte insertion. */
     if ( flags & H_ZERO_PAGE ) {
-        memset((void *)(rpn << PAGE_SHIFT), 0, 1UL << pgshift);
+        ulong pg = mfn << PAGE_SHIFT;
+        ulong pgs = 1UL << pgshift;
+
+        while (pgs > 0) {
+            clear_page((void *)pg);
+            pg += PAGE_SIZE;
+            --pgs;
+        }
     }
 
     if ( flags & H_ICACHE_INVALIDATE ) {
         ulong k;
-        ulong addr = rpn << PAGE_SHIFT;
+        ulong addr = mfn << PAGE_SHIFT;
 
         for (k = 0; k < (1UL << pgshift); k += L1_CACHE_BYTES) {
             dcbst(addr + k);
@@ -225,7 +256,7 @@ static void h_enter(struct cpu_user_regs
 
     if ( flags & H_ICACHE_SYNCHRONIZE ) {
         ulong k;
-        ulong addr = rpn << PAGE_SHIFT;
+        ulong addr = mfn << PAGE_SHIFT;
         for (k = 0; k < (1UL << pgshift); k += L1_CACHE_BYTES) {
             icbi(addr + k);
             sync();
@@ -256,6 +287,12 @@ static void h_enter(struct cpu_user_regs
     /* If the PTEG is full then no additional values are returned. */
     printk("%s: PTEG FULL\n", __func__);
 #endif
+
+    if (pg != NULL)
+        put_page(pg);
+
+    if (f != NULL)
+        put_domain(f);
 
     regs->gprs[3] = H_PTEG_Full;
 }
@@ -476,9 +513,23 @@ static void h_remove(struct cpu_user_reg
 
     /* XXX - I'm very skeptical of doing ANYTHING if not bits.v */
     /* XXX - I think the spec should be questioned in this case (MFM) */
-    if (pte->bits.v == 0) {
+    if (lpte.bits.v == 0) {
         printk("%s: removing invalid entry\n", __func__);
     }
+
+    if (lpte.bits.v) {
+        ulong mfn = lpte.bits.rpn;
+        if (!cpu_io_mfn(mfn)) {
+            struct page_info *pg = mfn_to_page(mfn);
+            struct domain *f = page_get_owner(pg);
+
+            if (f != d) {
+                put_domain(f);
+                put_page(pg);
+            }
+        }
+    }
+
     asm volatile("eieio; std %1, 0(%0); ptesync"
             :
             : "b" (pte), "r" (0)
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/Makefile
--- a/xen/arch/powerpc/powerpc64/Makefile       Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/powerpc64/Makefile       Sun Sep 24 13:10:13 2006 -0600
@@ -6,6 +6,9 @@ obj-y += io.o
 obj-y += io.o
 obj-y += memcpy.o
 obj-y += ppc970.o
+obj-y += ppc970_machinecheck.o
+obj-y += ppc970_scom.o
 obj-y += prom_call.o
 obj-y += string.o
 obj-y += traps.o
+
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/domain.c
--- a/xen/arch/powerpc/powerpc64/domain.c       Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/powerpc64/domain.c       Sun Sep 24 13:10:13 2006 -0600
@@ -55,29 +55,39 @@ void load_sprs(struct vcpu *v)
     /* adjust the DEC value to account for cycles while not
      * running this OS */
     timebase_delta = mftb() - v->arch.timebase;
-    v->arch.dec -= timebase_delta;
+    if (timebase_delta > v->arch.dec)
+        v->arch.dec = 0;
+    else
+        v->arch.dec -= timebase_delta;
 }
 
 /* XXX evaluate all isyncs in segment code */
 
-static void flush_slb(struct vcpu *v)
+void flush_segments(void)
 {
-    struct slb_entry *slb0 = &v->arch.slb_entries[0];
+    struct slb_entry slb0;
+    ulong zero = 0;
 
-    slbia();
+    __asm__ __volatile__(
+        "slbmfev %0,%2\n"
+        "slbmfee %1,%2\n"
+        :"=&r"(slb0.slb_vsid), "=&r"(slb0.slb_esid)
+        :"r"(zero)
+        :"memory");
 
     /* we manually have to invalidate SLB[0] since slbia doesn't. */
     /* XXX name magic constants! */
-    if (slb0->slb_esid & (1 << (63 - 36))) {
+    if (slb0.slb_esid & SLB_ESID_VALID) {
         ulong rb;
         ulong class;
 
-        class = (slb0->slb_vsid >> (63 - 56)) & 1ULL;
-        rb = slb0->slb_esid & (~0ULL << (63 - 35));
-        rb |= class << (63 - 36);
+        class = !!(slb0.slb_vsid & SLB_ESID_CLASS);
+        rb = slb0.slb_esid & SLB_ESID_MASK;
+        rb |= class << SLBIE_CLASS_LOG;
 
         slbie(rb);
     }
+    slbia();
 }
 
 void save_segments(struct vcpu *v)
@@ -108,7 +118,7 @@ void save_segments(struct vcpu *v)
 #endif
     }
 
-    flush_slb(v);
+    flush_segments();
 }
 
 void load_segments(struct vcpu *v)
@@ -123,7 +133,8 @@ void load_segments(struct vcpu *v)
 
         /* FIXME: should we bother to restore invalid entries */
         /* stuff in the index here */
-        esid |= i & ((0x1UL << (63 - 52 + 1)) - 1);
+        esid &= ~SLBMTE_ENTRY_MASK;
+        esid |= i;
 
         __asm__ __volatile__(
                 "isync\n"
@@ -141,3 +152,27 @@ void load_segments(struct vcpu *v)
 #endif
     }
 }
+
+void dump_segments(int valid)
+{
+    int i;
+
+    printk("Dump %s SLB entries:\n", valid ? "VALID" : "ALL");
+
+    /* save all extra SLBs */
+    for (i = 0; i < NUM_SLB_ENTRIES; i++) {
+        ulong vsid;
+        ulong esid;
+
+        __asm__ __volatile__(
+                "slbmfev %0,%2\n"
+                "slbmfee %1,%2\n"
+                :"=&r"(vsid), "=&r"(esid)
+                :"r"(i)
+                :"memory");
+
+        if (valid && !(esid & SLB_ESID_VALID))
+            continue;
+        printf("S%02d: 0x%016lx 0x%016lx\n", i, vsid, esid);
+    }
+}
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/exceptions.S
--- a/xen/arch/powerpc/powerpc64/exceptions.S   Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/powerpc64/exceptions.S   Sun Sep 24 13:10:13 2006 -0600
@@ -1,27 +1,30 @@
 /*
- * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
+ * Copyright (C) IBM Corp. 2005, 2006
+ *
+ * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
-
+ 
 #include <asm/config.h>
 #include <asm/asm-offsets.h>
 #include <asm/reg_defs.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
+#include <asm/percpu.h>
 
 .macro SAVE_GPR regno uregs
 std \regno, (UREGS_gprs + GPR_WIDTH * \regno)(\uregs)
@@ -115,10 +118,13 @@ 1:
     mfspr r0, SPRN_HSPRG1
     std r0, UREGS_r13(r1)           /* save R13 from HSPRG1 */
 
-    /* done with processor_area; re-enable MSR:RI */ 
-    mfmsr r0
-    ori r0, r0, MSR_RI@l
-    mtmsrd r0
+    /* Only _one_ larx is allowed at a time.  Any future use will be
+     * rejected until the earlier one (if any) completes.  Since we
+     * may have interrupted a larx in the Domain, or Xen we need to
+     * clear any larx that may currently exist.  We could probably
+     * skip which for hcalls */
+    ldx r0, 0, r1
+    stdcx. r0, 0, r1
 
     /* save CTR and use it to jump */
     mfctr r0
@@ -144,6 +150,13 @@ 1:
     li r0, -1 /* we clobbered the OS's SRR0/SRR1 to get here. */
     std r0, UREGS_srr0(\uregs)
     std r0, UREGS_srr1(\uregs)
+
+    /* done with processor_area; re-enable MSR:RI */ 
+    mfmsr r0
+    ori r0, r0, MSR_RI@l
+    mtmsrd r0
+
+
 .endm
 
 /* For exceptions that use HSRR0/1 (preserving the OS's SRR0/1). */
@@ -164,6 +177,12 @@ 1:
     std r0, UREGS_srr0(\uregs)
     mfspr r0, SPRN_SRR1
     std r0, UREGS_srr1(\uregs)
+
+    /* done with processor_area; re-enable MSR:RI */ 
+    mfmsr r0
+    ori r0, r0, MSR_RI@l
+    mtmsrd r0
+
 .endm
 
 /* Hypervisor exception handling code; copied to physical address zero. */
@@ -178,6 +197,14 @@ zero:
     li r0, 0x0 /* exception vector for GDB stub */
     bctr
 
+    /* The following byte array is where any per-CPU state flags 
+     * that can be be used across interrupts.  Currently it is only used
+     * to track Cache Inhibited Mode when a Machine Check occurs. */
+     /* NOTE: This array is indexed by PIR NOT CPUID */
+    . = MCK_CPU_STAT_BASE
+    .space NR_CPUS
+    . = MCK_GOOD_HID4
+    .quad 0        
     . = 0x100 # System Reset
 ex_reset:
     /* XXX thread initialization */
@@ -188,8 +215,19 @@ ex_reset:
 
     . = 0x200 # Machine Check
 ex_machcheck:
-    GET_STACK r13 SPRN_SRR1
-    EXCEPTION_HEAD r13 ex_program_continued
+    /* Restore HID4 to a known state early, we do not recover from
+     * machine check yet, but when we do we shoul dbe able to restore
+     * HID4 to it proper value */
+    mtspr SPRN_HSPRG1, r13
+    ld r13, MCK_GOOD_HID4(0)
+    sync
+    mtspr SPRN_HID4, r13
+    isync
+    /* Hopefully we don't have to worry about the ERAT */
+    mfspr r13, SPRN_HSPRG1
+    /* and now back to our regularly schedualed program */
+    GET_STACK r13 SPRN_SRR1
+    EXCEPTION_HEAD r13 ex_machcheck_continued
     li r0, 0x200 /* exception vector for GDB stub */
     bctr
 
@@ -324,6 +362,10 @@ exception_vectors_end:
     HRFID
     b .                         /* prevent speculative icache fetch */
 .endm
+
+/* Not a whole lot just yet */
+ex_machcheck_continued:
+
 
 /* We enter with the exception number in r0. The EXCEPTION_SAVE_STATE macro
  * clobbers r0 though, so we have to move it around a little bit. Not ideal,
@@ -371,6 +413,7 @@ ex_hcall_continued:
     mfmsr r14
     ori r14, r14, MSR_EE
     xori r15, r14, MSR_EE
+
 hcall_test_all_events:
     mtmsrd r15, 1                       /* disable interrupts */
     ld r3, PAREA_vcpu(r13)
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/io.S
--- a/xen/arch/powerpc/powerpc64/io.S   Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/powerpc64/io.S   Sun Sep 24 13:10:13 2006 -0600
@@ -1,23 +1,27 @@
 /*
- * Copyright (C) 2005 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM Corporation
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2005, 2006
+ *
+ * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
 
 #include <asm/config.h>
 #include <asm/processor.h>
+#include <asm/percpu.h>
 
 /* Xen runs in real mode (i.e. untranslated, MMU disabled). This avoids TLB
  * flushes and also makes it easy to access all domains' memory. However, on
@@ -54,6 +58,12 @@
        sync
        mtspr SPRN_HID4, r5
        isync
+
+       /* Mark the processor as "in CI mode" */
+       mfspr r5, SPRN_PIR
+       li r6, MCK_CPU_STAT_CI
+       stb r6, MCK_CPU_STAT_BASE(r5)
+       sync
 .endm
 
 .macro ENABLE_DCACHE addr
@@ -63,6 +73,12 @@
        mtspr SPRN_HID4, r9
        isync
 
+       /* Mark the processor as "out of CI mode" */
+       mfspr r5, SPRN_PIR
+       li r6, 0
+       stb r6, MCK_CPU_STAT_BASE(r5)
+       sync
+       
        /* re-enable interrupts */
        mtmsr r8
 .endm
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/powerpc64/ppc970.c
--- a/xen/arch/powerpc/powerpc64/ppc970.c       Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/powerpc64/ppc970.c       Sun Sep 24 13:10:13 2006 -0600
@@ -17,6 +17,7 @@
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  *          Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Amos Waterland  <apw@xxxxxxxxxx>
  */
 
 #include <xen/config.h>
@@ -30,23 +31,31 @@
 #include <asm/powerpc64/processor.h>
 #include <asm/powerpc64/ppc970-hid.h>
 
+#undef DEBUG
 #undef SERIALIZE
 
-extern volatile struct processor_area * volatile global_cpu_table[];
+struct cpu_caches cpu_caches = {
+    .dline_size = 0x80,
+    .log_dline_size = 7,
+    .dlines_per_page = PAGE_SIZE >> 7,
+    .iline_size = 0x80,
+    .log_iline_size = 7,
+    .ilines_per_page = PAGE_SIZE >> 7,
+};
 
 struct rma_settings {
     int order;
-    int rmlr0;
-    int rmlr12;
+    int rmlr_0;
+    int rmlr_1_2;
 };
 
 static struct rma_settings rma_orders[] = {
-    { .order = 26, .rmlr0 = 0, .rmlr12 = 3, }, /*  64 MB */
-    { .order = 27, .rmlr0 = 1, .rmlr12 = 3, }, /* 128 MB */
-    { .order = 28, .rmlr0 = 1, .rmlr12 = 0, }, /* 256 MB */
-    { .order = 30, .rmlr0 = 0, .rmlr12 = 2, }, /*   1 GB */
-    { .order = 34, .rmlr0 = 0, .rmlr12 = 1, }, /*  16 GB */
-    { .order = 38, .rmlr0 = 0, .rmlr12 = 0, }, /* 256 GB */
+    { .order = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /*  64 MB */
+    { .order = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */
+    { .order = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */
+    { .order = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /*   1 GB */
+    { .order = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /*  16 GB */
+    { .order = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */
 };
 
 static uint log_large_page_sizes[] = {
@@ -68,6 +77,11 @@ unsigned int cpu_default_rma_order_pages
     return rma_orders[0].order - PAGE_SHIFT;
 }
 
+int cpu_rma_valid(unsigned int log)
+{
+    return cpu_find_rma(log) != NULL;
+}
+
 unsigned int cpu_large_page_orders(uint *sizes, uint max)
 {
     uint i = 0;
@@ -85,17 +99,63 @@ unsigned int cpu_extent_order(void)
     return log_large_page_sizes[0] - PAGE_SHIFT;
 }
 
+
+/* This is more a platform thing than a CPU thing, but we only have
+ * one platform now */
+int cpu_io_mfn(ulong mfn)
+{
+    /* totally cheating */
+    if (mfn >= (2UL << (30 - PAGE_SHIFT)) && /* 2GiB */
+        mfn < (4UL << (30 - PAGE_SHIFT)))    /* 4GiB */
+        return 1;
+
+    return 0;
+}
+
+static u64 cpu0_hids[6];
+static u64 cpu0_hior;
+
 void cpu_initialize(int cpuid)
 {
-    ulong r1, r2;
-    __asm__ __volatile__ ("mr %0, 1" : "=r" (r1));
-    __asm__ __volatile__ ("mr %0, 2" : "=r" (r2));
+    union hid0 hid0;
+    union hid1 hid1;
+    union hid4 hid4;
+    union hid5 hid5;
+
+    if (cpuid == 0) {
+        /* we can assume that these are sane to start with.  We
+         * _do_not_ store the results in case we want to mess with them
+         * on a per-cpu basis later. */
+        cpu0_hids[0] = mfhid0();
+        cpu0_hids[1] = mfhid1();
+        cpu0_hids[4] = mfhid4();
+        cpu0_hids[5] = mfhid5();
+        cpu0_hior = 0;
+    }
+
+    hid0.word = cpu0_hids[0];
+    hid1.word = cpu0_hids[1];
+    hid4.word = cpu0_hids[4];
+    hid5.word = cpu0_hids[5];
 
     /* This is SMP safe because the compiler must use r13 for it.  */
     parea = global_cpu_table[cpuid];
     ASSERT(parea != NULL);
 
     mthsprg0((ulong)parea); /* now ready for exceptions */
+
+    printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n",
+           mfpir(), hard_smp_processor_id(), smp_processor_id());
+
+#ifdef DEBUG
+    {
+        ulong r1, r2;
+
+        asm volatile ("mr %0, 1" : "=r" (r1));
+        asm volatile ("mr %0, 2" : "=r" (r2));
+        printk("  SP = %lx TOC = %lx\n",  r1, r2);
+    }
+#endif
 
     /* Set decrementers for 1 second to keep them out of the way during
      * intialization. */
@@ -103,59 +163,81 @@ void cpu_initialize(int cpuid)
     mtdec(timebase_freq);
     mthdec(timebase_freq);
 
-    union hid0 hid0;
-
-    hid0.word = mfhid0();
-    hid0.bits.nap = 1;
-    hid0.bits.dpm = 1;
-    hid0.bits.nhr = 1;
-    hid0.bits.hdice = 1; /* enable HDEC */
-    hid0.bits.eb_therm = 1;
-    hid0.bits.en_attn = 1;
+    hid0.bits.nap = 1;      /* NAP */
+    hid0.bits.dpm = 1;      /* Dynamic Power Management */
+    hid0.bits.nhr = 1;      /* Not Hard Reset */
+    hid0.bits.hdice_en = 1; /* enable HDEC */
+    hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */
+    /* only debug Xen should activate ATTN */
+    hid0.bits.en_attn = 1;  /* Enable attn instruction */
+    hid0.bits.en_mck = 1;   /* Enable external machine check interrupts */
+
 #ifdef SERIALIZE
-    ulong s = 0;
-
-    s |= 1UL << (63-0);     /* one_ppc */
-    s |= 1UL << (63-2);     /* isync_sc */
-    s |= 1UL << (63-16);     /* inorder */
+    hid0.bits.one_ppc = 1;
+    hid0.bits.isync_sc = 1;
+    hid0.bits.inorder = 1;
     /* may not want these */
-    s |= 1UL << (63-1);     /* do_single */
-    s |= 1UL << (63-3);     /* ser-gp */
-    hid0.word |= s;
-#endif
-
-    printk("CPU #%d: Hello World! SP = %lx TOC = %lx HID0 = %lx\n", 
-           smp_processor_id(), r1, r2, hid0.word);
+    hid0.bits.do_single = 1;
+    hid0.bits.ser-gp = 1;
+#endif
 
     mthid0(hid0.word);
 
-    union hid1 hid1;
-
-    hid1.word = mfhid1();
-    hid1.bits.bht_pm = 7;
-    hid1.bits.en_ls = 1;
-
-    hid1.bits.en_cc = 1;
-    hid1.bits.en_ic = 1;
-
-    hid1.bits.pf_mode = 2;
-
-    hid1.bits.en_if_cach = 1;
-    hid1.bits.en_ic_rec = 1;
-    hid1.bits.en_id_rec = 1;
-    hid1.bits.en_er_rec = 1;
-
-    hid1.bits.en_sp_itw = 1;
+    hid1.bits.bht_pm = 7; /* branch history table prediction mode */
+    hid1.bits.en_ls = 1; /* enable link stack */
+
+    hid1.bits.en_cc = 1; /* enable count cache */
+    hid1.bits.en_ic = 1; /* enable inst cache */
+
+    hid1.bits.pf_mode = 2; /* prefetch mode */
+
+    hid1.bits.en_if_cach = 1; /* i-fetch cacheability control */
+    hid1.bits.en_ic_rec = 1; /* i-cache parity error recovery */
+    hid1.bits.en_id_rec = 1; /* i-dir parity error recovery */
+    hid1.bits.en_er_rec = 1; /* i-ERAT parity error recovery */
+
+    hid1.bits.en_sp_itw = 1; /* En speculative tablewalks */
     mthid1(hid1.word);
 
-    union hid5 hid5;
-
-    hid5.word = mfhid5();
-    hid5.bits.DCBZ_size = 0;
-    hid5.bits.DCBZ32_ill = 0;
+    /* no changes to hid4 but we want to make sure that secondaries
+     * are sane */
+    hid4.bits.lg_pg_dis = 0;    /* make sure we enable large pages */
+    mthid4(hid4.word);
+
+    hid5.bits.DC_mck = 1; /* Machine check enabled for dcache errors */
+    hid5.bits.DCBZ_size = 0; /* make dcbz size 32 bytes */
+    hid5.bits.DCBZ32_ill = 0; /* make dzbz 32byte illeagal */
     mthid5(hid5.word);
 
-    __asm__ __volatile__("isync; slbia; isync" : : : "memory");
+#ifdef DEBUG
+    printk("hid0 0x%016lx\n"
+           "hid1 0x%016lx\n"
+           "hid4 0x%016lx\n"
+           "hid5 0x%016lx\n",
+           mfhid0(), mfhid1(), mfhid4(), mfhid5());
+#endif
+
+    /* Make sure firmware has not left this dirty */
+    mthior(cpu0_hior);
+
+    /* some machine check goodness */
+    /* save this for checkstop processing */
+    if (cpuid == 0)
+        *mck_good_hid4 = hid4.word;
+
+    if (mfpir() > NR_CPUS)
+        panic("we do not expect a processor to have a PIR (%u) "
+              "to be larger that NR_CPUS(%u)\n",
+              mfpir(), NR_CPUS);
+
+    cpu_scom_init();
+
+    /* initialize the SLB */
+#ifdef DEBUG
+    dump_segments(1);
+#endif
+    flush_segments();
+    local_flush_tlb();
 }
 
 void cpu_init_vcpu(struct vcpu *v)
@@ -166,18 +248,18 @@ void cpu_init_vcpu(struct vcpu *v)
 
     hid4.word = mfhid4();
 
-    hid4.bits.lpes0 = 0; /* exceptions set MSR_HV=1 */
-    hid4.bits.lpes1 = 1; /* RMA applies */
-
-    hid4.bits.rmor = page_to_maddr(d->arch.rma_page) >> 26;
-
-    hid4.bits.lpid01 = d->domain_id & 3;
-    hid4.bits.lpid25 = (d->domain_id >> 2) & 0xf;
+    hid4.bits.lpes_0 = 0; /* external exceptions set MSR_HV=1 */
+    hid4.bits.lpes_1 = 1; /* RMA applies */
+
+    hid4.bits.rmor_0_15 = page_to_maddr(d->arch.rma_page) >> 26;
+
+    hid4.bits.lpid_0_1 = d->domain_id & 3;
+    hid4.bits.lpid_2_5 = (d->domain_id >> 2) & 0xf;
 
     rma_settings = cpu_find_rma(d->arch.rma_order + PAGE_SHIFT);
     ASSERT(rma_settings != NULL);
-    hid4.bits.rmlr0 = rma_settings->rmlr0;
-    hid4.bits.rmlr12 = rma_settings->rmlr12;
+    hid4.bits.rmlr_0 = rma_settings->rmlr_0;
+    hid4.bits.rmlr_1_2 = rma_settings->rmlr_1_2;
 
     v->arch.cpu.hid4.word = hid4.word;
 }
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/setup.c  Sun Sep 24 13:10:13 2006 -0600
@@ -16,6 +16,8 @@
  * Copyright (C) IBM Corp. 2005, 2006
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Amos Waterland <apw@xxxxxxxxxx>
+ *          Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
 
 #include <xen/config.h>
@@ -41,6 +43,7 @@
 #include <asm/debugger.h>
 #include <asm/delay.h>
 #include <asm/percpu.h>
+#include <asm/io.h>
 #include "exceptions.h"
 #include "of-devtree.h"
 #include "oftree.h"
@@ -71,20 +74,18 @@ ulong oftree_len;
 ulong oftree_len;
 ulong oftree_end;
 
+uint cpu_hard_id[NR_CPUS] __initdata;
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
 cpumask_t cpu_present_map;
 cpumask_t cpu_possible_map;
 
 /* XXX get this from ISA node in device tree */
+char *vgabase;
 ulong isa_io_base;
 struct ns16550_defaults ns16550;
 
 extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[];
-extern void idle_loop(void);
-
-/* move us to a header file */
-extern void initialize_keytable(void);
 
 volatile struct processor_area * volatile global_cpu_table[NR_CPUS];
 
@@ -99,21 +100,6 @@ unsigned long kernel_text_end(void)
 unsigned long kernel_text_end(void)
 {
     return (unsigned long) &_etext;
-}
-
-void idle_loop(void)
-{
-    int cpu = smp_processor_id();
-
-    for ( ; ; )
-    {
-        while (!softirq_pending(cpu)) {
-            void sleep(void);
-            page_scrub_schedule_work();
-            sleep();
-        }
-        do_softirq();
-    }
 }
 
 static void __init do_initcalls(void)
@@ -209,6 +195,8 @@ static void __init start_of_day(void)
     schedulers_start();
 }
 
+extern void idle_loop(void);
+
 void startup_cpu_idle_loop(void)
 {
     struct vcpu *v = current;
@@ -237,6 +225,7 @@ static void init_parea(int cpuid)
               __func__, STACK_ORDER, cpuid);
 
     pa->whoami = cpuid;
+    pa->hard_id = cpu_hard_id[cpuid];
     pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE);
 
     /* This store has the effect of invoking secondary_cpu_init.  */
@@ -254,18 +243,22 @@ static int kick_secondary_cpus(int maxcp
         if (cpuid >= maxcpus)
             break;
         init_parea(cpuid);
-        cpu_set(cpuid, cpu_online_map);
-        cpu_set(cpuid, cpu_possible_map);
+        smp_generic_give_timebase();
+
+        /* wait for it */
+        while (!cpu_online(cpuid))
+            cpu_relax();
     }
 
     return 0;
 }
 
 /* This is the first C code that secondary processors invoke.  */
-int secondary_cpu_init(int cpuid, unsigned long r4);
 int secondary_cpu_init(int cpuid, unsigned long r4)
 {
     cpu_initialize(cpuid);
+    smp_generic_take_timebase();
+    cpu_set(cpuid, cpu_online_map);
     while(1);
 }
 
@@ -339,7 +332,7 @@ static void __init __start_xen(multiboot
 #endif
 
     /* Deal with secondary processors.  */
-    if (opt_nosmp) {
+    if (opt_nosmp || ofd_boot_cpu == -1) {
         printk("nosmp: leaving secondary processors spinning forever\n");
     } else {
         printk("spinning up at most %d total processors ...\n", max_cpus);
@@ -350,8 +343,17 @@ static void __init __start_xen(multiboot
 
     /* Create initial domain 0. */
     dom0 = domain_create(0);
-    if ((dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL))
+    if (dom0 == NULL)
         panic("Error creating domain 0\n");
+    dom0->max_pages = ~0U;
+    if (0 > allocate_rma(dom0, cpu_default_rma_order_pages()))
+        panic("Error allocating domain 0 RMA\n");
+    if (NULL == alloc_vcpu(dom0, 0, 0))
+        panic("Error creating domain 0 vcpu 0\n");
+
+    /* The Interrupt Controller will route everything to CPU 0 so we
+     * need to make sure Dom0's vVCPU 0 is pinned to the CPU */
+    dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
 
     set_bit(_DOMF_privileged, &dom0->domain_flags);
     /* post-create hooks sets security label */
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/shadow.c
--- a/xen/arch/powerpc/shadow.c Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/shadow.c Sun Sep 24 13:10:13 2006 -0600
@@ -78,7 +78,6 @@ unsigned int shadow_set_allocation(struc
                                     unsigned int megabytes,
                                     int *preempted)
 {
-    unsigned int rc;
     uint pages;
     uint p;
     uint order;
@@ -91,7 +90,7 @@ unsigned int shadow_set_allocation(struc
     if (megabytes == 0) {
         /* old management tools */
         megabytes = 1;          /* 1/64th of 64M */
-        printk("%s: Fix management tools to set and get shadow/htab values\n"
+        printk("%s: WARNING!!: Update your managment tools\n"
                "    using %d MiB htab\n",
                __func__, megabytes);
     }
@@ -112,7 +111,7 @@ unsigned int shadow_set_allocation(struc
     for (p = 0; p < (1 << order); p++)
         clear_page((void *)(addr + (p << PAGE_SHIFT)));
 
-    return rc;
+    return 0;
 }
 
 int shadow_domctl(struct domain *d, 
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/time.c
--- a/xen/arch/powerpc/time.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/time.c   Sun Sep 24 13:10:13 2006 -0600
@@ -34,40 +34,6 @@ unsigned long cpu_khz;
 unsigned long cpu_khz;
 unsigned int timebase_freq;
 
-u64 get_timebase(void)
-{
-    u64 s;
-
-#ifdef __PPC64__
-    s = mftb();
-#else
-    do {
-        unsigned up;
-        unsigned lo;
-        unsigned up2;
-
-        up = mftbu();
-        lo = mftbl();
-        up2 = mftbu();
-    } while (up1 != up2);
-    s = ((ulong)up << 32) | lo;
-#endif
-    return s;
-}
-
-static ulong ns_to_tb(ulong ns)
-{
-    return (ns * timebase_freq) / 1000000000ULL;
-}
-
-static ulong tb_to_ns(ulong tb)
-{
-    return tb * (1000000000ULL / timebase_freq);
-}
-
-/*
- * Return nanoseconds from time of boot
- */
 s_time_t get_s_time(void)
 {
     return tb_to_ns(get_timebase());
@@ -94,7 +60,7 @@ int reprogram_timer(s_time_t timeout)
     s_time_t expire;
 
     if (timeout == 0) {
-        expire = 0;
+        expire = INT_MAX;
     } else {
         s_time_t now;
 
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/powerpc/usercopy.c
--- a/xen/arch/powerpc/usercopy.c       Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/powerpc/usercopy.c       Sun Sep 24 13:10:13 2006 -0600
@@ -47,14 +47,30 @@ static unsigned long paddr_to_maddr(unsi
     pfn = pa >> PAGE_SHIFT;
 
     pa = pfn2mfn(d, pfn, &mtype);
+    if (pa == INVALID_MFN) {
+        printk("%s: Dom:%d bad paddr: 0x%lx\n",
+               __func__, d->domain_id, paddr);
+        return 0;
+    }
     switch (mtype) {
-        case PFN_TYPE_RMA:
-        case PFN_TYPE_LOGICAL:
-            break;
-        default:
-            panic("%s: called with bad memory address type: 0x%lx\n",
-                    __func__, paddr);
-            break;
+    case PFN_TYPE_RMA:
+    case PFN_TYPE_LOGICAL:
+        break;
+
+    case PFN_TYPE_FOREIGN:
+        /* I don't think this should ever happen, but I suppose it
+         * could be possible */
+        printk("%s: Dom:%d paddr: 0x%lx type: FOREIGN\n",
+               __func__, d->domain_id, paddr);
+        WARN();
+        break;
+
+    case PFN_TYPE_IO:
+    default:
+        printk("%s: Dom:%d paddr: 0x%lx bad type: 0x%x\n",
+               __func__, d->domain_id, paddr, mtype);
+        WARN();
+        return 0;
     }
     pa <<= PAGE_SHIFT;
     pa |= offset;
@@ -85,6 +101,9 @@ xencomm_copy_from_guest(void *to, const 
 
     /* first we need to access the descriptor */
     desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
+    if (desc == NULL)
+        return n;
+
     if (desc->magic != XENCOMM_MAGIC) {
         printk("%s: error: %p magic was 0x%x\n",
                __func__, desc, desc->magic);
@@ -117,6 +136,9 @@ xencomm_copy_from_guest(void *to, const 
             unsigned int bytes = min(chunksz, n - to_pos);
 
             src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
+            if (src_maddr == 0)
+                return n - to_pos;
+
             if (xencomm_debug)
                 printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
             memcpy((void *)dest, (void *)src_maddr, bytes);
@@ -153,6 +175,9 @@ xencomm_copy_to_guest(void *to, const vo
 
     /* first we need to access the descriptor */
     desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
+    if (desc == NULL)
+        return n;
+
     if (desc->magic != XENCOMM_MAGIC) {
         printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
         return n;
@@ -184,6 +209,9 @@ xencomm_copy_to_guest(void *to, const vo
             unsigned int bytes = min(chunksz, n - from_pos);
 
             dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
+            if (dest_maddr == 0)
+                return -1;
+
             if (xencomm_debug)
                 printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
             memcpy((void *)dest_maddr, (void *)source, bytes);
@@ -199,16 +227,19 @@ xencomm_copy_to_guest(void *to, const vo
 
 /* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
  * exhausted pages to XENCOMM_INVALID. */
-void xencomm_add_offset(void *handle, unsigned int bytes)
+int xencomm_add_offset(void *handle, unsigned int bytes)
 {
     struct xencomm_desc *desc;
     int i = 0;
 
     /* first we need to access the descriptor */
     desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
+    if (desc == NULL)
+        return -1;
+
     if (desc->magic != XENCOMM_MAGIC) {
         printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
-        return;
+        return -1;
     }
 
     /* iterate through the descriptor incrementing addresses */
@@ -230,6 +261,7 @@ void xencomm_add_offset(void *handle, un
         }
         bytes -= chunk_skip;
     }
+    return 0;
 }
 
 int xencomm_handle_is_null(void *ptr)
@@ -237,6 +269,9 @@ int xencomm_handle_is_null(void *ptr)
     struct xencomm_desc *desc;
 
     desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr);
+    if (desc == NULL)
+        return 1;
 
     return (desc->nr_addrs == 0);
 }
+
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/Rules.mk     Sun Sep 24 13:10:13 2006 -0600
@@ -42,6 +42,9 @@ ifeq ($(TARGET_SUBARCH),x86_64)
 ifeq ($(TARGET_SUBARCH),x86_64)
 CFLAGS  += -mno-red-zone -fpic -fno-reorder-blocks
 CFLAGS  += -fno-asynchronous-unwind-tables
+# -fvisibility=hidden reduces -fpic cost, if it's available
+CFLAGS  += $(shell $(CC) -v --help 2>&1 | grep " -fvisibility=" | \
+             grep -q hidden && echo "-fvisibility=hidden")
 LDFLAGS += -m elf_x86_64
 x86_32 := n
 x86_64 := y
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/acpi/boot.c
--- a/xen/arch/x86/acpi/boot.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/acpi/boot.c  Sun Sep 24 13:10:13 2006 -0600
@@ -106,7 +106,7 @@ char *__acpi_map_table(unsigned long phy
        unsigned long base, offset, mapped_size;
        int idx;
 
-       if (phys + size < 8 * 1024 * 1024) 
+       if (phys + size < 8 * 1024 * 1024)
                return __va(phys);
 
        offset = phys & (PAGE_SIZE - 1);
@@ -132,7 +132,7 @@ char *__acpi_map_table(unsigned long phy
 #ifdef CONFIG_X86_LOCAL_APIC
 static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size)
 {
-       struct acpi_table_madt  *madt = NULL;
+       struct acpi_table_madt *madt = NULL;
 
        if (!phys_addr || !size)
                return -EINVAL;
@@ -147,18 +147,18 @@ static int __init acpi_parse_madt(unsign
                acpi_lapic_addr = (u64) madt->lapic_address;
 
                printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n",
-                       madt->lapic_address);
+                      madt->lapic_address);
        }
 
        acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
-       
+
        return 0;
 }
 
 static int __init
 acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
 {
-       struct acpi_table_lapic *processor = NULL;
+       struct acpi_table_lapic *processor = NULL;
 
        processor = (struct acpi_table_lapic *)header;
 
@@ -167,10 +167,17 @@ acpi_parse_lapic(acpi_table_entry_header
 
        acpi_table_print_madt_entry(header);
 
-       /* Register even disabled CPUs for cpu hotplug */
-
-       x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
-
+       /* Record local apic id only when enabled */
+       if (processor->flags.enabled)
+               x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
+
+       /*
+        * We need to register disabled CPU as well to permit
+        * counting disabled CPUs. This allows us to size
+        * cpus_possible_map more accurately, to permit
+        * to not preallocating memory for all NR_CPUS
+        * when we use CPU hotplug.
+        */
        mp_register_lapic(processor->id,        /* APIC ID */
                          processor->flags.enabled);    /* Enabled? */
 
@@ -224,7 +231,7 @@ acpi_parse_ioapic(acpi_table_entry_heade
 
        if (BAD_MADT_ENTRY(ioapic, end))
                return -EINVAL;
- 
+
        acpi_table_print_madt_entry(header);
 
        mp_register_ioapic(ioapic->id,
@@ -281,8 +288,8 @@ static unsigned long __init
 static unsigned long __init
 acpi_scan_rsdp(unsigned long start, unsigned long length)
 {
-       unsigned long           offset = 0;
-       unsigned long           sig_len = sizeof("RSD PTR ") - 1;
+       unsigned long offset = 0;
+       unsigned long sig_len = sizeof("RSD PTR ") - 1;
 
        /*
         * Scan all 16-byte boundaries of the physical memory region for the
@@ -302,7 +309,7 @@ static int __init acpi_parse_sbf(unsigne
        struct acpi_table_sbf *sb;
 
        if (!phys_addr || !size)
-       return -EINVAL;
+               return -EINVAL;
 
        sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size);
        if (!sb) {
@@ -310,11 +317,10 @@ static int __init acpi_parse_sbf(unsigne
                return -ENODEV;
        }
 
-       sbf_port = sb->sbf_cmos; /* Save CMOS port */
-
-       return 0;
-}
-
+       sbf_port = sb->sbf_cmos;        /* Save CMOS port */
+
+       return 0;
+}
 
 #ifdef CONFIG_HPET_TIMER
 
@@ -349,7 +355,7 @@ static int __init acpi_parse_hpet(unsign
 
                hpet_address = hpet_tbl->addr.addrl;
                printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
-                       hpet_tbl->id, hpet_address);
+                      hpet_tbl->id, hpet_address);
        }
 #endif /* X86 */
 
@@ -410,17 +416,16 @@ static int __init acpi_parse_fadt(unsign
        return 0;
 }
 
-
 unsigned long __init acpi_find_rsdp(void)
 {
-       unsigned long           rsdp_phys = 0;
+       unsigned long rsdp_phys = 0;
 
 #if 0
        if (efi_enabled) {
-               if (efi.acpi20)
-                       return __pa(efi.acpi20);
-               else if (efi.acpi)
-                       return __pa(efi.acpi);
+               if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
+                       return efi.acpi20;
+               else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
+                       return efi.acpi;
        }
 #endif
        /*
@@ -442,6 +447,9 @@ static int __init acpi_parse_madt_lapic_
 static int __init acpi_parse_madt_lapic_entries(void)
 {
        int count;
+
+       if (!cpu_has_apic)
+               return -ENODEV;
 
        /* 
         * Note that the LAPIC address is obtained from the MADT (32-bit value)
@@ -460,8 +468,8 @@ static int __init acpi_parse_madt_lapic_
        mp_register_lapic_address(acpi_lapic_addr);
 
        count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
-                                      MAX_APICS);
-       if (!count) { 
+                                     MAX_APICS);
+       if (!count) {
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return -ENODEV;
@@ -499,14 +507,17 @@ static int __init acpi_parse_madt_ioapic
         */
        if (acpi_disabled || acpi_noirq) {
                return -ENODEV;
-        }
-
-       /*
-        * if "noapic" boot option, don't look for IO-APICs
+       }
+
+       if (!cpu_has_apic)
+               return -ENODEV;
+
+       /*
+        * if "noapic" boot option, don't look for IO-APICs
         */
        if (skip_ioapic_setup) {
                printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
-                       "due to 'noapic' option.\n");
+                      "due to 'noapic' option.\n");
                return -ENODEV;
        }
 
@@ -852,7 +863,7 @@ int __init acpi_boot_table_init(void)
         * One exception: acpi=ht continues far enough to enumerate LAPICs
         */
        if (acpi_disabled && !acpi_ht)
-                return 1;
+               return 1;
 
        /* 
         * Initialize the ACPI boot-time table parser.
@@ -884,7 +895,6 @@ int __init acpi_boot_table_init(void)
        return 0;
 }
 
-
 int __init acpi_boot_init(void)
 {
        /*
@@ -892,7 +902,7 @@ int __init acpi_boot_init(void)
         * One exception: acpi=ht continues far enough to enumerate LAPICs
         */
        if (acpi_disabled && !acpi_ht)
-                return 1;
+               return 1;
 
        acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
 
@@ -910,4 +920,3 @@ int __init acpi_boot_init(void)
 
        return 0;
 }
-
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/apic.c       Sun Sep 24 13:10:13 2006 -0600
@@ -1,5 +1,5 @@
 /*
- *      based on linux-2.6.11/arch/i386/kernel/apic.c
+ *      based on linux-2.6.17.13/arch/i386/kernel/apic.c
  *
  *  Local APIC handling, local APIC timers
  *
@@ -50,6 +50,18 @@ int apic_verbosity;
 
 static void apic_pm_activate(void);
 
+int modern_apic(void)
+{
+    unsigned int lvr, version;
+    /* AMD systems use old APIC versions, so check the CPU */
+    if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+        boot_cpu_data.x86 >= 0xf)
+        return 1;
+    lvr = apic_read(APIC_LVR);
+    version = GET_APIC_VERSION(lvr);
+    return version >= 0x14;
+}
+
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
@@ -64,8 +76,10 @@ void ack_bad_irq(unsigned int irq)
      * holds up an irq slot - in excessive cases (when multiple
      * unexpected vectors occur) that might lock up the APIC
      * completely.
-     */
-    ack_APIC_irq();
+     * But only ack when the APIC is enabled -AK
+     */
+    if (cpu_has_apic)
+        ack_APIC_irq();
 }
 
 void __init apic_intr_init(void)
@@ -91,12 +105,21 @@ int using_apic_timer = 0;
 
 static int enabled_via_apicbase;
 
+void enable_NMI_through_LVT0 (void * dummy)
+{
+    unsigned int v, ver;
+
+    ver = apic_read(APIC_LVR);
+    ver = GET_APIC_VERSION(ver);
+    v = APIC_DM_NMI;                   /* unmask and set to NMI */
+    if (!APIC_INTEGRATED(ver))         /* 82489DX */
+        v |= APIC_LVT_LEVEL_TRIGGER;
+    apic_write_around(APIC_LVT0, v);
+}
+
 int get_physical_broadcast(void)
 {
-    unsigned int lvr, version;
-    lvr = apic_read(APIC_LVR);
-    version = GET_APIC_VERSION(lvr);
-    if (!APIC_INTEGRATED(version) || version >= 0x14)
+    if (modern_apic())
         return 0xff;
     else
         return 0xf;
@@ -323,9 +346,9 @@ int __init verify_local_APIC(void)
 
 void __init sync_Arb_IDs(void)
 {
-    /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */
-    unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
-    if (ver >= 0x14)    /* P4 or higher */
+    /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1
+       And not needed on AMD */
+    if (modern_apic())
         return;
     /*
      * Wait for idle.
@@ -389,6 +412,7 @@ void __devinit setup_local_APIC(void)
 void __devinit setup_local_APIC(void)
 {
     unsigned long oldvalue, value, ver, maxlvt;
+    int i, j;
 
     /* Pound the ESR really hard over the head with a big hammer - mbligh */
     if (esr_disable) {
@@ -424,6 +448,25 @@ void __devinit setup_local_APIC(void)
     value = apic_read(APIC_TASKPRI);
     value &= ~APIC_TPRI_MASK;
     apic_write_around(APIC_TASKPRI, value);
+
+    /*
+     * After a crash, we no longer service the interrupts and a pending
+     * interrupt from previous kernel might still have ISR bit set.
+     *
+     * Most probably by now CPU has serviced that pending interrupt and
+     * it might not have done the ack_APIC_irq() because it thought,
+     * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
+     * does not clear the ISR bit and cpu thinks it has already serivced
+     * the interrupt. Hence a vector might get locked. It was noticed
+     * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
+     */
+    for (i = APIC_ISR_NR - 1; i >= 0; i--) {
+        value = apic_read(APIC_ISR + i*0x10);
+        for (j = 31; j >= 0; j--) {
+            if (value & (1<<j))
+                ack_APIC_irq();
+        }
+    }
 
     /*
      * Now that we are all set up, enable the APIC
@@ -534,6 +577,29 @@ void __devinit setup_local_APIC(void)
     if (nmi_watchdog == NMI_LOCAL_APIC)
         setup_apic_nmi_watchdog();
     apic_pm_activate();
+}
+
+/*
+ * If Linux enabled the LAPIC against the BIOS default
+ * disable it down before re-entering the BIOS on shutdown.
+ * Otherwise the BIOS may get confused and not power-off.
+ * Additionally clear all LVT entries before disable_local_APIC
+ * for the case where Linux didn't enable the LAPIC.
+ */
+void lapic_shutdown(void)
+{
+    unsigned long flags;
+
+    if (!cpu_has_apic)
+        return;
+
+    local_irq_save(flags);
+    clear_local_APIC();
+
+    if (enabled_via_apicbase)
+        disable_local_APIC();
+
+    local_irq_restore(flags);
 }
 
 static void apic_pm_activate(void) { }
@@ -1086,6 +1152,7 @@ int __init APIC_init_uniprocessor (void)
     if (!cpu_has_apic && 
APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
         printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                boot_cpu_physical_apicid);
+        clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
         return -1;
     }
 
@@ -1093,6 +1160,14 @@ int __init APIC_init_uniprocessor (void)
 
     connect_bsp_APIC();
 
+    /*
+     * Hack: In case of kdump, after a crash, kernel might be booting
+     * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
+     * might be zero if read from MP tables. Get it from LAPIC.
+     */
+#ifdef CONFIG_CRASH_DUMP
+    boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+#endif
     phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
 
     setup_local_APIC();
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S        Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/boot/x86_64.S        Sun Sep 24 13:10:13 2006 -0600
@@ -9,6 +9,8 @@
                 
         .text
         .code32
+
+#define SYM_PHYS(sym) (sym - __PAGE_OFFSET)
 
 ENTRY(start)
 ENTRY(stext)
@@ -24,15 +26,14 @@ ENTRY(_stext)
         /* Checksum: must be the negated sum of the first two fields. */
         .long   -0x1BADB005
 
-        .org    0x010
-        .asciz "ERR: Not a 64-bit CPU!"
-        .org    0x028
-        .asciz "ERR: Not a Multiboot bootloader!"
+.Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
+.Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
+
 bad_cpu:
-        mov     $0x100010,%esi # Error message
+        mov     $(SYM_PHYS(.Lbad_cpu_msg)),%esi # Error message
         jmp     print_err
 not_multiboot:
-        mov     $0x100028,%esi # Error message
+        mov     $(SYM_PHYS(.Lbad_ldr_msg)),%esi # Error message
 print_err:
         mov     $0xB8000,%edi  # VGA framebuffer
 1:      mov     (%esi),%bl
@@ -55,7 +56,7 @@ __start:
         cli
 
         /* Set up a few descriptors: on entry only CS is guaranteed good. */
-        lgdt    %cs:0x100306        # nopaging_gdt_descr
+        lgdt    %cs:SYM_PHYS(nopaging_gdt_descr)
         mov     $(__HYPERVISOR_DS32),%ecx
         mov     %ecx,%ds
         mov     %ecx,%es
@@ -68,7 +69,7 @@ __start:
         jne     not_multiboot
 
         /* Save the Multiboot info structure for later use. */
-        mov     %ebx,0x100300       # multiboot_ptr
+        mov     %ebx,SYM_PHYS(multiboot_ptr)
 
         /* We begin by interrogating the CPU for the presence of long mode. */
         mov     $0x80000000,%eax
@@ -79,7 +80,7 @@ __start:
         cpuid
         bt      $29,%edx            # Long mode feature?
         jnc     bad_cpu
-        mov     %edx,0x100310       # cpuid_ext_features
+        mov     %edx,SYM_PHYS(cpuid_ext_features)
 skip_boot_checks:
 
         /* Set up FPU. */
@@ -90,7 +91,7 @@ skip_boot_checks:
         mov     %ecx,%cr4
 
         /* Load pagetable base register. */
-        mov     $0x102000,%eax   /* idle_pg_table */
+        mov     $SYM_PHYS(idle_pg_table),%eax
         mov     %eax,%cr3
 
         /* Set up EFER (Extended Feature Enable Register). */
@@ -98,7 +99,7 @@ skip_boot_checks:
         rdmsr
         btsl    $_EFER_LME,%eax /* Long Mode      */
         btsl    $_EFER_SCE,%eax /* SYSCALL/SYSRET */
-        mov     0x100310,%edi
+        mov     SYM_PHYS(cpuid_ext_features),%edi
         btl     $20,%edi        /* CPUID 0x80000001, EDX[20] */
         jnc     1f
         btsl    $_EFER_NX,%eax  /* No-Execute     */
@@ -109,11 +110,10 @@ 1:      wrmsr
         jmp     1f
 
 1:      /* Now in compatibility mode. Long-jump into 64-bit mode. */
-        ljmp    $(__HYPERVISOR_CS64),$0x100200
+        ljmp    $(__HYPERVISOR_CS64),$SYM_PHYS(start64)
         
         .code64
-        .org    0x0200
-
+start64:
         /* Install relocated selectors (FS/GS unused). */
         lgdt    gdt_descr(%rip)
 
@@ -195,18 +195,16 @@ 1:      jmp     1b
 .globl idt
 .globl gdt        
 
-        .org    0x300
-        .code32
-
-multiboot_ptr:        /* 0x300 */
+        .align 8, 0xCC
+multiboot_ptr:
         .long   0
 
         .word   0
-nopaging_gdt_descr:   /* 0x306 */
+nopaging_gdt_descr:
         .word   LAST_RESERVED_GDT_BYTE
         .quad   gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
 
-cpuid_ext_features:   /* 0x310 */
+cpuid_ext_features:
         .long   0
         
         .word   0
@@ -227,7 +225,7 @@ high_start:
 high_start:
         .quad   __high_start
 
-        .org    0x1000
+        .align PAGE_SIZE, 0
 ENTRY(gdt_table)
         .quad 0x0000000000000000     /* unused */
         .quad 0x00cf9a000000ffff     /* 0xe008 ring 0 code, compatibility */
@@ -240,7 +238,7 @@ ENTRY(gdt_table)
         .fill 4*NR_CPUS,8,0          /* space for TSS and LDT per CPU     */
 
 /* Initial PML4 -- level-4 page table. */
-        .org 0x2000
+        .align PAGE_SIZE, 0
 ENTRY(idle_pg_table)
 ENTRY(idle_pg_table_4)
         .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0]
@@ -248,12 +246,12 @@ ENTRY(idle_pg_table_4)
         .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262]
 
 /* Initial PDP -- level-3 page table. */
-        .org 0x3000
+        .align PAGE_SIZE, 0
 ENTRY(idle_pg_table_l3)
         .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
 
 /* Initial PDE -- level-2 page table. Maps first 1GB physical memory. */
-        .org 0x4000
+        .align PAGE_SIZE, 0
 ENTRY(idle_pg_table_l2)
         .macro identmap from=0, count=512
         .if \count-1
@@ -265,8 +263,7 @@ ENTRY(idle_pg_table_l2)
         .endm
         identmap
 
-        .org 0x4000 + PAGE_SIZE
-        .code64
+        .align PAGE_SIZE, 0
 
 .section ".bss.stack_aligned","w"
 ENTRY(cpu0_stack)
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/domain_build.c       Sun Sep 24 13:10:13 2006 -0600
@@ -74,10 +74,11 @@ string_param("dom0_ioports_disable", opt
 #define L3_PROT (_PAGE_PRESENT)
 #elif defined(__x86_64__)
 /* Allow ring-3 access in long mode as guest cannot use ring 1. */
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+#define BASE_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
+#define L1_PROT (BASE_PROT|_PAGE_GUEST_KERNEL)
+#define L2_PROT (BASE_PROT|_PAGE_DIRTY)
+#define L3_PROT (BASE_PROT|_PAGE_DIRTY)
+#define L4_PROT (BASE_PROT|_PAGE_DIRTY)
 #endif
 
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
@@ -510,15 +511,13 @@ int construct_dom0(struct domain *d,
         case 1 ... 4:
             page->u.inuse.type_info &= ~PGT_type_mask;
             page->u.inuse.type_info |= PGT_l2_page_table;
-            page->u.inuse.type_info |=
-                (count-1) << PGT_va_shift;
+            if ( count == 4 )
+                page->u.inuse.type_info |= PGT_pae_xen_l2;
             get_page(page, d); /* an extra ref because of readable mapping */
             break;
         default:
             page->u.inuse.type_info &= ~PGT_type_mask;
             page->u.inuse.type_info |= PGT_l1_page_table;
-            page->u.inuse.type_info |= 
-                ((dsi.v_start>>L2_PAGETABLE_SHIFT)+(count-5))<<PGT_va_shift;
             get_page(page, d); /* an extra ref because of readable mapping */
             break;
         }
@@ -544,8 +543,6 @@ int construct_dom0(struct domain *d,
         {
             page->u.inuse.type_info &= ~PGT_type_mask;
             page->u.inuse.type_info |= PGT_l1_page_table;
-            page->u.inuse.type_info |= 
-                ((dsi.v_start>>L2_PAGETABLE_SHIFT)+(count-1))<<PGT_va_shift;
 
             /*
              * No longer writable: decrement the type_count.
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/domctl.c     Sun Sep 24 13:10:13 2006 -0600
@@ -22,6 +22,7 @@
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/processor.h>
+#include <public/hvm/e820.h>
 
 long arch_do_domctl(
     struct xen_domctl *domctl,
@@ -213,7 +214,7 @@ long arch_do_domctl(
         int i;
         struct domain *d = find_domain_by_id(domctl->domain);
         unsigned long max_pfns = domctl->u.getmemlist.max_pfns;
-        unsigned long mfn;
+        unsigned long mfn, gmfn;
         struct list_head *list_ent;
 
         ret = -EINVAL;
@@ -222,19 +223,48 @@ long arch_do_domctl(
             ret = 0;
 
             spin_lock(&d->page_alloc_lock);
-            list_ent = d->page_list.next;
-            for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
-            {
-                mfn = page_to_mfn(list_entry(
-                    list_ent, struct page_info, list));
-                if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
-                                          i, &mfn, 1) )
-                {
-                    ret = -EFAULT;
-                    break;
-                }
-                list_ent = mfn_to_page(mfn)->list.next;
-            }
+
+            if ( hvm_guest(d->vcpu[0]) && shadow_mode_translate(d) )
+            {
+                /* HVM domain: scan P2M to get guaranteed physmap order. */
+                for ( i = 0, gmfn = 0;
+                      (i < max_pfns) && (i < d->tot_pages); 
+                      i++, gmfn++ )
+                {
+                    if ( unlikely(i == (HVM_BELOW_4G_MMIO_START>>PAGE_SHIFT)) )
+                    {
+                        /* skip MMIO range */
+                        gmfn += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
+                    }
+                    mfn = gmfn_to_mfn(d, gmfn);
+                    if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
+                                              i, &mfn, 1) )
+                    {
+                        ret = -EFAULT;
+                        break;
+                    }
+                }
+            }
+            else 
+            {        
+                /* Other guests: return in order of ownership list. */
+                list_ent = d->page_list.next;
+                for ( i = 0;
+                      (i < max_pfns) && (list_ent != &d->page_list);
+                      i++ )
+                {
+                    mfn = page_to_mfn(list_entry(
+                        list_ent, struct page_info, list));
+                    if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
+                                              i, &mfn, 1) )
+                    {
+                        ret = -EFAULT;
+                        break;
+                    }
+                    list_ent = mfn_to_page(mfn)->list.next;
+                }
+            }
+            
             spin_unlock(&d->page_alloc_lock);
 
             domctl->u.getmemlist.num_pfns = i;
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/flushtlb.c
--- a/xen/arch/x86/flushtlb.c   Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/flushtlb.c   Sun Sep 24 13:10:13 2006 -0600
@@ -4,13 +4,14 @@
  * TLB flushes are timestamped using a global virtual 'clock' which ticks
  * on any TLB flush on any processor.
  * 
- * Copyright (c) 2003-2004, K A Fraser
+ * Copyright (c) 2003-2006, K A Fraser
  */
 
 #include <xen/config.h>
 #include <xen/sched.h>
 #include <xen/softirq.h>
 #include <asm/flushtlb.h>
+#include <asm/page.h>
 
 /* Debug builds: Wrap frequently to stress-test the wrap logic. */
 #ifdef NDEBUG
@@ -22,21 +23,17 @@ u32 tlbflush_clock = 1U;
 u32 tlbflush_clock = 1U;
 DEFINE_PER_CPU(u32, tlbflush_time);
 
-void write_cr3(unsigned long cr3)
+/*
+ * pre_flush(): Increment the virtual TLB-flush clock. Returns new clock value.
+ * 
+ * This must happen *before* we flush the TLB. If we do it after, we race other
+ * CPUs invalidating PTEs. For example, a page invalidated after the flush
+ * might get the old timestamp, but this CPU can speculatively fetch the
+ * mapping into its TLB after the flush but before inc'ing the clock.
+ */
+static u32 pre_flush(void)
 {
     u32 t, t1, t2;
-    unsigned long flags;
-
-    /* This non-reentrant function is sometimes called in interrupt context. */
-    local_irq_save(flags);
-
-    /*
-     * STEP 1. Increment the virtual clock *before* flushing the TLB.
-     *         If we do it after, we race other CPUs invalidating PTEs.
-     *         (e.g., a page invalidated after the flush might get the old 
-     *          timestamp, but this CPU can speculatively fetch the mapping
-     *          into its TLB after the flush but before inc'ing the clock).
-     */
 
     t = tlbflush_clock;
     do {
@@ -52,26 +49,68 @@ void write_cr3(unsigned long cr3)
     if ( unlikely(t2 == 0) )
         raise_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ);
 
-    /*
-     * STEP 2. Update %CR3, thereby flushing the TLB.
-     */
+ skip_clocktick:
+    return t2;
+}
 
- skip_clocktick:
+/*
+ * post_flush(): Update this CPU's timestamp with specified clock value.
+ * 
+ * Note that this happens *after* flushing the TLB, as otherwise we can race a 
+ * NEED_FLUSH() test on another CPU. (e.g., other CPU sees the updated CPU 
+ * stamp and so does not force a synchronous TLB flush, but the flush in this
+ * function hasn't yet occurred and so the TLB might be stale). The ordering 
+ * would only actually matter if this function were interruptible, and 
+ * something that abuses the stale mapping could exist in an interrupt 
+ * handler. In fact neither of these is the case, so really we are being ultra 
+ * paranoid.
+ */
+static void post_flush(u32 t)
+{
+    this_cpu(tlbflush_time) = t;
+}
+
+void write_cr3(unsigned long cr3)
+{
+    unsigned long flags;
+    u32 t;
+
+    /* This non-reentrant function is sometimes called in interrupt context. */
+    local_irq_save(flags);
+
+    t = pre_flush();
+
+#ifdef USER_MAPPINGS_ARE_GLOBAL
+    __pge_off();
     __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (cr3) : "memory" );
+    __pge_on();
+#else
+    __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (cr3) : "memory" );
+#endif
 
-    /*
-     * STEP 3. Update this CPU's timestamp. Note that this happens *after*
-     *         flushing the TLB, as otherwise we can race a NEED_FLUSH() test
-     *         on another CPU. (e.g., other CPU sees the updated CPU stamp and
-     *         so does not force a synchronous TLB flush, but the flush in this
-     *         function hasn't yet occurred and so the TLB might be stale).
-     *         The ordering would only actually matter if this function were
-     *         interruptible, and something that abuses the stale mapping could
-     *         exist in an interrupt handler. In fact neither of these is the
-     *         case, so really we are being ultra paranoid.
-     */
-
-    this_cpu(tlbflush_time) = t2;
+    post_flush(t);
 
     local_irq_restore(flags);
 }
+
+void local_flush_tlb(void)
+{
+    unsigned long flags;
+    u32 t;
+
+    /* This non-reentrant function is sometimes called in interrupt context. */
+    local_irq_save(flags);
+
+    t = pre_flush();
+
+#ifdef USER_MAPPINGS_ARE_GLOBAL
+    __pge_off();
+    __pge_on();
+#else
+    __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (read_cr3()) : "memory" );
+#endif
+
+    post_flush(t);
+
+    local_irq_restore(flags);
+}
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Sun Sep 24 13:10:13 2006 -0600
@@ -337,7 +337,6 @@ int cpu_get_interrupt(struct vcpu *v, in
     return -1;
 }
 
-#include <asm/hvm/vmx/vmx.h>
 void hvm_hlt(unsigned long rflags)
 {
     struct vcpu *v = current;
diff -r da942e577e5e -r 432f978d1cd1 xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c  Thu Sep 21 15:35:45 2006 -0600
+++ b/xen/arch/x86/hvm/i8259.c  Sun Sep 24 13:10:13 2006 -0600
@@ -35,12 +35,11 @@
 #include <asm/current.h>
 
 /* set irq level. If an edge is detected, then the IRR is set to 1 */
-/* Caller must hold vpic lock */
 static inline void pic_set_irq1(PicState *s, int irq, int level)
 {
     int mask;
 
-    BUG_ON(!spin_is_locked(&s->pics_state->lock));
+    ASSERT(spin_is_locked(&s->pics_state->lock));
 
     mask = 1 << irq;
     if (s->elcr & mask) {
@@ -55,9 +54,8 @@ static inline void pic_set_irq1(PicState
     } else {
         /* edge triggered */
         if (level) {
-            if ((s->last_irr & mask) == 0) {
+            if ((s->last_irr & mask) == 0)
                 s->irr |= mask;
-            }
             s->last_irr |= mask;
         } else {
             s->last_irr &= ~mask;
@@ -67,12 +65,11 @@ static inline void pic_set_irq1(PicState
 
 /* return the highest priority found in mask (highest = smallest
    number). Return 8 if no irq */
-/* Caller must hold vpic lock */
 static inline int get_priority(PicState *s, int mask)
 {
     int priority;
 
-    BUG_ON(!spin_is_locked(&s->pics_state->lock));
+    ASSERT(spin_is_locked(&s->pics_state->lock));
 
     if (mask == 0)
         return 8;
@@ -83,12 +80,11 @@ static inline int get_priority(PicState 
 }
 
 /* return the pic wanted interrupt. return -1 if none */
-/* Caller must hold vpic lock */
 static int pic_get_irq(PicState *s)
 {
     int mask, cur_priority, priority;
 
-    BUG_ON(!spin_is_locked(&s->pics_state->lock));
+    ASSERT(spin_is_locked(&s->pics_state->lock));
 
     mask = s->irr & ~s->imr;
     priority = get_priority(s, mask);
@@ -112,12 +108,11 @@ static int pic_get_irq(PicState *s)
 /* raise irq to CPU if necessary. must be called every time the active
    irq may change */
 /* XXX: should not export it, but it is needed for an APIC kludge */
-/* Caller must hold vpic lock */
 void pic_update_irq(struct hvm_virpic *s)
 {
     int irq2, irq;
 
-    BUG_ON(!spin_is_locked(&s->lock));
+    ASSERT(spin_is_locked(&s->lock));
 
     /* first look at slave pic */
     irq2 = pic_get_irq(&s->pics[1]);
@@ -179,10 +174,9 @@ void pic_set_irq(struct hvm_virpic *isa_
 }
 
 /* acknowledge interrupt 'irq' */
-/* Caller must hold vpic lock */
 static inline void pic_intack(PicState *s, int irq)
 {
-    BUG_ON(!spin_is_locked(&s->pics_state->lock));
+    ASSERT(spin_is_locked(&s->pics_state->lock));
 
     if (s->auto_eoi) {
         if (s->rotate_on_auto_eoi)
@@ -219,7 +213,6 @@ int pic_read_irq(struct hvm_virpic *s)
         }
     } else {
         /* spurious IRQ on host controller */
-        printk("spurious IRQ irq got=%d\n",irq);
         irq = 7;
         intno = s->pics[0].irq_base + irq;
     }
@@ -229,12 +222,11 @@ int pic_read_irq(struct hvm_virpic *s)
     return intno;
 }
 
-/* Caller must hold vpic lock */
 static void update_shared_irr(struct hvm_virpic *s, PicState *c)
 {
     uint8_t *pl, *pe;
 
-    BUG_ON(!spin_is_locked(&s->lock));
+    ASSERT(spin_is_locked(&s->lock));
 
     get_sp(current->domain)->sp_global.pic_elcr = 
         s->pics[0].elcr | ((u16)s->pics[1].elcr << 8);
@@ -250,12 +242,11 @@ static void update_shared_irr(struct hvm
     }
 }
 
-/* Caller must hold vpic lock */
 static void pic_reset(void *opaque)
 {
     PicState *s = opaque;
 
-    BUG_ON(!spin_is_locked(&s->pics_state->lock));
+    ASSERT(spin_is_locked(&s->pics_state->lock));

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


 


Rackspace

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