[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 ebed727182630279e605f32f35a5364924cbd433
# Parent  11b718eb22c996868bed5b18dcc08081ad27d0be
# Parent  d19deb173503962cc42c235cdeda84d3b4a6a52c
merge with xen-unstable.hg
---
 tools/firmware/acpi/Makefile                                                   
       |   68 
 tools/firmware/acpi/README                                                     
       |   22 
 tools/firmware/acpi/acpi2_0.h                                                  
       |  331 
 tools/firmware/acpi/acpi_build.c                                               
       |  232 
 tools/firmware/acpi/acpi_dsdt.asl                                              
       |  521 
 tools/firmware/acpi/acpi_dsdt.c                                                
       |  300 
 tools/firmware/acpi/acpi_facs.c                                                
       |   72 
 tools/firmware/acpi/acpi_facs.h                                                
       |   32 
 tools/firmware/acpi/acpi_fadt.c                                                
       |  193 
 tools/firmware/acpi/acpi_fadt.h                                                
       |  166 
 tools/firmware/acpi/acpi_gen.c                                                 
       |   53 
 tools/firmware/acpi/acpi_madt.c                                                
       |   68 
 tools/firmware/acpi/acpi_madt.h                                                
       |   44 
 tools/firmware/acpi/acpi_rsdt.c                                                
       |   68 
 tools/pygrub/src/fsys/__init__.py                                              
       |   64 
 tools/pygrub/src/fsys/ext2/__init__.py                                         
       |   38 
 tools/pygrub/src/fsys/ext2/ext2module.c                                        
       |  387 
 tools/pygrub/src/fsys/ext2/test.py                                             
       |   15 
 tools/pygrub/src/fsys/reiser/__init__.py                                       
       |   40 
 tools/pygrub/src/fsys/reiser/reisermodule.c                                    
       |  345 
 .hgignore                                                                      
       |    3 
 buildconfigs/linux-defconfig_xen0_ia64                                         
       |    2 
 buildconfigs/linux-defconfig_xen_ia64                                          
       |    2 
 config/SunOS.mk                                                                
       |    2 
 docs/src/user.tex                                                              
       |   26 
 docs/xen-api/Makefile                                                          
       |   23 
 docs/xen-api/coversheet.tex                                                    
       |   50 
 docs/xen-api/fdl.tex                                                           
       |  488 
 docs/xen-api/presentation.tex                                                  
       |  149 
 docs/xen-api/todo.tex                                                          
       |  140 
 docs/xen-api/vm-lifecycle.tex                                                  
       |   24 
 docs/xen-api/vm_lifecycle.dot                                                  
       |   15 
 docs/xen-api/wire-protocol.tex                                                 
       |  287 
 docs/xen-api/xen.eps                                                           
       |   49 
 docs/xen-api/xenapi-coversheet.tex                                             
       |   40 
 docs/xen-api/xenapi-datamodel-graph.dot                                        
       |   17 
 docs/xen-api/xenapi-datamodel.tex                                              
       | 9648 ++++++++++
 docs/xen-api/xenapi.tex                                                        
       |   56 
 linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c                               
       |    2 
 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c                                 
       |    4 
 linux-2.6-xen-sparse/arch/i386/mm/init-xen.c                                   
       |    4 
 linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c                                   
       |    5 
 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c                                 
       |    4 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c                                
       |    1 
 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c                             
       |   42 
 linux-2.6-xen-sparse/drivers/xen/blkback/common.h                              
       |    5 
 linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c                                 
       |    3 
 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c                              
       |   21 
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c                           
       |   30 
 linux-2.6-xen-sparse/drivers/xen/blkfront/block.h                              
       |    2 
 linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c                                
       |   75 
 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c                               
       |  215 
 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c                               
       |    6 
 linux-2.6-xen-sparse/drivers/xen/core/Makefile                                 
       |    2 
 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c                         
       |  185 
 linux-2.6-xen-sparse/drivers/xen/core/reboot.c                                 
       |  212 
 linux-2.6-xen-sparse/drivers/xen/netback/interface.c                           
       |    3 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c                             
       |    9 
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c                              
       |   14 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c                           
       |   48 
 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c                             
       |   18 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c                         
       |    7 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h                    
       |    1 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h                 
       |   10 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h                
       |    8 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h               
       |   15 
 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h                              
       |    3 
 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h                             
       |   16 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h                  
       |    1 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h               
       |   10 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h             
       |   17 
 linux-2.6-xen-sparse/include/xen/gnttab.h                                      
       |    5 
 patches/linux-2.6.16.29/series                                                 
       |    1 
 patches/linux-2.6.16.29/xenoprof-generic.patch                                 
       |   53 
 tools/Makefile                                                                 
       |    1 
 tools/blktap/drivers/blktapctrl.c                                              
       |    4 
 tools/blktap/drivers/tapdisk.c                                                 
       |    5 
 tools/blktap/drivers/tapdisk.h                                                 
       |    1 
 tools/blktap/lib/blktaplib.h                                                   
       |    7 
 tools/console/Makefile                                                         
       |    2 
 tools/examples/blktap                                                          
       |   18 
 tools/examples/block                                                           
       |   30 
 tools/examples/external-device-migrate                                         
       |   56 
 tools/examples/vif-bridge                                                      
       |    2 
 tools/examples/vif-nat                                                         
       |    4 
 tools/examples/vif-route                                                       
       |    2 
 tools/examples/xend-config.sxp                                                 
       |    2 
 tools/examples/xmexample.hvm                                                   
       |    3 
 tools/firmware/Makefile                                                        
       |    1 
 tools/firmware/hvmloader/Makefile                                              
       |   11 
 tools/firmware/hvmloader/acpi/Makefile                                         
       |   63 
 tools/firmware/hvmloader/acpi/README                                           
       |   24 
 tools/firmware/hvmloader/acpi/acpi2_0.h                                        
       |  324 
 tools/firmware/hvmloader/acpi/build.c                                          
       |  241 
 tools/firmware/hvmloader/acpi/dsdt.asl                                         
       |  521 
 tools/firmware/hvmloader/acpi/dsdt.c                                           
       |  300 
 tools/firmware/hvmloader/acpi/gen.c                                            
       |   53 
 tools/firmware/hvmloader/acpi/static_tables.c                                  
       |  184 
 tools/firmware/hvmloader/acpi_madt.c                                           
       |  176 
 tools/firmware/hvmloader/acpi_ssdt_tpm.asl                                     
       |   29 
 tools/firmware/hvmloader/acpi_ssdt_tpm.h                                       
       |   25 
 tools/firmware/hvmloader/acpi_utils.c                                          
       |  207 
 tools/firmware/hvmloader/acpi_utils.h                                          
       |   36 
 tools/firmware/hvmloader/hvmloader.c                                           
       |   16 
 tools/firmware/hvmloader/util.c                                                
       |    5 
 tools/firmware/vmxassist/setup.c                                               
       |    3 
 tools/firmware/vmxassist/vm86.c                                                
       |   87 
 tools/ioemu/Makefile.target                                                    
       |    1 
 tools/ioemu/hw/ne2000.c                                                        
       |   35 
 tools/ioemu/hw/pc.c                                                            
       |    3 
 tools/ioemu/hw/serial.c                                                        
       |   44 
 tools/ioemu/hw/tpm_tis.c                                                       
       | 1114 +
 tools/ioemu/keymaps/ja                                                         
       |    3 
 tools/ioemu/target-i386-dm/cpu.h                                               
       |    2 
 tools/ioemu/target-i386-dm/exec-dm.c                                           
       |   50 
 tools/ioemu/target-i386-dm/helper2.c                                           
       |  131 
 tools/ioemu/target-i386-dm/i8259-dm.c                                          
       |   42 
 tools/ioemu/target-i386-dm/qemu-dm.debug                                       
       |    7 
 tools/ioemu/vl.c                                                               
       |   25 
 tools/ioemu/vl.h                                                               
       |   23 
 tools/ioemu/vnc_keysym.h                                                       
       |   10 
 tools/ioemu/xenstore.c                                                         
       |  137 
 tools/libfsimage/Makefile                                                      
       |   13 
 tools/libfsimage/Rules.mk                                                      
       |   32 
 tools/libfsimage/check-libext2fs                                               
       |   21 
 tools/libfsimage/common/Makefile                                               
       |   46 
 tools/libfsimage/common/fsimage.c                                              
       |  142 
 tools/libfsimage/common/fsimage.h                                              
       |   52 
 tools/libfsimage/common/fsimage_grub.c                                         
       |  276 
 tools/libfsimage/common/fsimage_grub.h                                         
       |   92 
 tools/libfsimage/common/fsimage_plugin.c                                       
       |  214 
 tools/libfsimage/common/fsimage_plugin.h                                       
       |   65 
 tools/libfsimage/common/fsimage_priv.h                                         
       |   62 
 tools/libfsimage/common/mapfile-GNU                                            
       |   37 
 tools/libfsimage/common/mapfile-SunOS                                          
       |   35 
 tools/libfsimage/ext2fs-lib/Makefile                                           
       |   15 
 tools/libfsimage/ext2fs-lib/ext2fs-lib.c                                       
       |  172 
 tools/libfsimage/ext2fs/Makefile                                               
       |   13 
 tools/libfsimage/ext2fs/fsys_ext2fs.c                                          
       |  804 
 tools/libfsimage/reiserfs/Makefile                                             
       |   13 
 tools/libfsimage/reiserfs/fsys_reiserfs.c                                      
       | 1254 +
 tools/libfsimage/ufs/Makefile                                                  
       |   13 
 tools/libfsimage/ufs/fsys_ufs.c                                                
       |  276 
 tools/libfsimage/ufs/ufs.h                                                     
       |  228 
 tools/libxc/ia64/xc_ia64_hvm_build.c                                           
       |    2 
 tools/libxc/xc_core.c                                                          
       |    2 
 tools/libxc/xc_domain.c                                                        
       |   28 
 tools/libxc/xc_hvm_build.c                                                     
       |  297 
 tools/libxc/xc_linux_build.c                                                   
       |  195 
 tools/libxc/xc_linux_save.c                                                    
       |   24 
 tools/libxc/xc_misc.c                                                          
       |   28 
 tools/libxc/xc_private.c                                                       
       |   22 
 tools/libxc/xc_private.h                                                       
       |    5 
 tools/libxc/xc_ptrace.c                                                        
       |   29 
 tools/libxc/xc_ptrace_core.c                                                   
       |   24 
 tools/libxc/xenctrl.h                                                          
       |   31 
 tools/libxc/xenguest.h                                                         
       |   34 
 tools/libxc/xg_private.c                                                       
       |   66 
 tools/libxc/xg_private.h                                                       
       |    2 
 tools/libxen/COPYING                                                           
       |  510 
 tools/libxen/Makefile                                                          
       |   37 
 tools/libxen/README                                                            
       |   54 
 tools/libxen/include/xen_boot_type.h                                           
       |   87 
 tools/libxen/include/xen_boot_type_internal.h                                  
       |   37 
 tools/libxen/include/xen_common.h                                              
       |  145 
 tools/libxen/include/xen_cpu_feature.h                                         
       |  387 
 tools/libxen/include/xen_cpu_feature_internal.h                                
       |   37 
 tools/libxen/include/xen_driver_type.h                                         
       |   77 
 tools/libxen/include/xen_driver_type_internal.h                                
       |   37 
 tools/libxen/include/xen_host.h                                                
       |  292 
 tools/libxen/include/xen_host_cpu.h                                            
       |  239 
 tools/libxen/include/xen_host_cpu_decl.h                                       
       |   30 
 tools/libxen/include/xen_host_decl.h                                           
       |   30 
 tools/libxen/include/xen_int_float_map.h                                       
       |   53 
 tools/libxen/include/xen_internal.h                                            
       |  193 
 tools/libxen/include/xen_network.h                                             
       |  273 
 tools/libxen/include/xen_network_decl.h                                        
       |   30 
 tools/libxen/include/xen_on_crash_behaviour.h                                  
       |   97 
 tools/libxen/include/xen_on_crash_behaviour_internal.h                         
       |   38 
 tools/libxen/include/xen_on_normal_exit.h                                      
       |   77 
 tools/libxen/include/xen_on_normal_exit_internal.h                             
       |   37 
 tools/libxen/include/xen_pif.h                                                 
       |  290 
 tools/libxen/include/xen_pif_decl.h                                            
       |   30 
 tools/libxen/include/xen_sr.h                                                  
       |  282 
 tools/libxen/include/xen_sr_decl.h                                             
       |   30 
 tools/libxen/include/xen_string_string_map.h                                   
       |   53 
 tools/libxen/include/xen_user.h                                                
       |  204 
 tools/libxen/include/xen_user_decl.h                                           
       |   30 
 tools/libxen/include/xen_vbd.h                                                 
       |  285 
 tools/libxen/include/xen_vbd_decl.h                                            
       |   30 
 tools/libxen/include/xen_vbd_mode.h                                            
       |   77 
 tools/libxen/include/xen_vbd_mode_internal.h                                   
       |   37 
 tools/libxen/include/xen_vdi.h                                                 
       |  344 
 tools/libxen/include/xen_vdi_decl.h                                            
       |   30 
 tools/libxen/include/xen_vdi_type.h                                            
       |   82 
 tools/libxen/include/xen_vdi_type_internal.h                                   
       |   37 
 tools/libxen/include/xen_vif.h                                                 
       |  305 
 tools/libxen/include/xen_vif_decl.h                                            
       |   30 
 tools/libxen/include/xen_vm.h                                                  
       |  819 
 tools/libxen/include/xen_vm_decl.h                                             
       |   30 
 tools/libxen/include/xen_vm_power_state.h                                      
       |   97 
 tools/libxen/include/xen_vm_power_state_internal.h                             
       |   37 
 tools/libxen/include/xen_vtpm.h                                                
       |  216 
 tools/libxen/include/xen_vtpm_decl.h                                           
       |   31 
 tools/libxen/src/xen_boot_type.c                                               
       |   83 
 tools/libxen/src/xen_common.c                                                  
       | 1363 +
 tools/libxen/src/xen_cpu_feature.c                                             
       |  143 
 tools/libxen/src/xen_driver_type.c                                             
       |   81 
 tools/libxen/src/xen_host.c                                                    
       |  390 
 tools/libxen/src/xen_host_cpu.c                                                
       |  287 
 tools/libxen/src/xen_int_float_map.c                                           
       |   37 
 tools/libxen/src/xen_network.c                                                 
       |  364 
 tools/libxen/src/xen_on_crash_behaviour.c                                      
       |   85 
 tools/libxen/src/xen_on_normal_exit.c                                          
       |   81 
 tools/libxen/src/xen_pif.c                                                     
       |  403 
 tools/libxen/src/xen_sr.c                                                      
       |  388 
 tools/libxen/src/xen_string_string_map.c                                       
       |   49 
 tools/libxen/src/xen_user.c                                                    
       |  201 
 tools/libxen/src/xen_vbd.c                                                     
       |  387 
 tools/libxen/src/xen_vbd_mode.c                                                
       |   81 
 tools/libxen/src/xen_vdi.c                                                     
       |  533 
 tools/libxen/src/xen_vdi_type.c                                                
       |   82 
 tools/libxen/src/xen_vif.c                                                     
       |  440 
 tools/libxen/src/xen_vm.c                                                      
       | 1596 +
 tools/libxen/src/xen_vm_power_state.c                                          
       |   85 
 tools/libxen/src/xen_vtpm.c                                                    
       |  227 
 tools/libxen/test/test_bindings.c                                              
       |  424 
 tools/pygrub/setup.py                                                          
       |   43 
 tools/pygrub/src/fsimage/fsimage.c                                             
       |  299 
 tools/pygrub/src/pygrub                                                        
       |   35 
 tools/python/README.XendConfig                                                 
       |  159 
 tools/python/README.sxpcfg                                                     
       |  116 
 tools/python/scripts/README                                                    
       |   49 
 tools/python/scripts/README.lifecycle                                          
       |  136 
 tools/python/scripts/xapi.domcfg.py                                            
       |   37 
 tools/python/scripts/xapi.py                                                   
       |  537 
 tools/python/scripts/xapi.vbdcfg.py                                            
       |   12 
 tools/python/scripts/xapi.vdicfg.py                                            
       |    7 
 tools/python/scripts/xapi.vifcfg.py                                            
       |   10 
 tools/python/scripts/xapi.vtpmcfg.py                                           
       |    3 
 tools/python/setup.py                                                          
       |    3 
 tools/python/xen/lowlevel/xc/xc.c                                              
       |   90 
 tools/python/xen/util/blkif.py                                                 
       |   14 
 tools/python/xen/util/xmlrpclib2.py                                            
       |   36 
 tools/python/xen/xend/Args.py                                                  
       |    2 
 tools/python/xen/xend/PrettyPrint.py                                           
       |    2 
 tools/python/xen/xend/XendAPI.py                                               
       | 1531 +
 tools/python/xen/xend/XendAPIConstants.py                                      
       |   75 
 tools/python/xen/xend/XendAuthSessions.py                                      
       |  137 
 tools/python/xen/xend/XendBootloader.py                                        
       |    6 
 tools/python/xen/xend/XendCheckpoint.py                                        
       |   29 
 tools/python/xen/xend/XendConfig.py                                            
       |  872 
 tools/python/xen/xend/XendConstants.py                                         
       |   96 
 tools/python/xen/xend/XendDevices.py                                           
       |   68 
 tools/python/xen/xend/XendDomain.py                                            
       | 1313 +
 tools/python/xen/xend/XendDomainInfo.py                                        
       | 2490 +-
 tools/python/xen/xend/XendError.py                                             
       |   16 
 tools/python/xen/xend/XendNode.py                                              
       |  131 
 tools/python/xen/xend/XendProtocol.py                                          
       |    2 
 tools/python/xen/xend/XendRoot.py                                              
       |   28 
 tools/python/xen/xend/XendStorageRepository.py                                 
       |  381 
 tools/python/xen/xend/XendVDI.py                                               
       |  155 
 tools/python/xen/xend/image.py                                                 
       |   84 
 tools/python/xen/xend/server/DevController.py                                  
       |   79 
 tools/python/xen/xend/server/SrvDaemon.py                                      
       |   10 
 tools/python/xen/xend/server/SrvDomainDir.py                                   
       |    2 
 tools/python/xen/xend/server/SrvServer.py                                      
       |   30 
 tools/python/xen/xend/server/XMLRPCServer.py                                   
       |  103 
 tools/python/xen/xend/server/blkif.py                                          
       |   56 
 tools/python/xen/xend/server/iopif.py                                          
       |    4 
 tools/python/xen/xend/server/irqif.py                                          
       |    2 
 tools/python/xen/xend/server/netif.py                                          
       |   38 
 tools/python/xen/xend/server/pciif.py                                          
       |   61 
 tools/python/xen/xend/server/tpmif.py                                          
       |   32 
 tools/python/xen/xend/sxp.py                                                   
       |   24 
 tools/python/xen/xend/uuid.py                                                  
       |   10 
 tools/python/xen/xm/create.py                                                  
       |   84 
 tools/python/xen/xm/main.py                                                    
       |  108 
 tools/python/xen/xm/new.py                                                     
       |   68 
 tools/xenmon/Makefile                                                          
       |    2 
 tools/xenmon/xenmon.py                                                         
       |    4 
 tools/xenstat/libxenstat/src/xenstat.c                                         
       |   20 
 tools/xenstore/Makefile                                                        
       |    2 
 tools/xenstore/xsls.c                                                          
       |   19 
 tools/xentrace/formats                                                         
       |    2 
 tools/xm-test/configure.ac                                                     
       |    9 
 tools/xm-test/lib/XmTestLib/arch.py                                            
       |    1 
 tools/xm-test/lib/XmTestReport/arch.py                                         
       |    4 
 tools/xm-test/ramdisk/Makefile.am                                              
       |    6 
 tools/xm-test/ramdisk/README-XenSource-initrd-1.0-img                          
       |    3 
 tools/xm-test/ramdisk/README-XenSource-initrd-1.1-img                          
       |   45 
 tools/xm-test/ramdisk/make-release.sh                                          
       |   47 
 tools/xm-test/ramdisk/patches/buildroot/add_xvd_devices.patch                  
       |    5 
 tools/xm-test/runtest.sh                                                       
       |   27 
 tools/xm-test/tests/block-create/01_block_attach_device_pos.py                 
       |   10 
 tools/xm-test/tests/block-create/02_block_attach_file_device_pos.py            
       |    8 
 tools/xm-test/tests/block-create/04_block_attach_device_repeatedly_pos.py      
       |   16 
 
tools/xm-test/tests/block-create/05_block_attach_and_dettach_device_repeatedly_pos.py
 |   18 
 tools/xm-test/tests/block-create/06_block_attach_baddomain_neg.py              
       |    8 
 tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py              
       |   14 
 tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py         
       |   16 
 
tools/xm-test/tests/block-create/09_block_attach_and_dettach_device_check_data_pos.py
 |   44 
 tools/xm-test/tests/block-create/10_block_attach_dettach_multiple_devices.py   
       |   30 
 tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py                
       |    2 
 tools/xm-test/tests/block-create/12_block_attach_shared_domU.py                
       |    2 
 tools/xm-test/tests/block-destroy/01_block-destroy_btblock_pos.py              
       |    8 
 tools/xm-test/tests/block-destroy/02_block-destroy_rtblock_pos.py              
       |    8 
 tools/xm-test/tests/block-destroy/04_block-destroy_nonattached_neg.py          
       |    2 
 tools/xm-test/tests/block-destroy/05_block-destroy_byname_pos.py               
       |    8 
 tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py           
       |   10 
 tools/xm-test/tests/block-integrity/01_block_device_read_verify.py             
       |    4 
 tools/xm-test/tests/block-integrity/02_block_device_write_verify.py            
       |    4 
 tools/xm-test/tests/block-list/01_block-list_pos.py                            
       |    6 
 tools/xm-test/tests/block-list/02_block-list_attachbd_pos.py                   
       |    6 
 tools/xm-test/tests/block-list/03_block-list_anotherbd_pos.py                  
       |   10 
 tools/xm-test/tests/block-list/06_block-list_checkremove_pos.py                
       |   24 
 tools/xm-test/tests/create/07_create_mem64_pos.py                              
       |    2 
 tools/xm-test/tests/create/08_create_mem128_pos.py                             
       |    2 
 tools/xm-test/tests/create/09_create_mem256_pos.py                             
       |    2 
 tools/xm-test/tests/create/14_create_blockroot_pos.py                          
       |   11 
 tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py          
       |    6 
 unmodified_drivers/linux-2.6/Makefile                                          
       |    1 
 unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h        
       |    1 
 unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h              
       |   15 
 unmodified_drivers/linux-2.6/mkbuildtree                                       
       |    3 
 unmodified_drivers/linux-2.6/platform-pci/evtchn.c                             
       |    8 
 unmodified_drivers/linux-2.6/util/Kbuild                                       
       |    3 
 unmodified_drivers/linux-2.6/util/Makefile                                     
       |    3 
 xen/COPYING                                                                    
       |   20 
 xen/arch/ia64/vmx/mmio.c                                                       
       |   16 
 xen/arch/ia64/vmx/vlsapic.c                                                    
       |   61 
 xen/arch/ia64/vmx/vmx_hypercall.c                                              
       |    2 
 xen/arch/ia64/vmx/vmx_init.c                                                   
       |   11 
 xen/arch/ia64/vmx/vmx_process.c                                                
       |    4 
 xen/arch/ia64/vmx/vmx_support.c                                                
       |   25 
 xen/arch/ia64/xen/dom0_ops.c                                                   
       |    3 
 xen/arch/ia64/xen/domain.c                                                     
       |  110 
 xen/arch/ia64/xen/irq.c                                                        
       |   14 
 xen/arch/ia64/xen/mm.c                                                         
       |   77 
 xen/arch/ia64/xen/tlb_track.c                                                  
       |    5 
 xen/arch/ia64/xen/vcpu.c                                                       
       |    7 
 xen/arch/ia64/xen/xencomm.c                                                    
       |    7 
 xen/arch/ia64/xen/xensetup.c                                                   
       |    6 
 xen/arch/powerpc/domain.c                                                      
       |   23 
 xen/arch/powerpc/domain_build.c                                                
       |    2 
 xen/arch/powerpc/mm.c                                                          
       |    8 
 xen/arch/powerpc/papr/xlate.c                                                  
       |    2 
 xen/arch/powerpc/setup.c                                                       
       |    9 
 xen/arch/powerpc/shadow.c                                                      
       |    4 
 xen/arch/powerpc/usercopy.c                                                    
       |    7 
 xen/arch/x86/domain.c                                                          
       |  129 
 xen/arch/x86/domain_build.c                                                    
       |  100 
 xen/arch/x86/domctl.c                                                          
       |   57 
 xen/arch/x86/e820.c                                                            
       |    2 
 xen/arch/x86/extable.c                                                         
       |    2 
 xen/arch/x86/hvm/hvm.c                                                         
       |  508 
 xen/arch/x86/hvm/i8254.c                                                       
       |   16 
 xen/arch/x86/hvm/i8259.c                                                       
       |  295 
 xen/arch/x86/hvm/instrlen.c                                                    
       |    5 
 xen/arch/x86/hvm/intercept.c                                                   
       |   93 
 xen/arch/x86/hvm/io.c                                                          
       |  139 
 xen/arch/x86/hvm/platform.c                                                    
       |   85 
 xen/arch/x86/hvm/pmtimer.c                                                     
       |    6 
 xen/arch/x86/hvm/rtc.c                                                         
       |   30 
 xen/arch/x86/hvm/svm/intr.c                                                    
       |   80 
 xen/arch/x86/hvm/svm/svm.c                                                     
       |  245 
 xen/arch/x86/hvm/svm/vmcb.c                                                    
       |  412 
 xen/arch/x86/hvm/svm/x86_32/exits.S                                            
       |    7 
 xen/arch/x86/hvm/svm/x86_64/exits.S                                            
       |   11 
 xen/arch/x86/hvm/vioapic.c                                                     
       |  988 -
 xen/arch/x86/hvm/vlapic.c                                                      
       |  737 
 xen/arch/x86/hvm/vmx/io.c                                                      
       |   48 
 xen/arch/x86/hvm/vmx/vmcs.c                                                    
       |  479 
 xen/arch/x86/hvm/vmx/vmx.c                                                     
       |  829 
 xen/arch/x86/hvm/vmx/x86_32/exits.S                                            
       |    3 
 xen/arch/x86/hvm/vmx/x86_64/exits.S                                            
       |    3 
 xen/arch/x86/io_apic.c                                                         
       |    3 
 xen/arch/x86/irq.c                                                             
       |   13 
 xen/arch/x86/mm.c                                                              
       |   33 
 xen/arch/x86/mm/shadow/common.c                                                
       |  152 
 xen/arch/x86/mm/shadow/multi.c                                                 
       |  717 
 xen/arch/x86/mm/shadow/private.h                                               
       |  117 
 xen/arch/x86/mm/shadow/types.h                                                 
       |   96 
 xen/arch/x86/oprofile/xenoprof.c                                               
       |    2 
 xen/arch/x86/platform_hypercall.c                                              
       |    2 
 xen/arch/x86/setup.c                                                           
       |   11 
 xen/arch/x86/traps.c                                                           
       |  114 
 xen/arch/x86/x86_32/asm-offsets.c                                              
       |    1 
 xen/arch/x86/x86_32/domain_page.c                                              
       |    2 
 xen/arch/x86/x86_32/seg_fixup.c                                                
       |   50 
 xen/arch/x86/x86_32/traps.c                                                    
       |   16 
 xen/arch/x86/x86_64/asm-offsets.c                                              
       |    1 
 xen/arch/x86/x86_64/traps.c                                                    
       |   24 
 xen/arch/x86/x86_emulate.c                                                     
       |   12 
 xen/common/domain.c                                                            
       |   99 
 xen/common/domctl.c                                                            
       |   44 
 xen/common/event_channel.c                                                     
       |    3 
 xen/common/grant_table.c                                                       
       |   93 
 xen/common/keyhandler.c                                                        
       |    4 
 xen/common/lib.c                                                               
       |   17 
 xen/common/memory.c                                                            
       |  303 
 xen/common/multicall.c                                                         
       |    2 
 xen/common/page_alloc.c                                                        
       |    7 
 xen/common/perfc.c                                                             
       |   13 
 xen/common/sched_credit.c                                                      
       |  520 
 xen/common/sched_sedf.c                                                        
       |   44 
 xen/common/schedule.c                                                          
       |   27 
 xen/common/trace.c                                                             
       |    2 
 xen/common/xmalloc.c                                                           
       |   90 
 xen/drivers/char/console.c                                                     
       |  260 
 xen/include/asm-ia64/config.h                                                  
       |    7 
 xen/include/asm-ia64/debugger.h                                                
       |    1 
 xen/include/asm-ia64/mm.h                                                      
       |    2 
 xen/include/asm-ia64/vlsapic.h                                                 
       |    1 
 xen/include/asm-ia64/vmx.h                                                     
       |    2 
 xen/include/asm-ia64/vmx_platform.h                                            
       |    6 
 xen/include/asm-ia64/vmx_vpd.h                                                 
       |    1 
 xen/include/asm-powerpc/powerpc64/config.h                                     
       |    6 
 xen/include/asm-x86/bitops.h                                                   
       |   58 
 xen/include/asm-x86/config.h                                                   
       |    7 
 xen/include/asm-x86/grant_table.h                                              
       |    4 
 xen/include/asm-x86/hvm/domain.h                                               
       |   12 
 xen/include/asm-x86/hvm/hvm.h                                                  
       |   31 
 xen/include/asm-x86/hvm/io.h                                                   
       |   18 
 xen/include/asm-x86/hvm/support.h                                              
       |   17 
 xen/include/asm-x86/hvm/svm/vmcb.h                                             
       |   24 
 xen/include/asm-x86/hvm/vcpu.h                                                 
       |    5 
 xen/include/asm-x86/hvm/vioapic.h                                              
       |  113 
 xen/include/asm-x86/hvm/vlapic.h                                               
       |  116 
 xen/include/asm-x86/hvm/vmx/vmcs.h                                             
       |    6 
 xen/include/asm-x86/hvm/vmx/vmx.h                                              
       |  178 
 xen/include/asm-x86/hvm/vpic.h                                                 
       |   39 
 xen/include/asm-x86/hvm/vpt.h                                                  
       |    1 
 xen/include/asm-x86/mm.h                                                       
       |    9 
 xen/include/asm-x86/page.h                                                     
       |   12 
 xen/include/asm-x86/perfc_defn.h                                               
       |    3 
 xen/include/asm-x86/processor.h                                                
       |    2 
 xen/include/asm-x86/regs.h                                                     
       |    2 
 xen/include/asm-x86/shadow.h                                                   
       |   70 
 xen/include/asm-x86/x86_32/page-2level.h                                       
       |    3 
 xen/include/asm-x86/x86_32/page-3level.h                                       
       |   11 
 xen/include/asm-x86/x86_64/page.h                                              
       |    3 
 xen/include/public/COPYING                                                     
       |   16 
 xen/include/public/acm.h                                                       
       |   18 
 xen/include/public/acm_ops.h                                                   
       |   18 
 xen/include/public/arch-ia64.h                                                 
       |   19 
 xen/include/public/arch-x86_32.h                                               
       |   21 
 xen/include/public/arch-x86_64.h                                               
       |   27 
 xen/include/public/callback.h                                                  
       |   18 
 xen/include/public/dom0_ops.h                                                  
       |   18 
 xen/include/public/domctl.h                                                    
       |   63 
 xen/include/public/elfnote.h                                                   
       |   18 
 xen/include/public/event_channel.h                                             
       |   18 
 xen/include/public/features.h                                                  
       |   18 
 xen/include/public/grant_table.h                                               
       |   18 
 xen/include/public/hvm/e820.h                                                  
       |   27 
 xen/include/public/hvm/hvm_info_table.h                                        
       |   18 
 xen/include/public/hvm/hvm_op.h                                                
       |   25 
 xen/include/public/hvm/ioreq.h                                                 
       |   48 
 xen/include/public/hvm/params.h                                                
       |   42 
 xen/include/public/hvm/vmx_assist.h                                            
       |   18 
 xen/include/public/io/blkif.h                                                  
       |   47 
 xen/include/public/io/console.h                                                
       |   18 
 xen/include/public/io/netif.h                                                  
       |   18 
 xen/include/public/io/pciif.h                                                  
       |   18 
 xen/include/public/io/ring.h                                                   
       |   18 
 xen/include/public/io/tpmif.h                                                  
       |   18 
 xen/include/public/io/xenbus.h                                                 
       |   18 
 xen/include/public/io/xs_wire.h                                                
       |   19 
 xen/include/public/memory.h                                                    
       |   18 
 xen/include/public/nmi.h                                                       
       |   18 
 xen/include/public/physdev.h                                                   
       |   20 
 xen/include/public/platform.h                                                  
       |   18 
 xen/include/public/sched.h                                                     
       |   18 
 xen/include/public/sysctl.h                                                    
       |   18 
 xen/include/public/trace.h                                                     
       |   18 
 xen/include/public/vcpu.h                                                      
       |   18 
 xen/include/public/version.h                                                   
       |   18 
 xen/include/public/xen-compat.h                                                
       |   18 
 xen/include/public/xen.h                                                       
       |   18 
 xen/include/public/xenoprof.h                                                  
       |   18 
 xen/include/xen/config.h                                                       
       |   74 
 xen/include/xen/console.h                                                      
       |    3 
 xen/include/xen/domain.h                                                       
       |   14 
 xen/include/xen/lib.h                                                          
       |    4 
 xen/include/xen/sched-if.h                                                     
       |    6 
 xen/include/xen/sched.h                                                        
       |   61 
 xen/include/xen/softirq.h                                                      
       |    5 
 488 files changed, 47189 insertions(+), 11341 deletions(-), 3 modifications(!)

diff -r 11b718eb22c9 -r ebed72718263 .hgignore
--- a/.hgignore Thu Nov 02 12:43:04 2006 -0700
+++ b/.hgignore Fri Nov 10 11:11:04 2006 -0700
@@ -98,7 +98,7 @@
 ^tools/firmware/.*\.bin$
 ^tools/firmware/.*\.sym$
 ^tools/firmware/.*bios/.*bios.*\.txt$
-^tools/firmware/acpi/acpigen$
+^tools/firmware/hvmloader/acpi/acpigen$
 ^tools/firmware/hvmloader/hvmloader$
 ^tools/firmware/hvmloader/roms\.h$
 ^tools/firmware/rombios/BIOS-bochs-[^/]*$
@@ -123,6 +123,7 @@
 ^tools/ioemu/qemu\.1$
 ^tools/ioemu/qemu\.pod$
 ^tools/libxc/xen/.*$
+^tools/libxen/test/test_bindings$
 ^tools/libaio/src/.*\.ol$
 ^tools/libaio/src/.*\.os$
 ^tools/misc/cpuperf/cpuperf-perfcntr$
diff -r 11b718eb22c9 -r ebed72718263 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Thu Nov 02 12:43:04 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Fri Nov 10 11:11:04 2006 -0700
@@ -1529,7 +1529,7 @@ CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
+CONFIG_XEN_BLKDEV_TAP=y
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 11b718eb22c9 -r ebed72718263 buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Thu Nov 02 12:43:04 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_ia64     Fri Nov 10 11:11:04 2006 -0700
@@ -1535,7 +1535,7 @@ CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
+CONFIG_XEN_BLKDEV_TAP=y
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 11b718eb22c9 -r ebed72718263 config/SunOS.mk
--- a/config/SunOS.mk   Thu Nov 02 12:43:04 2006 -0700
+++ b/config/SunOS.mk   Fri Nov 10 11:11:04 2006 -0700
@@ -21,7 +21,7 @@ SOCKET_LIBS = -lsocket
 SOCKET_LIBS = -lsocket
 CURSES_LIBS = -lcurses
 SONAME_LDFLAG = -h
-SHLIB_CFLAGS = -static-libgcc -shared
+SHLIB_CFLAGS = -R /usr/sfw/$(LIBDIR) -shared
 
 ifneq ($(debug),y)
 # Optimisation flags are overridable
diff -r 11b718eb22c9 -r ebed72718263 docs/src/user.tex
--- a/docs/src/user.tex Thu Nov 02 12:43:04 2006 -0700
+++ b/docs/src/user.tex Fri Nov 10 11:11:04 2006 -0700
@@ -3192,6 +3192,15 @@ editing \path{grub.conf}.
   input to DOM0 when it boots --- if it is `x' then auto-switching is
   disabled.  Any other value, or omitting the character, enables
   auto-switching.  [NB. Default switch-char is `a'.]
+\item [ loglvl=$<$level$>/<$level$>$ ]
+  Specify logging level. Messages of the specified severity level (and
+  higher) will be printed to the Xen console. Valid levels are `none',
+  `error', `warning', `info', `debug', and `all'. The second level
+  specifier is optional: it is used to specify message severities
+  which are to be rate limited. Default is `loglvl=warning'.
+\item [ guest\_loglvl=$<$level$>/<$level$>$ ] As for loglvl, but
+  applies to messages relating to guests. Default is
+  `guest\_loglvl=none/warning'. 
 \item [ nmi=xxx ]
   Specify what to do with an NMI parity or I/O error. \\
   `nmi=fatal':  Xen prints a diagnostic and then hangs. \\
@@ -3202,12 +3211,21 @@ editing \path{grub.conf}.
   ignored. This parameter may be specified with a B, K, M or G suffix,
   representing bytes, kilobytes, megabytes and gigabytes respectively.
   The default unit, if no suffix is specified, is kilobytes.
-\item [ dom0\_mem=xxx ] Set the amount of memory to be allocated to
-  domain0. In Xen 3.x the parameter may be specified with a B, K, M or
+\item [ dom0\_mem=$<$specifier list$>$ ] Set the amount of memory to
+  be allocated to domain 0. This is a comma-separated list containing
+  the following optional components:
+  \begin{description}
+  \item[ min:$<$min\_amt$>$ ] Minimum amount to allocate to domain 0
+  \item[ max:$<$min\_amt$>$ ] Maximum amount to allocate to domain 0
+  \item[ $<$amt$>$ ] Precise amount to allocate to domain 0
+  \end{description}
+  Each numeric parameter may be specified with a B, K, M or
   G suffix, representing bytes, kilobytes, megabytes and gigabytes
   respectively; if no suffix is specified, the parameter defaults to
-  kilobytes. In previous versions of Xen, suffixes were not supported
-  and the value is always interpreted as kilobytes.
+  kilobytes. Negative values are subtracted from total available
+  memory. If $<$amt$>$ is not specified, it defaults to all available
+  memory less a small amount (clamped to 128MB) for uses such as DMA
+  buffers.
 \item [ dom0\_vcpus\_pin ] Pins domain 0 VCPUs on their respective
   physical CPUS (default=false).
 \item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c  Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c  Fri Nov 10 11:11:04 
2006 -0700
@@ -60,7 +60,7 @@ int __init sysenter_setup(void)
 
 #ifdef CONFIG_XEN
        if (boot_cpu_has(X86_FEATURE_SEP)) {
-               struct callback_register sysenter = {
+               static struct callback_register __initdata sysenter = {
                        .type = CALLBACKTYPE_sysenter,
                        .address = { __KERNEL_CS, (unsigned long)sysenter_entry 
},
                };
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Fri Nov 10 11:11:04 
2006 -0700
@@ -325,6 +325,7 @@ int xen_create_contiguous_region(
        success = (exchange.nr_exchanged == (1UL << order));
        BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
        BUG_ON(success && (rc != 0));
+#ifdef CONFIG_XEN_COMPAT_030002
        if (unlikely(rc == -ENOSYS)) {
                /* Compatibility when XENMEM_exchange is unsupported. */
                if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
@@ -341,6 +342,7 @@ int xen_create_contiguous_region(
                                BUG();
                }
        }
+#endif
 
        /* 3. Map the new extent in place of old pages. */
        for (i = 0; i < (1UL<<order); i++) {
@@ -419,6 +421,7 @@ void xen_destroy_contiguous_region(unsig
        success = (exchange.nr_exchanged == 1);
        BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
        BUG_ON(success && (rc != 0));
+#ifdef CONFIG_XEN_COMPAT_030002
        if (unlikely(rc == -ENOSYS)) {
                /* Compatibility when XENMEM_exchange is unsupported. */
                if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
@@ -429,6 +432,7 @@ void xen_destroy_contiguous_region(unsig
                        BUG();
                success = 1;
        }
+#endif
 
        /* 4. Map new pages in place of old pages. */
        for (i = 0; i < (1UL<<order); i++) {
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c      Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c      Fri Nov 10 11:11:04 
2006 -0700
@@ -663,8 +663,8 @@ void __init mem_init(void)
        totalram_pages += free_all_bootmem();
        /* XEN: init and count low-mem pages outside initial allocation. */
        for (pfn = xen_start_info->nr_pages; pfn < max_low_pfn; pfn++) {
-               ClearPageReserved(&mem_map[pfn]);
-               set_page_count(&mem_map[pfn], 1);
+               ClearPageReserved(pfn_to_page(pfn));
+               set_page_count(pfn_to_page(pfn), 1);
                totalram_pages++;
        }
 
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c      Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xencomm.c      Fri Nov 10 11:11:04 
2006 -0700
@@ -20,6 +20,11 @@
 #include <linux/mm.h>
 #include <xen/interface/xen.h>
 #include <asm/page.h>
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
 #include <asm/xen/xencomm.h>
 
 static int xencomm_debug = 0;
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c    Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c    Fri Nov 10 11:11:04 
2006 -0700
@@ -913,8 +913,8 @@ void __init mem_init(void)
 #endif
        /* XEN: init and count pages outside initial allocation. */
        for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
-               ClearPageReserved(&mem_map[pfn]);
-               set_page_count(&mem_map[pfn], 1);
+               ClearPageReserved(pfn_to_page(pfn));
+               set_page_count(pfn_to_page(pfn), 1);
                totalram_pages++;
        }
        reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn);
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Fri Nov 10 11:11:04 
2006 -0700
@@ -41,6 +41,7 @@
 #include <xen/evtchn.h>
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/tpmif.h>
+#include <xen/gnttab.h>
 #include <xen/xenbus.h>
 #include "tpm.h"
 #include "tpm_vtpm.h"
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Fri Nov 10 
11:11:04 2006 -0700
@@ -189,9 +189,9 @@ static void fast_flush_area(pending_req_
 
 static void print_stats(blkif_t *blkif)
 {
-       printk(KERN_DEBUG "%s: oo %3d  |  rd %4d  |  wr %4d\n",
+       printk(KERN_DEBUG "%s: oo %3d  |  rd %4d  |  wr %4d  |  br %4d\n",
               current->comm, blkif->st_oo_req,
-              blkif->st_rd_req, blkif->st_wr_req);
+              blkif->st_rd_req, blkif->st_wr_req, blkif->st_br_req);
        blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
        blkif->st_rd_req = 0;
        blkif->st_wr_req = 0;
@@ -241,11 +241,17 @@ int blkif_schedule(void *arg)
  * COMPLETION CALLBACK -- Called as bh->b_end_io()
  */
 
-static void __end_block_io_op(pending_req_t *pending_req, int uptodate)
+static void __end_block_io_op(pending_req_t *pending_req, int error)
 {
        /* An error fails the entire request. */
-       if (!uptodate) {
-               DPRINTK("Buffer not up-to-date at end of operation\n");
+       if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) &&
+           (error == -EOPNOTSUPP)) {
+               DPRINTK("blkback: write barrier op failed, not supported\n");
+               blkback_barrier(XBT_NIL, pending_req->blkif->be, 0);
+               pending_req->status = BLKIF_RSP_EOPNOTSUPP;
+       } else if (error) {
+               DPRINTK("Buffer not up-to-date at end of operation, "
+                       "error=%d\n", error);
                pending_req->status = BLKIF_RSP_ERROR;
        }
 
@@ -262,7 +268,7 @@ static int end_block_io_op(struct bio *b
 {
        if (bio->bi_size != 0)
                return 1;
-       __end_block_io_op(bio->bi_private, !error);
+       __end_block_io_op(bio->bi_private, error);
        bio_put(bio);
        return error;
 }
@@ -319,6 +325,9 @@ static int do_block_io_op(blkif_t *blkif
                        blkif->st_rd_req++;
                        dispatch_rw_block_io(blkif, &req, pending_req);
                        break;
+               case BLKIF_OP_WRITE_BARRIER:
+                       blkif->st_br_req++;
+                       /* fall through */
                case BLKIF_OP_WRITE:
                        blkif->st_wr_req++;
                        dispatch_rw_block_io(blkif, &req, pending_req);
@@ -340,7 +349,6 @@ static void dispatch_rw_block_io(blkif_t
                                 pending_req_t *pending_req)
 {
        extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
-       int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
        struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        struct phys_req preq;
        struct { 
@@ -349,6 +357,22 @@ static void dispatch_rw_block_io(blkif_t
        unsigned int nseg;
        struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        int ret, i, nbio = 0;
+       int operation;
+
+       switch (req->operation) {
+       case BLKIF_OP_READ:
+               operation = READ;
+               break;
+       case BLKIF_OP_WRITE:
+               operation = WRITE;
+               break;
+       case BLKIF_OP_WRITE_BARRIER:
+               operation = WRITE_BARRIER;
+               break;
+       default:
+               operation = 0; /* make gcc happy */
+               BUG();
+       }
 
        /* Check that number of segments is sane. */
        nseg = req->nr_segments;
@@ -364,7 +388,7 @@ static void dispatch_rw_block_io(blkif_t
 
        pending_req->blkif     = blkif;
        pending_req->id        = req->id;
-       pending_req->operation = operation;
+       pending_req->operation = req->operation;
        pending_req->status    = BLKIF_RSP_OKAY;
        pending_req->nr_pages  = nseg;
 
@@ -380,7 +404,7 @@ static void dispatch_rw_block_io(blkif_t
                preq.nr_sects += seg[i].nsec;
 
                flags = GNTMAP_host_map;
-               if ( operation == WRITE )
+               if (operation != READ)
                        flags |= GNTMAP_readonly;
                gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags,
                                  req->seg[i].gref, blkif->domid);
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Fri Nov 10 11:11:04 
2006 -0700
@@ -44,6 +44,7 @@
 #include <xen/interface/io/ring.h>
 #include <xen/gnttab.h>
 #include <xen/driver_util.h>
+#include <xen/xenbus.h>
 
 #define DPRINTK(_f, _a...)                     \
        pr_debug("(file=%s, line=%d) " _f,      \
@@ -87,6 +88,7 @@ typedef struct blkif_st {
        int                 st_rd_req;
        int                 st_wr_req;
        int                 st_oo_req;
+       int                 st_br_req;
 
        wait_queue_head_t waiting_to_free;
 
@@ -131,4 +133,7 @@ irqreturn_t blkif_be_int(int irq, void *
 irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 int blkif_schedule(void *arg);
 
+int blkback_barrier(struct xenbus_transaction xbt,
+                   struct backend_info *be, int state);
+
 #endif /* __BLKIF__BACKEND__COMMON_H__ */
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Fri Nov 10 11:11:04 
2006 -0700
@@ -31,7 +31,6 @@
  */
 
 #include "common.h"
-#include <xen/xenbus.h>
 
 #define vbd_sz(_v)   ((_v)->bdev->bd_part ?                            \
        (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
@@ -104,7 +103,7 @@ int vbd_translate(struct phys_req *req, 
        struct vbd *vbd = &blkif->vbd;
        int rc = -EACCES;
 
-       if ((operation == WRITE) && vbd->readonly)
+       if ((operation != READ) && vbd->readonly)
                goto out;
 
        if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Nov 10 11:11:04 
2006 -0700
@@ -20,7 +20,6 @@
 #include <stdarg.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
-#include <xen/xenbus.h>
 #include "common.h"
 
 #undef DPRINTK
@@ -91,11 +90,13 @@ VBD_SHOW(oo_req, "%d\n", be->blkif->st_o
 VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
 VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
 VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
+VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req);
 
 static struct attribute *vbdstat_attrs[] = {
        &dev_attr_oo_req.attr,
        &dev_attr_rd_req.attr,
        &dev_attr_wr_req.attr,
+       &dev_attr_br_req.attr,
        NULL
 };
 
@@ -165,6 +166,19 @@ static int blkback_remove(struct xenbus_
        return 0;
 }
 
+int blkback_barrier(struct xenbus_transaction xbt,
+                   struct backend_info *be, int state)
+{
+       struct xenbus_device *dev = be->dev;
+       int err;
+
+       err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
+                           "%d", state);
+       if (err)
+               xenbus_dev_fatal(dev, err, "writing feature-barrier");
+
+       return err;
+}
 
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
@@ -366,11 +380,14 @@ static void connect(struct backend_info 
        /* Supply the information about the device the frontend needs */
 again:
        err = xenbus_transaction_start(&xbt);
-
        if (err) {
                xenbus_dev_fatal(dev, err, "starting transaction");
                return;
        }
+
+       err = blkback_barrier(xbt, be, 1);
+       if (err)
+               goto abort;
 
        err = xenbus_printf(xbt, dev->nodename, "sectors", "%lu",
                            vbd_size(&be->blkif->vbd));
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Fri Nov 10 
11:11:04 2006 -0700
@@ -320,6 +320,12 @@ static void connect(struct blkfront_info
                return;
        }
 
+       err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+                           "feature-barrier", "%lu", &info->feature_barrier,
+                           NULL);
+       if (err)
+               info->feature_barrier = 0;
+
        err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
        if (err) {
                xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
@@ -569,10 +575,13 @@ static int blkif_queue_request(struct re
        info->shadow[id].request = (unsigned long)req;
 
        ring_req->id = id;
+       ring_req->sector_number = (blkif_sector_t)req->sector;
+       ring_req->handle = info->handle;
+
        ring_req->operation = rq_data_dir(req) ?
                BLKIF_OP_WRITE : BLKIF_OP_READ;
-       ring_req->sector_number = (blkif_sector_t)req->sector;
-       ring_req->handle = info->handle;
+       if (blk_barrier_rq(req))
+               ring_req->operation = BLKIF_OP_WRITE_BARRIER;
 
        ring_req->nr_segments = 0;
        rq_for_each_bio (bio, req) {
@@ -670,6 +679,7 @@ static irqreturn_t blkif_int(int irq, vo
        RING_IDX i, rp;
        unsigned long flags;
        struct blkfront_info *info = (struct blkfront_info *)dev_id;
+       int uptodate;
 
        spin_lock_irqsave(&blkif_io_lock, flags);
 
@@ -694,19 +704,27 @@ static irqreturn_t blkif_int(int irq, vo
 
                ADD_ID_TO_FREELIST(info, id);
 
+               uptodate = (bret->status == BLKIF_RSP_OKAY);
                switch (bret->operation) {
+               case BLKIF_OP_WRITE_BARRIER:
+                       if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
+                               printk("blkfront: %s: write barrier op 
failed\n",
+                                      info->gd->disk_name);
+                               uptodate = -EOPNOTSUPP;
+                               info->feature_barrier = 0;
+                               xlvbd_barrier(info);
+                       }
+                       /* fall through */
                case BLKIF_OP_READ:
                case BLKIF_OP_WRITE:
                        if (unlikely(bret->status != BLKIF_RSP_OKAY))
                                DPRINTK("Bad return from blkdev data "
                                        "request: %x\n", bret->status);
 
-                       ret = end_that_request_first(
-                               req, (bret->status == BLKIF_RSP_OKAY),
+                       ret = end_that_request_first(req, uptodate,
                                req->hard_nr_sectors);
                        BUG_ON(ret);
-                       end_that_request_last(
-                               req, (bret->status == BLKIF_RSP_OKAY));
+                       end_that_request_last(req, uptodate);
                        break;
                default:
                        BUG();
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Fri Nov 10 11:11:04 
2006 -0700
@@ -126,6 +126,7 @@ struct blkfront_info
        struct gnttab_free_callback callback;
        struct blk_shadow shadow[BLK_RING_SIZE];
        unsigned long shadow_free;
+       int feature_barrier;
 
        /**
         * The number of people holding this device open.  We won't allow a
@@ -152,5 +153,6 @@ int xlvbd_add(blkif_sector_t capacity, i
 int xlvbd_add(blkif_sector_t capacity, int device,
              u16 vdisk_info, u16 sector_size, struct blkfront_info *info);
 void xlvbd_del(struct blkfront_info *info);
+int xlvbd_barrier(struct blkfront_info *info);
 
 #endif /* __XEN_DRIVERS_BLOCK_H__ */
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Fri Nov 10 11:11:04 
2006 -0700
@@ -50,7 +50,7 @@
  */
 
 #define NUM_IDE_MAJORS 10
-#define NUM_SCSI_MAJORS 9
+#define NUM_SCSI_MAJORS 17
 #define NUM_VBD_MAJORS 1
 
 static struct xlbd_type_info xlbd_ide_type = {
@@ -165,8 +165,11 @@ xlbd_get_major_info(int vdevice)
        case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
                index = 11 + major - SCSI_DISK1_MAJOR;
                break;
-       case SCSI_CDROM_MAJOR: index = 18; break;
-       default: index = 19; break;
+        case SCSI_DISK8_MAJOR ... SCSI_DISK15_MAJOR:
+                index = 18 + major - SCSI_DISK8_MAJOR;
+                break;
+        case SCSI_CDROM_MAJOR: index = 26; break;
+        default: index = 27; break;
        }
 
        mi = ((major_info[index] != NULL) ? major_info[index] :
@@ -227,6 +230,7 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
        struct xlbd_major_info *mi;
        int nr_minors = 1;
        int err = -ENODEV;
+       unsigned int offset;
 
        BUG_ON(info->gd != NULL);
        BUG_ON(info->mi != NULL);
@@ -244,15 +248,33 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
        if (gd == NULL)
                goto out;
 
-       if (nr_minors > 1)
-               sprintf(gd->disk_name, "%s%c", mi->type->diskname,
-                       'a' + mi->index * mi->type->disks_per_major +
-                       (minor >> mi->type->partn_shift));
-       else
-               sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
-                       'a' + mi->index * mi->type->disks_per_major +
-                       (minor >> mi->type->partn_shift),
-                       minor & ((1 << mi->type->partn_shift) - 1));
+       offset =  mi->index * mi->type->disks_per_major +
+                       (minor >> mi->type->partn_shift);
+       if (nr_minors > 1) {
+               if (offset < 26) {
+                       sprintf(gd->disk_name, "%s%c",
+                                mi->type->diskname, 'a' + offset );
+               }
+               else {
+                       sprintf(gd->disk_name, "%s%c%c",
+                               mi->type->diskname,
+                               'a' + ((offset/26)-1), 'a' + (offset%26) );
+               }
+       }
+       else {
+               if (offset < 26) {
+                       sprintf(gd->disk_name, "%s%c%d",
+                               mi->type->diskname,
+                               'a' + offset,
+                               minor & ((1 << mi->type->partn_shift) - 1));
+               }
+               else {
+                       sprintf(gd->disk_name, "%s%c%c%d",
+                               mi->type->diskname,
+                               'a' + ((offset/26)-1), 'a' + (offset%26),
+                               minor & ((1 << mi->type->partn_shift) - 1));
+               }
+       }
 
        gd->major = mi->major;
        gd->first_minor = minor;
@@ -267,6 +289,10 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
        }
 
        info->rq = gd->queue;
+       info->gd = gd;
+
+       if (info->feature_barrier)
+               xlvbd_barrier(info);
 
        if (vdisk_info & VDISK_READONLY)
                set_disk_ro(gd, 1);
@@ -276,8 +302,6 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
 
        if (vdisk_info & VDISK_CDROM)
                gd->flags |= GENHD_FL_CD;
-
-       info->gd = gd;
 
        return 0;
 
@@ -326,3 +350,26 @@ xlvbd_del(struct blkfront_info *info)
        blk_cleanup_queue(info->rq);
        info->rq = NULL;
 }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+int
+xlvbd_barrier(struct blkfront_info *info)
+{
+       int err;
+
+       err = blk_queue_ordered(info->rq,
+               info->feature_barrier ? QUEUE_ORDERED_DRAIN : 
QUEUE_ORDERED_NONE, NULL);
+       if (err)
+               return err;
+       printk("blkfront: %s: barriers %s\n",
+              info->gd->disk_name, info->feature_barrier ? "enabled" : 
"disabled");
+       return 0;
+}
+#else
+int
+xlvbd_barrier(struct blkfront_info *info)
+{
+       printk("blkfront: %s: barriers disabled\n", info->gd->disk_name);
+       return -ENOSYS;
+}
+#endif
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Fri Nov 10 11:11:04 
2006 -0700
@@ -93,8 +93,9 @@ int setup_xen_class(void)
  * mmap_alloc is initialised to 2 and should be adjustable on the fly via
  * sysfs.
  */
-#define MAX_DYNAMIC_MEM 64
-#define MAX_PENDING_REQS 64   
+#define BLK_RING_SIZE          __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
+#define MAX_DYNAMIC_MEM                BLK_RING_SIZE
+#define MAX_PENDING_REQS       BLK_RING_SIZE
 #define MMAP_PAGES (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
 #define MMAP_VADDR(_start, _req,_seg)                                   \
         (_start +                                                       \
@@ -215,6 +216,7 @@ struct grant_handle_pair
         grant_handle_t kernel;
         grant_handle_t user;
 };
+#define INVALID_GRANT_HANDLE   0xFFFF
 
 static struct grant_handle_pair 
     pending_grant_handles[MAX_DYNAMIC_MEM][MMAP_PAGES];
@@ -293,10 +295,11 @@ static inline int GET_NEXT_REQ(unsigned 
 
 
 #define BLKTAP_INVALID_HANDLE(_g) \
-    (((_g->kernel) == 0xFFFF) && ((_g->user) == 0xFFFF))
+    (((_g->kernel) == INVALID_GRANT_HANDLE) &&  \
+     ((_g->user) == INVALID_GRANT_HANDLE))
 
 #define BLKTAP_INVALIDATE_HANDLE(_g) do {       \
-    (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \
+    (_g)->kernel = INVALID_GRANT_HANDLE; (_g)->user = INVALID_GRANT_HANDLE; \
     } while(0)
 
 
@@ -535,8 +538,10 @@ static int blktap_release(struct inode *
        }
        
        if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) {
-               kthread_stop(info->blkif->xenblkd);
-               info->blkif->xenblkd = NULL;
+               if (info->blkif->xenblkd != NULL) {
+                       kthread_stop(info->blkif->xenblkd);
+                       info->blkif->xenblkd = NULL;
+               }
                info->status = CLEANSHUTDOWN;
        }       
        return 0;
@@ -588,8 +593,6 @@ static int blktap_mmap(struct file *filp
        info->user_vstart  = info->rings_vstart + (RING_PAGES << PAGE_SHIFT);
     
        /* Map the ring pages to the start of the region and reserve it. */
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
        if (remap_pfn_range(vma, vma->vm_start, 
                            __pa(info->ufe_ring.sring) >> PAGE_SHIFT, 
                            PAGE_SIZE, vma->vm_page_prot)) {
@@ -884,6 +887,15 @@ static void fast_flush_area(pending_req_
                return;
        }
 
+       if (info->vma != NULL &&
+           xen_feature(XENFEAT_auto_translated_physmap)) {
+               down_write(&info->vma->vm_mm->mmap_sem);
+               zap_page_range(info->vma, 
+                              MMAP_VADDR(info->user_vstart, u_idx, 0), 
+                              req->nr_pages << PAGE_SHIFT, NULL);
+               up_write(&info->vma->vm_mm->mmap_sem);
+       }
+
        mmap_idx = req->mem_idx;
 
        for (i = 0; i < req->nr_pages; i++) {
@@ -892,14 +904,15 @@ static void fast_flush_area(pending_req_
 
                khandle = &pending_handle(mmap_idx, k_idx, i);
 
-               if (khandle->kernel != 0xFFFF) {
+               if (khandle->kernel != INVALID_GRANT_HANDLE) {
                        gnttab_set_unmap_op(&unmap[invcount],
                                            idx_to_kaddr(mmap_idx, k_idx, i),
                                            GNTMAP_host_map, khandle->kernel);
                        invcount++;
                }
 
-               if (khandle->user != 0xFFFF) {
+               if (khandle->user != INVALID_GRANT_HANDLE) {
+                       BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
                        if (create_lookup_pte_addr(
                                info->vma->vm_mm,
                                MMAP_VADDR(info->user_vstart, u_idx, i),
@@ -908,8 +921,10 @@ static void fast_flush_area(pending_req_
                                return;
                        }
 
-                       gnttab_set_unmap_op(&unmap[invcount],
-                                           ptep, GNTMAP_host_map,
+                       gnttab_set_unmap_op(&unmap[invcount], ptep,
+                                           GNTMAP_host_map
+                                           | GNTMAP_application_map
+                                           | GNTMAP_contains_pte,
                                            khandle->user);
                        invcount++;
                }
@@ -920,7 +935,7 @@ static void fast_flush_area(pending_req_
                GNTTABOP_unmap_grant_ref, unmap, invcount);
        BUG_ON(ret);
        
-       if (info->vma != NULL)
+       if (info->vma != NULL && !xen_feature(XENFEAT_auto_translated_physmap))
                zap_page_range(info->vma, 
                               MMAP_VADDR(info->user_vstart, u_idx, 0), 
                               req->nr_pages << PAGE_SHIFT, NULL);
@@ -1004,11 +1019,14 @@ static int blktap_read_ufe_ring(tap_blki
        rmb();
         
        for (i = info->ufe_ring.rsp_cons; i != rp; i++) {
+               blkif_response_t res;
                resp = RING_GET_RESPONSE(&info->ufe_ring, i);
+               memcpy(&res, resp, sizeof(res));
+               mb(); /* rsp_cons read by RING_FULL() in do_block_io_op(). */
                ++info->ufe_ring.rsp_cons;
 
                /*retrieve [usr_idx] to [mmap_idx,pending_idx] mapping*/
-               usr_idx = (int)resp->id;
+               usr_idx = (int)res.id;
                pending_idx = MASK_PEND_IDX(ID_TO_IDX(info->idx_map[usr_idx]));
                mmap_idx = ID_TO_MIDX(info->idx_map[usr_idx]);
 
@@ -1041,8 +1059,8 @@ static int blktap_read_ufe_ring(tap_blki
                        map[offset] = NULL;
                }
                fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
-               make_response(blkif, pending_req->id, resp->operation,
-                             resp->status);
+               make_response(blkif, pending_req->id, res.operation,
+                             res.status);
                info->idx_map[usr_idx] = INVALID_REQ;
                blkif_put(pending_req->blkif);
                free_req(pending_req);
@@ -1184,8 +1202,10 @@ static void dispatch_rw_block_io(blkif_t
 
        /* Check we have space on user ring - should never fail. */
        usr_idx = GET_NEXT_REQ(info->idx_map);
-       if (usr_idx == INVALID_REQ)
+       if (usr_idx == INVALID_REQ) {
+               BUG();
                goto fail_response;
+       }
 
        /* Check that number of segments is sane. */
        nseg = req->nr_segments;
@@ -1219,14 +1239,12 @@ static void dispatch_rw_block_io(blkif_t
                unsigned long uvaddr;
                unsigned long kvaddr;
                uint64_t ptep;
-               struct page *page;
                uint32_t flags;
 
                uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
                kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
-               page = virt_to_page(kvaddr);
-
-               sector = req->sector_number + (8*i);
+
+               sector = req->sector_number + ((PAGE_SIZE / 512) * i);
                if( (blkif->sectors > 0) && (sector >= blkif->sectors) ) {
                        WPRINTK("BLKTAP: Sector request greater" 
                               "than size\n");
@@ -1236,7 +1254,7 @@ static void dispatch_rw_block_io(blkif_t
                                BLKIF_OP_WRITE ? "WRITE" : "READ"),
                                (long long unsigned) sector,
                                (long long unsigned) sector>>9,
-                               blkif->sectors);
+                               (long long unsigned) blkif->sectors);
                }
 
                flags = GNTMAP_host_map;
@@ -1246,68 +1264,103 @@ static void dispatch_rw_block_io(blkif_t
                                  req->seg[i].gref, blkif->domid);
                op++;
 
-               /* Now map it to user. */
-               ret = create_lookup_pte_addr(info->vma->vm_mm, 
-                                            uvaddr, &ptep);
-               if (ret) {
-                       WPRINTK("Couldn't get a pte addr!\n");
-                       goto fail_flush;
-               }
-
-               flags = GNTMAP_host_map | GNTMAP_application_map
-                       | GNTMAP_contains_pte;
-               if (operation == WRITE)
-                       flags |= GNTMAP_readonly;
-               gnttab_set_map_op(&map[op], ptep, flags,
-                                 req->seg[i].gref, blkif->domid);
-               op++;
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       /* Now map it to user. */
+                       ret = create_lookup_pte_addr(info->vma->vm_mm, 
+                                                    uvaddr, &ptep);
+                       if (ret) {
+                               WPRINTK("Couldn't get a pte addr!\n");
+                               goto fail_flush;
+                       }
+
+                       flags = GNTMAP_host_map | GNTMAP_application_map
+                               | GNTMAP_contains_pte;
+                       if (operation == WRITE)
+                               flags |= GNTMAP_readonly;
+                       gnttab_set_map_op(&map[op], ptep, flags,
+                                         req->seg[i].gref, blkif->domid);
+                       op++;
+               }
        }
 
        ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
        BUG_ON(ret);
 
-       for (i = 0; i < (nseg*2); i+=2) {
-               unsigned long uvaddr;
-               unsigned long kvaddr;
-               unsigned long offset;
-               struct page *pg;
-
-               uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
-               kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
-
-               if (unlikely(map[i].status != 0)) {
-                       WPRINTK("invalid kernel buffer -- "
-                               "could not remap it\n");
-                       ret |= 1;
-                       map[i].handle = 0xFFFF;
-               }
-
-               if (unlikely(map[i+1].status != 0)) {
-                       WPRINTK("invalid user buffer -- "
-                               "could not remap it\n");
-                       ret |= 1;
-                       map[i+1].handle = 0xFFFF;
-               }
-
-               pending_handle(mmap_idx, pending_idx, i/2).kernel 
-                       = map[i].handle;
-               pending_handle(mmap_idx, pending_idx, i/2).user   
-                       = map[i+1].handle;
-
-               if (ret)
-                       continue;
-
-               set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
-                       FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
-               offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
-               pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
-               ((struct page **)info->vma->vm_private_data)[offset] =
-                       pg;
+       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               for (i = 0; i < (nseg*2); i+=2) {
+                       unsigned long uvaddr;
+                       unsigned long kvaddr;
+                       unsigned long offset;
+                       struct page *pg;
+
+                       uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
+                       kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
+
+                       if (unlikely(map[i].status != 0)) {
+                               WPRINTK("invalid kernel buffer -- "
+                                       "could not remap it\n");
+                               ret |= 1;
+                               map[i].handle = INVALID_GRANT_HANDLE;
+                       }
+
+                       if (unlikely(map[i+1].status != 0)) {
+                               WPRINTK("invalid user buffer -- "
+                                       "could not remap it\n");
+                               ret |= 1;
+                               map[i+1].handle = INVALID_GRANT_HANDLE;
+                       }
+
+                       pending_handle(mmap_idx, pending_idx, i/2).kernel 
+                               = map[i].handle;
+                       pending_handle(mmap_idx, pending_idx, i/2).user   
+                               = map[i+1].handle;
+
+                       if (ret)
+                               continue;
+
+                       set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
+                                           FOREIGN_FRAME(map[i].dev_bus_addr
+                                                         >> PAGE_SHIFT));
+                       offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+                       pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
+                       ((struct page **)info->vma->vm_private_data)[offset] =
+                               pg;
+               }
+       } else {
+               for (i = 0; i < nseg; i++) {
+                       unsigned long uvaddr;
+                       unsigned long kvaddr;
+                       unsigned long offset;
+                       struct page *pg;
+
+                       uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
+                       kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
+
+                       if (unlikely(map[i].status != 0)) {
+                               WPRINTK("invalid kernel buffer -- "
+                                       "could not remap it\n");
+                               ret |= 1;
+                               map[i].handle = INVALID_GRANT_HANDLE;
+                       }
+
+                       pending_handle(mmap_idx, pending_idx, i).kernel 
+                               = map[i].handle;
+
+                       if (ret)
+                               continue;
+
+                       offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+                       pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
+                       ((struct page **)info->vma->vm_private_data)[offset] =
+                               pg;
+               }
        }
 
        if (ret)
                goto fail_flush;
 
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               down_write(&info->vma->vm_mm->mmap_sem);
        /* Mark mapped pages as reserved: */
        for (i = 0; i < req->nr_segments; i++) {
                unsigned long kvaddr;
@@ -1316,7 +1369,18 @@ static void dispatch_rw_block_io(blkif_t
                kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
                pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
                SetPageReserved(pg);
-       }
+               if (xen_feature(XENFEAT_auto_translated_physmap)) {
+                       ret = vm_insert_page(info->vma,
+                                            MMAP_VADDR(info->user_vstart,
+                                                       usr_idx, i), pg);
+                       if (ret) {
+                               up_write(&info->vma->vm_mm->mmap_sem);
+                               goto fail_flush;
+                       }
+               }
+       }
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               up_write(&info->vma->vm_mm->mmap_sem);
        
        /*record [mmap_idx,pending_idx] to [usr_idx] mapping*/
        info->idx_map[usr_idx] = MAKE_ID(mmap_idx, pending_idx);
@@ -1327,6 +1391,7 @@ static void dispatch_rw_block_io(blkif_t
                                  info->ufe_ring.req_prod_pvt);
        memcpy(target, req, sizeof(*req));
        target->id = usr_idx;
+       wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
        info->ufe_ring.req_prod_pvt++;
        return;
 
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c  Fri Nov 10 11:11:04 
2006 -0700
@@ -189,7 +189,7 @@ static int blktap_probe(struct xenbus_de
        return 0;
 
 fail:
-       DPRINTK("blktap probe failed");
+       DPRINTK("blktap probe failed\n");
        blktap_remove(dev);
        return err;
 }
@@ -243,7 +243,7 @@ static void tap_frontend_changed(struct 
        struct backend_info *be = dev->dev.driver_data;
        int err;
 
-       DPRINTK("");
+       DPRINTK("\n");
 
        switch (frontend_state) {
        case XenbusStateInitialising:
@@ -318,7 +318,7 @@ static int connect_ring(struct backend_i
        unsigned int evtchn;
        int err;
 
-       DPRINTK("%s", dev->otherend);
+       DPRINTK("%s\n", dev->otherend);
 
        err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", 
                            &ring_ref, "event-channel", "%u", &evtchn, NULL);
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/core/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Fri Nov 10 11:11:04 
2006 -0700
@@ -9,5 +9,5 @@ obj-$(CONFIG_HOTPLUG_CPU)       += cpu_hotplug
 obj-$(CONFIG_HOTPLUG_CPU)      += cpu_hotplug.o
 obj-$(CONFIG_XEN_SYSFS)                += xen_sysfs.o
 obj-$(CONFIG_XEN_SKBUFF)       += skbuff.o
-obj-$(CONFIG_XEN_REBOOT)       += reboot.o
+obj-$(CONFIG_XEN_REBOOT)       += reboot.o machine_reboot.o
 obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Fri Nov 10 11:11:04 
2006 -0700
@@ -1,25 +1,15 @@
 #define __KERNEL_SYSCALLS__
 #include <linux/version.h>
 #include <linux/kernel.h>
-#include <linux/mm.h>
 #include <linux/unistd.h>
 #include <linux/module.h>
 #include <linux/reboot.h>
 #include <linux/sysrq.h>
-#include <linux/stringify.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <xen/evtchn.h>
 #include <asm/hypervisor.h>
-#include <xen/interface/dom0_ops.h>
 #include <xen/xenbus.h>
-#include <linux/cpu.h>
 #include <linux/kthread.h>
-#include <xen/gnttab.h>
-#include <xen/xencons.h>
-#include <xen/cpu_hotplug.h>
-
-extern void ctrl_alt_del(void);
+
+MODULE_LICENSE("Dual BSD/GPL");
 
 #define SHUTDOWN_INVALID  -1
 #define SHUTDOWN_POWEROFF  0
@@ -31,185 +21,17 @@ extern void ctrl_alt_del(void);
  */
 #define SHUTDOWN_HALT      4
 
-#if defined(__i386__) || defined(__x86_64__)
-
-/*
- * Power off function, if any
- */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-void machine_emergency_restart(void)
-{
-       /* We really want to get pending console data out before we die. */
-       xencons_force_flush();
-       HYPERVISOR_shutdown(SHUTDOWN_reboot);
-}
-
-void machine_restart(char * __unused)
-{
-       machine_emergency_restart();
-}
-
-void machine_halt(void)
-{
-       machine_power_off();
-}
-
-void machine_power_off(void)
-{
-       /* We really want to get pending console data out before we die. */
-       xencons_force_flush();
-       if (pm_power_off)
-               pm_power_off();
-       HYPERVISOR_shutdown(SHUTDOWN_poweroff);
-}
-
-int reboot_thru_bios = 0;      /* for dmi_scan.c */
-EXPORT_SYMBOL(machine_restart);
-EXPORT_SYMBOL(machine_halt);
-EXPORT_SYMBOL(machine_power_off);
-
-#endif /* defined(__i386__) || defined(__x86_64__) */
-
-/******************************************************************************
- * Stop/pickle callback handling.
- */
-
 /* Ignore multiple shutdown requests. */
 static int shutting_down = SHUTDOWN_INVALID;
+
 static void __shutdown_handler(void *unused);
 static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
 
-#if defined(__i386__) || defined(__x86_64__)
-
-/* Ensure we run on the idle task page tables so that we will
-   switch page tables before running user space. This is needed
-   on architectures with separate kernel and user page tables
-   because the user page table pointer is not saved/restored. */
-static void switch_idle_mm(void)
-{
-       struct mm_struct *mm = current->active_mm;
-
-       if (mm == &init_mm)
-               return;
-
-       atomic_inc(&init_mm.mm_count);
-       switch_mm(mm, &init_mm, current);
-       current->active_mm = &init_mm;
-       mmdrop(mm);
-}
-
-static void pre_suspend(void)
-{
-       HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
-       clear_fixmap(FIX_SHARED_INFO);
-
-       xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
-       xen_start_info->console.domU.mfn =
-               mfn_to_pfn(xen_start_info->console.domU.mfn);
-}
-
-static void post_suspend(void)
-{
-       int i, j, k, fpp;
-       extern unsigned long max_pfn;
-       extern unsigned long *pfn_to_mfn_frame_list_list;
-       extern unsigned long *pfn_to_mfn_frame_list[];
-
-       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-
-       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-
-       memset(empty_zero_page, 0, PAGE_SIZE);
-
-       HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
-               virt_to_mfn(pfn_to_mfn_frame_list_list);
-
-       fpp = PAGE_SIZE/sizeof(unsigned long);
-       for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
-               if ((j % fpp) == 0) {
-                       k++;
-                       pfn_to_mfn_frame_list_list[k] =
-                               virt_to_mfn(pfn_to_mfn_frame_list[k]);
-                       j = 0;
-               }
-               pfn_to_mfn_frame_list[k][j] =
-                       virt_to_mfn(&phys_to_machine_mapping[i]);
-       }
-       HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-}
-
-#else /* !(defined(__i386__) || defined(__x86_64__)) */
-
-#define switch_idle_mm()       ((void)0)
-#define mm_pin_all()           ((void)0)
-#define pre_suspend()          ((void)0)
-#define post_suspend()         ((void)0)
-
+#ifdef CONFIG_XEN
+int __xen_suspend(void);
+#else
+#define __xen_suspend() (void)0
 #endif
-
-static int __do_suspend(void *ignore)
-{
-       int err;
-
-       extern void time_resume(void);
-
-       BUG_ON(smp_processor_id() != 0);
-       BUG_ON(in_interrupt());
-
-#if defined(__i386__) || defined(__x86_64__)
-       if (xen_feature(XENFEAT_auto_translated_physmap)) {
-               printk(KERN_WARNING "Cannot suspend in "
-                      "auto_translated_physmap mode.\n");
-               return -EOPNOTSUPP;
-       }
-#endif
-
-       err = smp_suspend();
-       if (err)
-               return err;
-
-       xenbus_suspend();
-
-       preempt_disable();
-
-       mm_pin_all();
-       local_irq_disable();
-       preempt_enable();
-
-       gnttab_suspend();
-
-       pre_suspend();
-
-       /*
-        * We'll stop somewhere inside this hypercall. When it returns,
-        * we'll start resuming after the restore.
-        */
-       HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
-
-       shutting_down = SHUTDOWN_INVALID;
-
-       post_suspend();
-
-       gnttab_resume();
-
-       irq_resume();
-
-       time_resume();
-
-       switch_idle_mm();
-
-       local_irq_enable();
-
-       xencons_resume();
-
-       xenbus_resume();
-
-       smp_resume();
-
-       return err;
-}
 
 static int shutdown_process(void *__unused)
 {
@@ -222,16 +44,25 @@ static int shutdown_process(void *__unus
 
        if ((shutting_down == SHUTDOWN_POWEROFF) ||
            (shutting_down == SHUTDOWN_HALT)) {
-               if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
+               if (call_usermodehelper("/sbin/poweroff", poweroff_argv, envp, 
0) < 0) {
+#ifdef CONFIG_XEN
                        sys_reboot(LINUX_REBOOT_MAGIC1,
                                   LINUX_REBOOT_MAGIC2,
                                   LINUX_REBOOT_CMD_POWER_OFF,
                                   NULL);
+#endif /* CONFIG_XEN */
                }
        }
 
        shutting_down = SHUTDOWN_INVALID; /* could try again */
 
+       return 0;
+}
+
+static int xen_suspend(void *__unused)
+{
+       __xen_suspend();
+       shutting_down = SHUTDOWN_INVALID;
        return 0;
 }
 
@@ -257,7 +88,7 @@ static void __shutdown_handler(void *unu
                err = kernel_thread(shutdown_process, NULL,
                                    CLONE_FS | CLONE_FILES);
        else
-               err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0);
+               err = kthread_create_on_cpu(xen_suspend, NULL, "suspend", 0);
 
        if (err < 0) {
                printk(KERN_WARNING "Error creating shutdown process (%d): "
@@ -298,7 +129,7 @@ static void shutdown_handler(struct xenb
        if (strcmp(str, "poweroff") == 0)
                shutting_down = SHUTDOWN_POWEROFF;
        else if (strcmp(str, "reboot") == 0)
-               ctrl_alt_del();
+               kill_proc(1, SIGINT, 1); /* interrupt init */
        else if (strcmp(str, "suspend") == 0)
                shutting_down = SHUTDOWN_SUSPEND;
        else if (strcmp(str, "halt") == 0)
@@ -364,10 +195,14 @@ static int setup_shutdown_watcher(struct
        err = register_xenbus_watch(&shutdown_watch);
        if (err)
                printk(KERN_ERR "Failed to set shutdown watcher\n");
+       else
+               xenbus_write(XBT_NIL, "control", "feature-reboot", "1");
 
        err = register_xenbus_watch(&sysrq_watch);
        if (err)
                printk(KERN_ERR "Failed to set sysrq watcher\n");
+       else
+               xenbus_write(XBT_NIL, "control", "feature-sysrq", "1");
 
        return NOTIFY_DONE;
 }
@@ -378,6 +213,7 @@ static int __init setup_shutdown_event(v
                .notifier_call = setup_shutdown_watcher
        };
        register_xenstore_notifier(&xenstore_notifier);
+
        return 0;
 }
 
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Nov 10 
11:11:04 2006 -0700
@@ -166,9 +166,6 @@ netif_t *netif_alloc(domid_t domid, unsi
        SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
 
        dev->tx_queue_len = netbk_queue_length;
-       if (dev->tx_queue_len != 0)
-               printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero "
-                      "queue length (%lu)!\n", dev->name, dev->tx_queue_len);
 
        /*
         * Initialise a dummy MAC address. We choose the numerically
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Nov 10 
11:11:04 2006 -0700
@@ -814,7 +814,7 @@ void netif_deschedule_work(netif_t *neti
 
 static void tx_add_credit(netif_t *netif)
 {
-       unsigned long max_burst;
+       unsigned long max_burst, max_credit;
 
        /*
         * Allow a burst big enough to transmit a jumbo packet of up to 128kB.
@@ -824,9 +824,10 @@ static void tx_add_credit(netif_t *netif
        max_burst = min(max_burst, 131072UL);
        max_burst = max(max_burst, netif->credit_bytes);
 
-       netif->remaining_credit = min(netif->remaining_credit +
-                                     netif->credit_bytes,
-                                     max_burst);
+       /* Take care that adding a new chunk of credit doesn't wrap to zero. */
+       max_credit = max(netif->remaining_credit + netif->credit_bytes, ~0UL);
+
+       netif->remaining_credit = min(max_credit, max_burst);
 }
 
 static void tx_credit_callback(unsigned long data)
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Nov 10 11:11:04 
2006 -0700
@@ -93,10 +93,22 @@ static int netback_probe(struct xenbus_d
                        goto abort_transaction;
                }
 
+               /* We support rx-copy path. */
                err = xenbus_printf(xbt, dev->nodename,
                                    "feature-rx-copy", "%d", 1);
                if (err) {
-                       message = "writing feature-copying";
+                       message = "writing feature-rx-copy";
+                       goto abort_transaction;
+               }
+
+               /*
+                * We don't support rx-flip path (except old guests who don't
+                * grok this feature flag).
+                */
+               err = xenbus_printf(xbt, dev->nodename,
+                                   "feature-rx-flip", "%d", 0);
+               if (err) {
+                       message = "writing feature-rx-flip";
                        goto abort_transaction;
                }
 
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Nov 10 
11:11:04 2006 -0700
@@ -101,6 +101,14 @@ static inline void dev_disable_gso_featu
 }
 #elif defined(NETIF_F_TSO)
 #define HAVE_TSO                       1
+
+/* Some older kernels cannot cope with incorrect checksums,
+ * particularly in netfilter. I'm not sure there is 100% correlation
+ * with the presence of NETIF_F_TSO but it appears to be a good first
+ * approximiation.
+ */
+#define HAVE_NO_CSUM_OFFLOAD           1
+
 #define gso_size tso_size
 #define gso_segs tso_segs
 static inline void dev_disable_gso_features(struct net_device *dev)
@@ -242,7 +250,6 @@ static void netif_disconnect_backend(str
 static void netif_disconnect_backend(struct netfront_info *);
 static int open_netdev(struct netfront_info *);
 static void close_netdev(struct netfront_info *);
-static void netif_free(struct netfront_info *);
 
 static int network_connect(struct net_device *);
 static void network_tx_buf_gc(struct net_device *);
@@ -395,6 +402,14 @@ again:
                goto abort_transaction;
        }
 
+#ifdef HAVE_NO_CSUM_OFFLOAD
+       err = xenbus_printf(xbt, dev->nodename, "feature-no-csum-offload", 
"%d", 1);
+       if (err) {
+               message = "writing feature-no-csum-offload";
+               goto abort_transaction;
+       }
+#endif
+
        err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
        if (err) {
                message = "writing feature-sg";
@@ -427,7 +442,6 @@ again:
  out:
        return err;
 }
-
 
 static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
 {
@@ -488,10 +502,8 @@ static int setup_device(struct xenbus_de
        return 0;
 
  fail:
-       netif_free(info);
        return err;
 }
-
 
 /**
  * Callback received when the backend's state changes.
@@ -513,10 +525,8 @@ static void backend_changed(struct xenbu
                break;
 
        case XenbusStateInitWait:
-               if (network_connect(netdev) != 0) {
-                       netif_free(np);
+               if (network_connect(netdev) != 0)
                        break;
-               }
                xenbus_switch_state(dev, XenbusStateConnected);
                (void)send_fake_arp(netdev);
                break;
@@ -526,7 +536,6 @@ static void backend_changed(struct xenbu
                break;
        }
 }
-
 
 /** Send a packet on a net device to encourage switches to learn the
  * MAC. We send a fake ARP request.
@@ -555,7 +564,6 @@ static int send_fake_arp(struct net_devi
 
        return dev_queue_xmit(skb);
 }
-
 
 static int network_open(struct net_device *dev)
 {
@@ -648,13 +656,11 @@ static void network_tx_buf_gc(struct net
        network_maybe_wake_tx(dev);
 }
 
-
 static void rx_refill_timeout(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
        netif_rx_schedule(dev);
 }
-
 
 static void network_alloc_rx_buffers(struct net_device *dev)
 {
@@ -1617,8 +1623,16 @@ static void xennet_set_features(struct n
        if (!(dev->features & NETIF_F_IP_CSUM))
                return;
 
-       if (!xennet_set_sg(dev, 1))
-               xennet_set_tso(dev, 1);
+       if (xennet_set_sg(dev, 1))
+               return;
+
+       /* Before 2.6.9 TSO seems to be unreliable so do not enable it
+        * on older kernels.
+        */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+       xennet_set_tso(dev, 1);
+#endif
+
 }
 
 static int network_connect(struct net_device *dev)
@@ -2063,14 +2077,6 @@ static void netif_disconnect_backend(str
 }
 
 
-static void netif_free(struct netfront_info *info)
-{
-       close_netdev(info);
-       netif_disconnect_backend(info);
-       free_netdev(info->netdev);
-}
-
-
 static void end_access(int ref, void *page)
 {
        if (ref != GRANT_INVALID_REF)
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Fri Nov 10 
11:11:04 2006 -0700
@@ -53,6 +53,8 @@ static int privcmd_ioctl(struct inode *i
                        return -EFAULT;
 
 #if defined(__i386__)
+               if (hypercall.op >= (PAGE_SIZE >> 5))
+                       break;
                __asm__ __volatile__ (
                        "pushl %%ebx; pushl %%ecx; pushl %%edx; "
                        "pushl %%esi; pushl %%edi; "
@@ -69,21 +71,21 @@ static int privcmd_ioctl(struct inode *i
                        "popl %%ecx; popl %%ebx"
                        : "=a" (ret) : "0" (&hypercall) : "memory" );
 #elif defined (__x86_64__)
-               {
+               if (hypercall.op < (PAGE_SIZE >> 5)) {
                        long ign1, ign2, ign3;
                        __asm__ __volatile__ (
                                "movq %8,%%r10; movq %9,%%r8;"
-                               "shlq $5,%%rax ;"
+                               "shll $5,%%eax ;"
                                "addq $hypercall_page,%%rax ;"
                                "call *%%rax"
                                : "=a" (ret), "=D" (ign1),
                                  "=S" (ign2), "=d" (ign3)
-                               : "0" ((unsigned long)hypercall.op), 
-                               "1" ((unsigned long)hypercall.arg[0]), 
-                               "2" ((unsigned long)hypercall.arg[1]),
-                               "3" ((unsigned long)hypercall.arg[2]), 
-                               "g" ((unsigned long)hypercall.arg[3]),
-                               "g" ((unsigned long)hypercall.arg[4])
+                               : "0" ((unsigned int)hypercall.op),
+                               "1" (hypercall.arg[0]),
+                               "2" (hypercall.arg[1]),
+                               "3" (hypercall.arg[2]),
+                               "g" (hypercall.arg[3]),
+                               "g" (hypercall.arg[4])
                                : "r8", "r10", "memory" );
                }
 #elif defined (__ia64__)
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Fri Nov 10 
11:11:04 2006 -0700
@@ -30,13 +30,16 @@
  * IN THE SOFTWARE.
  */
 
-#include <asm/hypervisor.h>
-#include <xen/evtchn.h>
 #include <linux/wait.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <linux/ptrace.h>
+#include <xen/evtchn.h>
 #include <xen/xenbus.h>
+
+#include <asm/hypervisor.h>
+
 #include "xenbus_comms.h"
 
 #ifdef HAVE_XEN_PLATFORM_COMPAT_H
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h       Thu Nov 
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h       Fri Nov 
10 11:11:04 2006 -0700
@@ -27,7 +27,6 @@ extern unsigned long __FIXADDR_TOP;
 #include <asm/acpi.h>
 #include <asm/apicdef.h>
 #include <asm/page.h>
-#include <xen/gnttab.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
 #include <asm/kmap_types.h>
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h    Thu Nov 
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h    Fri Nov 
10 11:11:04 2006 -0700
@@ -260,6 +260,8 @@ HYPERVISOR_event_channel_op(
        int cmd, void *arg)
 {
        int rc = _hypercall2(int, event_channel_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
        if (unlikely(rc == -ENOSYS)) {
                struct evtchn_op op;
                op.cmd = cmd;
@@ -267,6 +269,8 @@ HYPERVISOR_event_channel_op(
                rc = _hypercall1(int, event_channel_op_compat, &op);
                memcpy(arg, &op.u, sizeof(op.u));
        }
+#endif
+
        return rc;
 }
 
@@ -296,6 +300,8 @@ HYPERVISOR_physdev_op(
        int cmd, void *arg)
 {
        int rc = _hypercall2(int, physdev_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
        if (unlikely(rc == -ENOSYS)) {
                struct physdev_op op;
                op.cmd = cmd;
@@ -303,6 +309,8 @@ HYPERVISOR_physdev_op(
                rc = _hypercall1(int, physdev_op_compat, &op);
                memcpy(arg, &op.u, sizeof(op.u));
        }
+#endif
+
        return rc;
 }
 
@@ -350,9 +358,11 @@ HYPERVISOR_suspend(
        int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
                             &sched_shutdown, srec);
 
+#ifdef CONFIG_XEN_COMPAT_030002
        if (rc == -ENOSYS)
                rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
                                 SHUTDOWN_suspend, srec);
+#endif
 
        return rc;
 }
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h   Thu Nov 
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h   Fri Nov 
10 11:11:04 2006 -0700
@@ -131,8 +131,10 @@ HYPERVISOR_yield(
 {
        int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
 
+#ifdef CONFIG_XEN_COMPAT_030002
        if (rc == -ENOSYS)
                rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
+#endif
 
        return rc;
 }
@@ -143,8 +145,10 @@ HYPERVISOR_block(
 {
        int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
 
+#ifdef CONFIG_XEN_COMPAT_030002
        if (rc == -ENOSYS)
                rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
+#endif
 
        return rc;
 }
@@ -159,8 +163,10 @@ HYPERVISOR_shutdown(
 
        int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
 
+#ifdef CONFIG_XEN_COMPAT_030002
        if (rc == -ENOSYS)
                rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
+#endif
 
        return rc;
 }
@@ -177,8 +183,10 @@ HYPERVISOR_poll(
        set_xen_guest_handle(sched_poll.ports, ports);
 
        rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
+#ifdef CONFIG_XEN_COMPAT_030002
        if (rc == -ENOSYS)
                rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
+#endif
 
        return rc;
 }
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Thu Nov 
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Fri Nov 
10 11:11:04 2006 -0700
@@ -56,15 +56,15 @@ static void __init machine_specific_arch
        struct xen_machphys_mapping mapping;
        unsigned long machine_to_phys_nr_ents;
        struct xen_platform_parameters pp;
-       struct callback_register event = {
+       static struct callback_register __initdata event = {
                .type = CALLBACKTYPE_event,
                .address = { __KERNEL_CS, (unsigned long)hypervisor_callback },
        };
-       struct callback_register failsafe = {
+       static struct callback_register __initdata failsafe = {
                .type = CALLBACKTYPE_failsafe,
                .address = { __KERNEL_CS, (unsigned long)failsafe_callback },
        };
-       struct callback_register nmi_cb = {
+       static struct callback_register __initdata nmi_cb = {
                .type = CALLBACKTYPE_nmi,
                .address = { __KERNEL_CS, (unsigned long)nmi },
        };
@@ -72,19 +72,24 @@ static void __init machine_specific_arch
        ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
        if (ret == 0)
                ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
+#ifdef CONFIG_XEN_COMPAT_030002
        if (ret == -ENOSYS)
                ret = HYPERVISOR_set_callbacks(
                        event.address.cs, event.address.eip,
                        failsafe.address.cs, failsafe.address.eip);
+#endif
        BUG_ON(ret);
 
        ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
+#ifdef CONFIG_XEN_COMPAT_030002
        if (ret == -ENOSYS) {
-               struct xennmi_callback cb;
+               static struct xennmi_callback __initdata cb = {
+                       .handler_address = (unsigned long)nmi
+               };
 
-               cb.handler_address = nmi_cb.address.eip;
                HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
        }
+#endif
 
        if (HYPERVISOR_xen_version(XENVER_platform_parameters,
                                   &pp) == 0)
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Nov 02 12:43:04 
2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Fri Nov 10 11:11:04 
2006 -0700
@@ -283,6 +283,9 @@ static inline void exit_idle(void) {}
 #ifdef CONFIG_XEN
 #include <asm/xen/privop.h>
 #endif /* CONFIG_XEN */
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
 
 static inline unsigned long
 __HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Thu Nov 02 
12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Fri Nov 10 
11:11:04 2006 -0700
@@ -191,6 +191,22 @@ MULTI_grant_table_op(multicall_entry_t *
        mcl->args[2] = count;
 }
 
+/*
+ * for blktap.c
+ * int create_lookup_pte_addr(struct mm_struct *mm, 
+ *                            unsigned long address,
+ *                            uint64_t *ptep);
+ */
+#define create_lookup_pte_addr(mm, address, ptep)                      \
+       ({                                                              \
+               printk(KERN_EMERG                                       \
+                      "%s:%d "                                         \
+                      "create_lookup_pte_addr() isn't supported.\n",   \
+                      __func__, __LINE__);                             \
+               BUG();                                                  \
+               (-ENOSYS);                                              \
+       })
+
 // for debug
 asmlinkage int xprintk(const char *fmt, ...);
 #define xprintd(fmt, ...)      xprintk("%s:%d " fmt, __func__, __LINE__, \
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h     Thu Nov 
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/fixmap.h     Fri Nov 
10 11:11:04 2006 -0700
@@ -14,7 +14,6 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <asm/apicdef.h>
-#include <xen/gnttab.h>
 #include <asm/page.h>
 #include <asm/vsyscall.h>
 #include <asm/vsyscall32.h>
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h  Thu Nov 
02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h  Fri Nov 
10 11:11:04 2006 -0700
@@ -258,6 +258,8 @@ HYPERVISOR_event_channel_op(
        int cmd, void *arg)
 {
        int rc = _hypercall2(int, event_channel_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
        if (unlikely(rc == -ENOSYS)) {
                struct evtchn_op op;
                op.cmd = cmd;
@@ -265,6 +267,8 @@ HYPERVISOR_event_channel_op(
                rc = _hypercall1(int, event_channel_op_compat, &op);
                memcpy(arg, &op.u, sizeof(op.u));
        }
+#endif
+
        return rc;
 }
 
@@ -294,6 +298,8 @@ HYPERVISOR_physdev_op(
        int cmd, void *arg)
 {
        int rc = _hypercall2(int, physdev_op, cmd, arg);
+
+#ifdef CONFIG_XEN_COMPAT_030002
        if (unlikely(rc == -ENOSYS)) {
                struct physdev_op op;
                op.cmd = cmd;
@@ -301,6 +307,8 @@ HYPERVISOR_physdev_op(
                rc = _hypercall1(int, physdev_op_compat, &op);
                memcpy(arg, &op.u, sizeof(op.u));
        }
+#endif
+
        return rc;
 }
 
@@ -351,9 +359,11 @@ HYPERVISOR_suspend(
        int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
                             &sched_shutdown, srec);
 
+#ifdef CONFIG_XEN_COMPAT_030002
        if (rc == -ENOSYS)
                rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
                                 SHUTDOWN_suspend, srec);
+#endif
 
        return rc;
 }
diff -r 11b718eb22c9 -r ebed72718263 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h        
Thu Nov 02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h        
Fri Nov 10 11:11:04 2006 -0700
@@ -15,20 +15,20 @@ static void __init machine_specific_arch
 static void __init machine_specific_arch_setup(void)
 {
        int ret;
-       struct callback_register event = {
+       static struct callback_register __initdata event = {
                .type = CALLBACKTYPE_event,
                .address = (unsigned long) hypervisor_callback,
        };
-       struct callback_register failsafe = {
+       static struct callback_register __initdata failsafe = {
                .type = CALLBACKTYPE_failsafe,
                .address = (unsigned long)failsafe_callback,
        };
-       struct callback_register syscall = {
+       static struct callback_register __initdata syscall = {
                .type = CALLBACKTYPE_syscall,
                .address = (unsigned long)system_call,
        };
 #ifdef CONFIG_X86_LOCAL_APIC
-       struct callback_register nmi_cb = {
+       static struct callback_register __initdata nmi_cb = {
                .type = CALLBACKTYPE_nmi,
                .address = (unsigned long)nmi,
        };
@@ -39,20 +39,25 @@ static void __init machine_specific_arch
                ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
        if (ret == 0)
                ret = HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
+#ifdef CONFIG_XEN_COMPAT_030002
        if (ret == -ENOSYS)
                ret = HYPERVISOR_set_callbacks(
                        event.address,
                        failsafe.address,
                        syscall.address);
+#endif
        BUG_ON(ret);
 
 #ifdef CONFIG_X86_LOCAL_APIC
        ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
+#ifdef CONFIG_XEN_COMPAT_030002
        if (ret == -ENOSYS) {
-               struct xennmi_callback cb;
+               static struct xennmi_callback __initdata cb = {
+                       .handler_address = (unsigned long)nmi
+               };
 
-               cb.handler_address = nmi_cb.address;
                HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
        }
 #endif
+#endif
 }
diff -r 11b718eb22c9 -r ebed72718263 linux-2.6-xen-sparse/include/xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/xen/gnttab.h Thu Nov 02 12:43:04 2006 -0700
+++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Fri Nov 10 11:11:04 2006 -0700
@@ -39,6 +39,7 @@
 
 #include <linux/config.h>
 #include <asm/hypervisor.h>
+#include <asm/maddr.h> /* maddr_t */
 #include <xen/interface/grant_table.h>
 #include <xen/features.h>
 
@@ -118,7 +119,7 @@ int gnttab_resume(void);
 int gnttab_resume(void);
 
 static inline void
-gnttab_set_map_op(struct gnttab_map_grant_ref *map, unsigned long addr,
+gnttab_set_map_op(struct gnttab_map_grant_ref *map, maddr_t addr,
                  uint32_t flags, grant_ref_t ref, domid_t domid)
 {
        if (flags & GNTMAP_contains_pte)
@@ -134,7 +135,7 @@ gnttab_set_map_op(struct gnttab_map_gran
 }
 
 static inline void
-gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, unsigned long addr,
+gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, maddr_t addr,
                    uint32_t flags, grant_handle_t handle)
 {
        if (flags & GNTMAP_contains_pte)
diff -r 11b718eb22c9 -r ebed72718263 patches/linux-2.6.16.29/series
--- a/patches/linux-2.6.16.29/series    Thu Nov 02 12:43:04 2006 -0700
+++ b/patches/linux-2.6.16.29/series    Fri Nov 10 11:11:04 2006 -0700
@@ -10,6 +10,7 @@ net-gso-2-checksum-fix.patch
 net-gso-2-checksum-fix.patch
 net-gso-3-fix-errorcheck.patch
 net-gso-4-kill-warnon.patch
+net-gso-5-rcv-mss.patch
 pci-mmconfig-fix-from-2.6.17.patch
 pmd-shared.patch
 rcu_needs_cpu.patch
diff -r 11b718eb22c9 -r ebed72718263 
patches/linux-2.6.16.29/xenoprof-generic.patch
--- a/patches/linux-2.6.16.29/xenoprof-generic.patch    Thu Nov 02 12:43:04 
2006 -0700
+++ b/patches/linux-2.6.16.29/xenoprof-generic.patch    Fri Nov 10 11:11:04 
2006 -0700
@@ -1,6 +1,6 @@ diff -pruN ../orig-linux-2.6.16.29/drive
 diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c 
./drivers/oprofile/buffer_sync.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c     2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/buffer_sync.c   2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c     2006-11-06 
14:46:52.000000000 -0800
++++ ./drivers/oprofile/buffer_sync.c   2006-11-06 15:16:52.000000000 -0800
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -12,7 +12,27 @@ diff -pruN ../orig-linux-2.6.16.29/drive
   * This is the core of the buffer management. Each
   * CPU buffer is processed and entered into the
   * global event buffer. Such processing is necessary
-@@ -275,15 +279,31 @@ static void add_cpu_switch(int i)
+@@ -38,6 +42,7 @@ static cpumask_t marked_cpus = CPU_MASK_
+ static DEFINE_SPINLOCK(task_mortuary);
+ static void process_task_mortuary(void);
+ 
++static int cpu_current_domain[NR_CPUS];
+ 
+ /* Take ownership of the task struct and place it on the
+  * list for processing. Only after two full buffer syncs
+@@ -146,6 +151,11 @@ static void end_sync(void)
+ int sync_start(void)
+ {
+       int err;
++      int i;
++
++      for (i = 0; i < NR_CPUS; i++) {
++              cpu_current_domain[i] = COORDINATOR_DOMAIN;
++      }
+ 
+       start_cpu_work();
+ 
+@@ -275,15 +285,31 @@ static void add_cpu_switch(int i)
        last_cookie = INVALID_COOKIE;
  }
  
@@ -50,7 +70,7 @@ diff -pruN ../orig-linux-2.6.16.29/drive
  static void
  add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
  {
-@@ -348,9 +368,9 @@ static int add_us_sample(struct mm_struc
+@@ -348,9 +374,9 @@ static int add_us_sample(struct mm_struc
   * for later lookup from userspace.
   */
  static int
@@ -62,7 +82,7 @@ diff -pruN ../orig-linux-2.6.16.29/drive
                add_sample_entry(s->eip, s->event);
                return 1;
        } else if (mm) {
-@@ -496,10 +516,11 @@ void sync_buffer(int cpu)
+@@ -496,15 +522,21 @@ void sync_buffer(int cpu)
        struct mm_struct *mm = NULL;
        struct task_struct * new;
        unsigned long cookie = 0;
@@ -75,7 +95,17 @@ diff -pruN ../orig-linux-2.6.16.29/drive
  
        down(&buffer_sem);
   
-@@ -512,16 +533,18 @@ void sync_buffer(int cpu)
+       add_cpu_switch(cpu);
+ 
++      /* We need to assign the first samples in this CPU buffer to the
++         same domain that we were processing at the last sync_buffer */
++      if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
++              add_domain_switch(cpu_current_domain[cpu]);
++      }
+       /* Remember, only we can modify tail_pos */
+ 
+       available = get_slots(cpu_buf);
+@@ -512,16 +544,18 @@ void sync_buffer(int cpu)
        for (i = 0; i < available; ++i) {
                struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
   
@@ -99,7 +129,7 @@ diff -pruN ../orig-linux-2.6.16.29/drive
                        } else {
                                struct mm_struct * oldmm = mm;
  
-@@ -535,11 +558,16 @@ void sync_buffer(int cpu)
+@@ -535,11 +569,21 @@ void sync_buffer(int cpu)
                                add_user_ctx_switch(new, cookie);
                        }
                } else {
@@ -109,10 +139,15 @@ diff -pruN ../orig-linux-2.6.16.29/drive
 -                                      state = sb_bt_ignore;
 -                                      
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
 +                      if (domain_switch) {
++                              cpu_current_domain[cpu] = s->eip;
 +                              add_domain_switch(s->eip);
 +                              domain_switch = 0;
 +                      } else {
-+                              if (state >= sb_bt_start &&
++                              if (cpu_current_domain[cpu] !=
++                                  COORDINATOR_DOMAIN) {
++                                      add_sample_entry(s->eip, s->event);
++                              }
++                              else  if (state >= sb_bt_start &&
 +                                  !add_sample(mm, s, cpu_mode)) {
 +                                      if (state == sb_bt_start) {
 +                                              state = sb_bt_ignore;
@@ -121,9 +156,21 @@ diff -pruN ../orig-linux-2.6.16.29/drive
                                }
                        }
                }
+@@ -548,6 +592,11 @@ void sync_buffer(int cpu)
+       }
+       release_mm(mm);
+ 
++      /* We reset domain to COORDINATOR at each CPU switch */
++      if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
++              add_domain_switch(COORDINATOR_DOMAIN);
++      }
++
+       mark_done(cpu);
+ 
+       up(&buffer_sem);
 diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c 
./drivers/oprofile/cpu_buffer.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c      2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.c    2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c      2006-11-06 
14:46:52.000000000 -0800
++++ ./drivers/oprofile/cpu_buffer.c    2006-11-06 14:47:55.000000000 -0800
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -233,8 +280,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
   * This serves to avoid cpu buffer overflow, and makes sure
   * the task mortuary progresses
 diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h 
./drivers/oprofile/cpu_buffer.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h      2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.h    2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h      2006-11-06 
14:46:52.000000000 -0800
++++ ./drivers/oprofile/cpu_buffer.h    2006-11-06 14:47:55.000000000 -0800
 @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
        volatile unsigned long tail_pos;
        unsigned long buffer_size;
@@ -258,8 +305,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
  
  #endif /* OPROFILE_CPU_BUFFER_H */
 diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h 
./drivers/oprofile/event_buffer.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h    2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/event_buffer.h  2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h    2006-11-06 
14:46:52.000000000 -0800
++++ ./drivers/oprofile/event_buffer.h  2006-11-06 14:47:55.000000000 -0800
 @@ -29,15 +29,20 @@ void wake_up_buffer_waiter(void);
  #define CPU_SWITCH_CODE               2
  #define COOKIE_SWITCH_CODE            3
@@ -283,8 +330,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
  void add_event_entry(unsigned long data);
   
 diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c 
./drivers/oprofile/oprof.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c   2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/oprof.c 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c   2006-11-06 
14:46:52.000000000 -0800
++++ ./drivers/oprofile/oprof.c 2006-11-06 14:47:55.000000000 -0800
 @@ -5,6 +5,10 @@
   * @remark Read the file COPYING
   *
@@ -339,8 +386,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
  {
        int err;
 diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h 
./drivers/oprofile/oprof.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h   2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/oprof.h 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h   2006-11-06 
14:46:52.000000000 -0800
++++ ./drivers/oprofile/oprof.h 2006-11-06 14:47:55.000000000 -0800
 @@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
  void oprofile_timer_init(struct oprofile_operations * ops);
  
@@ -351,8 +398,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
   
  #endif /* OPROF_H */
 diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c 
./drivers/oprofile/oprofile_files.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c  2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/oprofile/oprofile_files.c        2006-09-19 14:06:05.000000000 
+0100
+--- ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c  2006-11-06 
14:46:52.000000000 -0800
++++ ./drivers/oprofile/oprofile_files.c        2006-11-06 14:47:55.000000000 
-0800
 @@ -5,15 +5,21 @@
   * @remark Read the file COPYING
   *
@@ -581,8 +628,8 @@ diff -pruN ../orig-linux-2.6.16.29/drive
        oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
        oprofilefs_create_ulong(sb, root, "buffer_watershed", 
&fs_buffer_watershed);
 diff -pruN ../orig-linux-2.6.16.29/include/linux/oprofile.h 
./include/linux/oprofile.h
---- ../orig-linux-2.6.16.29/include/linux/oprofile.h   2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/linux/oprofile.h 2006-09-19 14:06:05.000000000 +0100
+--- ../orig-linux-2.6.16.29/include/linux/oprofile.h   2006-11-06 
14:46:42.000000000 -0800
++++ ./include/linux/oprofile.h 2006-11-06 14:47:55.000000000 -0800
 @@ -16,6 +16,8 @@
  #include <linux/types.h>
  #include <linux/spinlock.h>
diff -r 11b718eb22c9 -r ebed72718263 tools/Makefile
--- a/tools/Makefile    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/Makefile    Fri Nov 10 11:11:04 2006 -0700
@@ -18,6 +18,7 @@ SUBDIRS-y += xenstat
 SUBDIRS-y += xenstat
 SUBDIRS-y += libaio
 SUBDIRS-y += blktap
+SUBDIRS-y += libfsimage
 
 # These don't cross-compile
 ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/drivers/blktapctrl.c Fri Nov 10 11:11:04 2006 -0700
@@ -607,9 +607,11 @@ int main(int argc, char *argv[])
        struct xs_handle *h;
        struct pollfd  pfd[NUM_POLL_FDS];
        pid_t process;
+       char buf[128];
 
        __init_blkif();
-       openlog("BLKTAPCTRL", LOG_CONS|LOG_ODELAY, LOG_DAEMON);
+       snprintf(buf, sizeof(buf), "BLKTAPCTRL[%d]", getpid());
+       openlog(buf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);
        daemon(0,0);
 
        print_drivers();
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/drivers/tapdisk.c    Fri Nov 10 11:11:04 2006 -0700
@@ -381,7 +381,6 @@ static inline int write_rsp_to_ring(stru
        
        rsp_d = RING_GET_RESPONSE(&info->fe_ring, info->fe_ring.rsp_prod_pvt);
        memcpy(rsp_d, rsp, sizeof(blkif_response_t));
-       wmb();
        info->fe_ring.rsp_prod_pvt++;
        
        return 0;
@@ -562,12 +561,14 @@ int main(int argc, char *argv[])
        fd_list_entry_t *ptr;
        struct tap_disk *drv;
        struct td_state *s;
+       char openlogbuf[128];
        
        if (argc != 3) usage();
 
        daemonize();
 
-       openlog("TAPDISK", LOG_CONS|LOG_ODELAY, LOG_DAEMON);
+       snprintf(openlogbuf, sizeof(openlogbuf), "TAPDISK[%d]", getpid());
+       openlog(openlogbuf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);
        /*Setup signal handlers*/
        signal (SIGBUS, sig_handler);
        signal (SIGINT, sig_handler);
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/drivers/tapdisk.h    Fri Nov 10 11:11:04 2006 -0700
@@ -61,7 +61,6 @@
 
 /* Things disks need to know about, these should probably be in a higher-level
  * header. */
-#define MAX_REQUESTS            64
 #define MAX_SEGMENTS_PER_REQ    11
 #define SECTOR_SHIFT             9
 #define DEFAULT_SECTOR_SIZE    512
diff -r 11b718eb22c9 -r ebed72718263 tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/blktap/lib/blktaplib.h      Fri Nov 10 11:11:04 2006 -0700
@@ -41,7 +41,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, getpagesize())
+#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, XC_PAGE_SIZE)
 
 /* size of the extra VMA area to map in attached pages. */
 #define BLKTAP_VMA_PAGES BLK_RING_SIZE
@@ -74,10 +74,10 @@ static inline int BLKTAP_MODE_VALID(unsi
                ( arg == BLKTAP_MODE_INTERPOSE    ) );
 }
 
-#define MAX_REQUESTS            64
+#define MAX_REQUESTS            BLK_RING_SIZE
 
 #define BLKTAP_IOCTL_KICK 1
-#define MAX_PENDING_REQS 64
+#define MAX_PENDING_REQS       BLK_RING_SIZE
 #define BLKTAP_DEV_DIR   "/dev/xen"
 #define BLKTAP_DEV_NAME  "blktap"
 #define BLKTAP_DEV_MINOR 0
@@ -199,7 +199,6 @@ int xs_fire_next_watch(struct xs_handle 
 
 
 /* Abitrary values, must match the underlying driver... */
-#define MAX_PENDING_REQS 64
 #define MAX_TAP_DEV 100
 
 /* Accessing attached data page mappings */
diff -r 11b718eb22c9 -r ebed72718263 tools/console/Makefile
--- a/tools/console/Makefile    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/console/Makefile    Fri Nov 10 11:11:04 2006 -0700
@@ -5,7 +5,7 @@ DAEMON_INSTALL_DIR = /usr/sbin
 DAEMON_INSTALL_DIR = /usr/sbin
 CLIENT_INSTALL_DIR = /usr/$(LIBDIR)/xen/bin
 
-CFLAGS  += -Werror -g
+CFLAGS  += -Werror
 
 CFLAGS  += -I $(XEN_LIBXC)
 CFLAGS  += -I $(XEN_XENSTORE)
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/blktap
--- a/tools/examples/blktap     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/blktap     Fri Nov 10 11:11:04 2006 -0700
@@ -4,12 +4,26 @@
 
 dir=$(dirname "$0")
 . "$dir/xen-hotplug-common.sh"
+. "$dir/block-common.sh"
 
 findCommand "$@"
 
-if [ "$command" == 'add' ]
+t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
+if [ -n "$t" ]
 then
-  success
+    p=$(xenstore_read "$XENBUS_PATH/params")
+    # if we have a ':', chew from head including :
+    if echo $p | grep -q \:
+    then
+        p=${p#*:}
+    fi
+fi
+file=$(readlink -f "$p") || ebusy "$p does not exist."
+
+if [ "$command" = 'add' ]
+then
+    [ -e "$file" ] || { ebusy $file does not exist; }
+    success
 fi
 
 exit 0
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/block
--- a/tools/examples/block      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/block      Fri Nov 10 11:11:04 2006 -0700
@@ -68,7 +68,7 @@ check_sharing()
   local devmm=$(device_major_minor "$dev")
   local file
 
-  if [ "$mode" == 'w' ]
+  if [ "$mode" = 'w' ]
   then
     toskip="^$"
   else
@@ -81,7 +81,7 @@ check_sharing()
     then
       local d=$(device_major_minor "$file")
 
-      if [ "$d" == "$devmm" ]
+      if [ "$d" = "$devmm" ]
       then
         echo 'local'
         return
@@ -96,9 +96,9 @@ check_sharing()
     do
       d=$(xenstore_read_default "$base_path/$dom/$dev/physical-device" "")
 
-      if [ "$d" == "$devmm" ]
+      if [ "$d" = "$devmm" ]
       then
-        if [ "$mode" == 'w' ]
+        if [ "$mode" = 'w' ]
         then
           if ! same_vm $dom
           then
@@ -109,7 +109,7 @@ check_sharing()
           local m=$(xenstore_read "$base_path/$dom/$dev/mode")
           m=$(canonicalise_mode "$m")
 
-          if [ "$m" == 'w' ]
+          if [ "$m" = 'w' ]
           then
             if ! same_vm $dom
             then
@@ -138,7 +138,7 @@ same_vm()
   local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm"         \
                   "$FRONTEND_UUID")
 
-  [ "$FRONTEND_UUID" == "$othervm" ]
+  [ "$FRONTEND_UUID" = "$othervm" ]
 }
 
 
@@ -153,7 +153,7 @@ check_device_sharing()
   local mode=$(canonicalise_mode "$2")
   local result
 
-  if [ "$mode" == '!' ]
+  if [ "x$mode" = 'x!' ]
   then
     return 0
   fi
@@ -202,7 +202,7 @@ do_ebusy()
   local mode="$2"
   local result="$3"
 
-  if [ "$result" == 'guest' ]
+  if [ "$result" = 'guest' ]
   then
     dom='a guest '
     when='now'
@@ -211,7 +211,7 @@ do_ebusy()
     when='by a guest'
   fi
 
-  if [ "$mode" == 'w' ]
+  if [ "$mode" = 'w' ]
   then
     m1=''
     m2=''
@@ -266,7 +266,7 @@ case "$command" in
 
         claim_lock "block"
 
-        if [ "$mode" == 'w' ] && ! stat "$file" -c %A | grep -q w
+        if [ "$mode" = 'w' ] && ! stat "$file" -c %A | grep -q w
         then
           release_lock "block"
           ebusy \
@@ -287,7 +287,7 @@ mount it read-write in a guest domain."
           if [ "$f" ]
           then
             # $dev is in use.  Check sharing.
-            if [ "$mode" == '!' ]
+            if [ "x$mode" = 'x!' ]
             then
               continue
             fi
@@ -307,7 +307,7 @@ mount it read-write in a guest domain."
                 do
                   d=$(xenstore_read_default \
                         "$XENBUS_BASE_PATH/$dom/$domdev/node" "")
-                  if [ "$d" == "$dev" ]
+                  if [ "$d" = "$dev" ]
                   then
                     f=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$domdev/params")
                     found=1
@@ -347,7 +347,7 @@ mount it read-write in a guest domain."
             f=$(readlink -f "$f" || echo $(dirname "$file")/$(basename "$f"))
 
 
-            if [ "$f" == "$file" ]
+            if [ "$f" = "$file" ]
             then
               check_file_sharing "$file" "$dev" "$mode"
             fi
@@ -355,14 +355,14 @@ mount it read-write in a guest domain."
             # $dev is not in use, so we'll remember it for use later; we want
             # to finish the sharing check first.
 
-            if [ "$loopdev" == '' ]
+            if [ "$loopdev" = '' ]
             then
               loopdev="$dev"
             fi
           fi
         done
 
-        if [ "$loopdev" == '' ]
+        if [ "$loopdev" = '' ]
         then
           fatal 'Failed to find an unused loop device'
         fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/external-device-migrate
--- a/tools/examples/external-device-migrate    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/external-device-migrate    Fri Nov 10 11:11:04 2006 -0700
@@ -55,41 +55,27 @@ function evaluate_params()
 {
        local step host domname typ recover filename func stype
        stype=""
-       while [ 1 ]; do
-               if [ "$1" == "-step" ]; then
-                       shift
-                       step=$1
-               elif [ "$1" == "-host" ]; then
-                       shift
-                       host=$1
-               elif [ "$1" == "-domname" ]; then
-                       shift
-                       domname=$1
-               elif [ "$1" == "-type" ]; then
-                       shift
-                       typ=$1
-               elif [ "$1" == "-subtype" ]; then
-                       shift
-                       stype="_$1"
-               elif [ "$1" == "-recover" ]; then
-                       recover=1
-               elif [ "$1" == "-help" ]; then
-                       ext_dev_migrate_usage
-                       exit
-               else
-                       break
-               fi
-               shift
+       while [ $# -ge 1 ]; do
+               case "$1" in
+               -step)          step=$2; shift 2;;
+               -host)          host=$2; shift 2;;
+               -domname)       domname=$2; shift 2;;
+               -type)          type=$2; shift 2;;
+               -subtype)       subtype=$2; shift 2;;
+               -recover)       recover=1; shift;;
+               -help)          ext_dev_migrate_usage; exit 0;;
+               *)              break;;
+               esac
        done
 
-       if [ "$step"    == "" -o \
-            "$host"    == "" -o \
-            "$typ"     == "" -o \
-            "$domname" == "" ]; then
-               echo "Error: Parameter(s) missing (-step/-host/-type/-domname)"
-               echo ""
-               echo "$0 -help for usage."
-               exit
+       if [ "$step"    = "" -o \
+            "$host"    = "" -o \
+            "$typ"     = "" -o \
+            "$domname" = "" ]; then
+               echo "Error: Parameter(s) missing (-step/-host/-type/-domname)" 
1>&2
+               echo "" 1>&2
+               echo "$0 -help for usage." 1>&2
+               exit 1
        fi
 
        filename="$dir/$typ$stype-migration.sh"
@@ -99,7 +85,7 @@ function evaluate_params()
        fi
        . "$filename"
 
-       if [ "$recover" == "1" ]; then
+       if [ "$recover" = "1" ]; then
                func="$typ"_recover
                eval $func $host $domname $step $*
        else
@@ -108,4 +94,4 @@ function evaluate_params()
        fi
 }
 
-evaluate_params $*
+evaluate_params "$@"
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/vif-bridge Fri Nov 10 11:11:04 2006 -0700
@@ -61,7 +61,7 @@ handle_iptable
 handle_iptable
 
 log debug "Successful vif-bridge $command for $vif, bridge $bridge."
-if [ "$command" == "online" ]
+if [ "$command" = "online" ]
 then
   success
 fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/vif-nat
--- a/tools/examples/vif-nat    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/vif-nat    Fri Nov 10 11:11:04 2006 -0700
@@ -72,7 +72,7 @@ dotted_quad()
 }
 
 
-if [ "$ip" == "" ]
+if [ "$ip" = "" ]
 then
   ip=$(ip_from_dom)
 fi
@@ -152,7 +152,7 @@ handle_iptable
 handle_iptable
 
 log debug "Successful vif-nat $command for $vif."
-if [ "$command" == "online" ]
+if [ "$command" = "online" ]
 then
   success
 fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/vif-route
--- a/tools/examples/vif-route  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/vif-route  Fri Nov 10 11:11:04 2006 -0700
@@ -50,7 +50,7 @@ handle_iptable
 handle_iptable
 
 log debug "Successful vif-route $command for $vif."
-if [ "$command" == "online" ]
+if [ "$command" = "online" ]
 then
   success
 fi
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/xend-config.sxp    Fri Nov 10 11:11:04 2006 -0700
@@ -51,7 +51,7 @@
 # regular expressions will be accepted.
 #
 # For example:
-#  (xend-relocation-hosts-allow '^localhost$ ^.*\.example\.org$')
+#  (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$')
 #
 #(xend-relocation-hosts-allow '')
 (xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
diff -r 11b718eb22c9 -r ebed72718263 tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/examples/xmexample.hvm      Fri Nov 10 11:11:04 2006 -0700
@@ -47,9 +47,6 @@ name = "ExampleHVMDomain"
 
 # enable/disable HVM guest ACPI, default=0 (disabled)
 #acpi=0
-
-# enable/disable HVM guest APIC, default=0 (disabled)
-#apic=0
 
 # List of which CPUS this domain is allowed to use, default Xen picks
 #cpus = ""         # leave to Xen to pick
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/Makefile
--- a/tools/firmware/Makefile   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/Makefile   Fri Nov 10 11:11:04 2006 -0700
@@ -9,7 +9,6 @@ SUBDIRS :=
 SUBDIRS :=
 SUBDIRS += rombios
 SUBDIRS += vgabios
-SUBDIRS += acpi
 SUBDIRS += vmxassist
 SUBDIRS += hvmloader
 
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/Makefile Fri Nov 10 11:11:04 2006 -0700
@@ -40,11 +40,14 @@ CFLAGS  += $(DEFINES) -I. $(XENINC) -fno
 CFLAGS  += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
 LDFLAGS  = -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR)
 
-SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c
+SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c acpi_utils.c
 OBJS = $(patsubst %.c,%.o,$(SRCS))
 
 .PHONY: all
 all: hvmloader
+
+acpi/acpi.bin:
+       $(MAKE) -C acpi
 
 hvmloader: roms.h $(SRCS)
        $(CC) $(CFLAGS) -c $(SRCS)
@@ -52,15 +55,15 @@ hvmloader: roms.h $(SRCS)
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
-roms.h:        ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin 
../acpi/acpi.bin
+roms.h:        ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin 
acpi/acpi.bin
        sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
        sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
        sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
>> roms.h
        sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
-       sh ./mkhex acpi ../acpi/acpi.bin >> roms.h
+       sh ./mkhex acpi acpi/acpi.bin >> roms.h
 
 .PHONY: clean
 clean:
        rm -f roms.h acpi.h
        rm -f hvmloader hvmloader.tmp hvmloader.o $(OBJS)
-
+       $(MAKE) -C acpi clean
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/acpi_madt.c      Fri Nov 10 11:11:04 2006 -0700
@@ -18,9 +18,9 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
 
-#include "../acpi/acpi2_0.h"
-#include "../acpi/acpi_madt.h"
+#include "acpi/acpi2_0.h"
 #include "util.h"
+#include "acpi_utils.h"
 #include <xen/hvm/hvm_info_table.h>
 
 #define NULL ((void*)0)
@@ -29,160 +29,134 @@ static struct hvm_info_table *table = NU
 
 static int validate_hvm_info(struct hvm_info_table *t)
 {
-       char signature[] = "HVM INFO";
-       uint8_t *ptr = (uint8_t *)t;
-       uint8_t sum = 0;
-       int i;
+    char signature[] = "HVM INFO";
+    uint8_t *ptr = (uint8_t *)t;
+    uint8_t sum = 0;
+    int i;
 
-       /* strncmp(t->signature, "HVM INFO", 8) */
-       for (i = 0; i < 8; i++) {
-               if (signature[i] != t->signature[i]) {
-                       puts("Bad hvm info signature\n");
-                       return 0;
-               }
-       }
+    /* strncmp(t->signature, "HVM INFO", 8) */
+    for (i = 0; i < 8; i++) {
+        if (signature[i] != t->signature[i]) {
+            puts("Bad hvm info signature\n");
+            return 0;
+        }
+    }
 
-       for (i = 0; i < t->length; i++)
-               sum += ptr[i];
+    for (i = 0; i < t->length; i++)
+        sum += ptr[i];
 
-       return (sum == 0);
+    return (sum == 0);
 }
 
 /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
 struct hvm_info_table *
 get_hvm_info_table(void)
 {
-       struct hvm_info_table *t;
+    struct hvm_info_table *t;
 
-       if (table != NULL)
-               return table;
+    if (table != NULL)
+        return table;
 
-       t = (struct hvm_info_table *)HVM_INFO_PADDR;
+    t = (struct hvm_info_table *)HVM_INFO_PADDR;
 
-       if (!validate_hvm_info(t)) {
-               puts("Bad hvm info table\n");
-               return NULL;
-       }
+    if (!validate_hvm_info(t)) {
+        puts("Bad hvm info table\n");
+        return NULL;
+    }
 
-       table = t;
+    table = t;
 
-       return table;
+    return table;
 }
 
 int
 get_vcpu_nr(void)
 {
-       struct hvm_info_table *t = get_hvm_info_table();
-       return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
+    struct hvm_info_table *t = get_hvm_info_table();
+    return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
 }
 
 int
 get_acpi_enabled(void)
 {
-       struct hvm_info_table *t = get_hvm_info_table();
-       return (t ? t->acpi_enabled : 0); /* default no acpi */
+    struct hvm_info_table *t = get_hvm_info_table();
+    return (t ? t->acpi_enabled : 0); /* default no acpi */
 }
 
 
 static void *
 acpi_madt_get_madt(unsigned char *acpi_start)
 {
-       ACPI_2_0_RSDP *rsdp=NULL;
-       ACPI_2_0_RSDT *rsdt=NULL;
-       ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
+    struct acpi_20_rsdt *rsdt;
+    struct acpi_20_madt *madt;
 
-       rsdp = (ACPI_2_0_RSDP *)(acpi_start + sizeof(ACPI_2_0_FACS));
-       if (rsdp->Signature != ACPI_2_0_RSDP_SIGNATURE) {
-               puts("Bad RSDP signature\n");
-               return NULL;
-       }
+    rsdt = acpi_rsdt_get(acpi_start);
+    if (rsdt == NULL)
+        return NULL;
 
-       rsdt= (ACPI_2_0_RSDT *)
-               (acpi_start + rsdp->RsdtAddress - ACPI_PHYSICAL_ADDRESS);
-       if (rsdt->Header.Signature != ACPI_2_0_RSDT_SIGNATURE) {
-               puts("Bad RSDT signature\n");
-               return NULL;
-       }
+    madt = (struct acpi_20_madt *)(acpi_start + rsdt->entry[1] -
+                                   ACPI_PHYSICAL_ADDRESS);
+    if (madt->header.header.signature != ACPI_2_0_MADT_SIGNATURE) {
+        puts("Bad MADT signature \n");
+        return NULL;
+    }
 
-       madt = (ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *)
-               ( acpi_start+ rsdt->Entry[1] - ACPI_PHYSICAL_ADDRESS);
-       if (madt->Header.Header.Signature !=
-           ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
-               puts("Bad MADT signature \n");
-               return NULL;
-       }
-
-       return madt;
-}
-
-static void
-set_checksum(void *start, int checksum_offset, int len)
-{
-       unsigned char sum = 0;
-       unsigned char *ptr;
-
-       ptr = start;
-       ptr[checksum_offset] = 0;
-       while (len--)
-               sum += *ptr++;
-
-       ptr = start;
-       ptr[checksum_offset] = -sum;
+    return madt;
 }
 
 static int
 acpi_madt_set_local_apics(
-       int nr_vcpu,
-       ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
+    int nr_vcpu,
+    struct acpi_20_madt *madt)
 {
-       int i;
+    int i;
 
-       if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
-               return -1;
+    if ((nr_vcpu > MAX_VIRT_CPUS) || (nr_vcpu < 0) || !madt)
+        return -1;
 
-       for (i = 0; i < nr_vcpu; i++) {
-               madt->LocalApic[i].Type            = ACPI_PROCESSOR_LOCAL_APIC;
-               madt->LocalApic[i].Length          = sizeof 
(ACPI_LOCAL_APIC_STRUCTURE);
-               madt->LocalApic[i].AcpiProcessorId = i;
-               madt->LocalApic[i].ApicId          = i;
-               madt->LocalApic[i].Flags           = 1;
-       }
+    for (i = 0; i < nr_vcpu; i++) {
+        madt->lapic[i].type    = ACPI_PROCESSOR_LOCAL_APIC;
+        madt->lapic[i].length  = sizeof(struct acpi_20_madt_lapic);
+        madt->lapic[i].acpi_processor_id = i;
+        madt->lapic[i].apic_id = i;
+        madt->lapic[i].flags   = 1;
+    }
 
-       madt->Header.Header.Length =
-               sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
-               (MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
+    madt->header.header.length =
+        sizeof(struct acpi_20_madt) -
+        (MAX_VIRT_CPUS - nr_vcpu) * sizeof(struct acpi_20_madt_lapic);
 
-       return 0;
+    return 0;
 }
 
 #define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
 
 int acpi_madt_update(unsigned char *acpi_start)
 {
-       int rc;
-       ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt;
+    int rc;
+    struct acpi_20_madt *madt;
 
-       madt = acpi_madt_get_madt(acpi_start);
-       if (!madt)
-               return -1;
+    madt = acpi_madt_get_madt(acpi_start);
+    if (!madt)
+        return -1;
 
-       rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
-       if (rc != 0)
-               return rc;
+    rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
+    if (rc != 0)
+        return rc;
 
-       set_checksum(
-               madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
-               madt->Header.Header.Length);
+    set_checksum(
+        madt, FIELD_OFFSET(struct acpi_header, checksum),
+        madt->header.header.length);
 
-       return 0;
+    return 0;
 }
 
 /*
  * Local variables:
- *  c-file-style: "linux"
- *  indent-tabs-mode: t
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
  * End:
  */
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/hvmloader.c      Fri Nov 10 11:11:04 2006 -0700
@@ -22,9 +22,10 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
 #include "roms.h"
-#include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include "acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
 #include "hypercall.h"
 #include "util.h"
+#include "acpi_utils.h"
 #include "smbios.h"
 #include <xen/version.h>
 #include <xen/hvm/params.h>
@@ -164,8 +165,6 @@ int
 int
 main(void)
 {
-       struct xen_hvm_param hvm_param;
-
        puts("HVM Loader\n");
 
        init_hypercalls();
@@ -176,10 +175,7 @@ main(void)
        puts("Loading ROMBIOS ...\n");
        memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
 
-       hvm_param.domid = DOMID_SELF;
-       hvm_param.index = HVM_PARAM_APIC_ENABLED;
-       if (!hypercall_hvm_op(HVMOP_get_param, &hvm_param) && hvm_param.value)
-               create_mp_tables();
+        create_mp_tables();
        
        if (cirrus_check()) {
                puts("Loading Cirrus VGABIOS ...\n");
@@ -195,12 +191,18 @@ main(void)
                puts("Loading ACPI ...\n");
                acpi_madt_update((unsigned char *) acpi);
                if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
+                       unsigned char *freemem = (unsigned char *)
+                                (ACPI_PHYSICAL_ADDRESS + sizeof(acpi));
                        /*
                         * Make sure acpi table does not overlap rombios
                         * currently acpi less than 8K will be OK.
                         */
                         memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi,
                                                                sizeof(acpi));
+                       acpi_update((unsigned char *)ACPI_PHYSICAL_ADDRESS,
+                                   sizeof(acpi),
+                                   (unsigned char *)0xF0000,
+                                   &freemem);
                }
        }
 
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/hvmloader/util.c   Fri Nov 10 11:11:04 2006 -0700
@@ -18,7 +18,7 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
 
-#include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include "acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
 #include "util.h"
 #include <stdint.h>
 
@@ -227,4 +227,5 @@ uuid_to_string(char *dest, uint8_t *uuid
                byte_to_hex(p, uuid[i]);
                p += 2;
        }
-}
+       *p = 0;
+}
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/vmxassist/setup.c  Fri Nov 10 11:11:04 2006 -0700
@@ -53,13 +53,10 @@ struct e820entry e820map[] = {
 struct e820entry e820map[] = {
        { 0x0000000000000000ULL, 0x000000000009F800ULL, E820_RAM },
        { 0x000000000009F800ULL, 0x0000000000000800ULL, E820_RESERVED },
-       { 0x00000000000A0000ULL, 0x0000000000020000ULL, E820_IO },
        { 0x00000000000C0000ULL, 0x0000000000040000ULL, E820_RESERVED },
        { 0x0000000000100000ULL, 0x0000000000000000ULL, E820_RAM },
-       { 0x0000000000000000ULL, 0x0000000000001000ULL, E820_SHARED_PAGE },
        { 0x0000000000000000ULL, 0x0000000000003000ULL, E820_NVS },
        { 0x0000000000003000ULL, 0x000000000000A000ULL, E820_ACPI },
-       { 0x00000000FEC00000ULL, 0x0000000001400000ULL, E820_IO },
 };
 #endif /* TEST */
 
diff -r 11b718eb22c9 -r ebed72718263 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/firmware/vmxassist/vm86.c   Fri Nov 10 11:11:04 2006 -0700
@@ -867,6 +867,18 @@ load_seg(unsigned long sel, uint32_t *ba
 }
 
 /*
+ * Emulate a protected mode segment load, falling back to clearing it if
+ * the descriptor was invalid.
+ */
+static void
+load_or_clear_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union 
vmcs_arbytes *arbytes)
+{
+       if (!load_seg(sel, base, limit, arbytes))
+               load_seg(0, base, limit, arbytes);          
+}
+
+
+/*
  * Transition to protected mode
  */
 static void
@@ -877,8 +889,6 @@ protected_mode(struct regs *regs)
        oldctx.eip = regs->eip;
        oldctx.esp = regs->uesp;
        oldctx.eflags = regs->eflags;
-
-       memset(&saved_rm_regs, 0, sizeof(struct regs));
 
        /* reload all segment registers */
        if (!load_seg(regs->cs, &oldctx.cs_base,
@@ -886,55 +896,16 @@ protected_mode(struct regs *regs)
                panic("Invalid %%cs=0x%x for protected mode\n", regs->cs);
        oldctx.cs_sel = regs->cs;
 
-       if (load_seg(regs->ves, &oldctx.es_base,
-                               &oldctx.es_limit, &oldctx.es_arbytes))
-               oldctx.es_sel = regs->ves;
-       else {
-               load_seg(0, &oldctx.es_base,
-                           &oldctx.es_limit, &oldctx.es_arbytes);
-               oldctx.es_sel = 0;
-               saved_rm_regs.ves = regs->ves;
-       }
-
-       if (load_seg(regs->uss, &oldctx.ss_base,
-                               &oldctx.ss_limit, &oldctx.ss_arbytes))
-               oldctx.ss_sel = regs->uss;
-       else {
-               load_seg(0, &oldctx.ss_base,
-                           &oldctx.ss_limit, &oldctx.ss_arbytes);
-               oldctx.ss_sel = 0;
-               saved_rm_regs.uss = regs->uss;
-       }
-
-       if (load_seg(regs->vds, &oldctx.ds_base,
-                               &oldctx.ds_limit, &oldctx.ds_arbytes))
-               oldctx.ds_sel = regs->vds;
-       else {
-               load_seg(0, &oldctx.ds_base,
-                           &oldctx.ds_limit, &oldctx.ds_arbytes);
-               oldctx.ds_sel = 0;
-               saved_rm_regs.vds = regs->vds;
-       }
-
-       if (load_seg(regs->vfs, &oldctx.fs_base,
-                               &oldctx.fs_limit, &oldctx.fs_arbytes))
-               oldctx.fs_sel = regs->vfs;
-       else {
-               load_seg(0, &oldctx.fs_base,
-                           &oldctx.fs_limit, &oldctx.fs_arbytes);
-               oldctx.fs_sel = 0;
-               saved_rm_regs.vfs = regs->vfs;
-       }
-
-       if (load_seg(regs->vgs, &oldctx.gs_base,
-                               &oldctx.gs_limit, &oldctx.gs_arbytes))
-               oldctx.gs_sel = regs->vgs;
-       else {
-               load_seg(0, &oldctx.gs_base,
-                           &oldctx.gs_limit, &oldctx.gs_arbytes);
-               oldctx.gs_sel = 0;
-               saved_rm_regs.vgs = regs->vgs;
-       }
+       load_or_clear_seg(oldctx.es_sel, &oldctx.es_base,
+                         &oldctx.es_limit, &oldctx.es_arbytes);
+       load_or_clear_seg(oldctx.ss_sel, &oldctx.ss_base,
+                         &oldctx.ss_limit, &oldctx.ss_arbytes);
+       load_or_clear_seg(oldctx.ds_sel, &oldctx.ds_base,
+                         &oldctx.ds_limit, &oldctx.ds_arbytes);
+       load_or_clear_seg(oldctx.fs_sel, &oldctx.fs_base,
+                         &oldctx.fs_limit, &oldctx.fs_arbytes);
+       load_or_clear_seg(oldctx.gs_sel, &oldctx.gs_base,
+                         &oldctx.gs_limit, &oldctx.gs_arbytes);
 
        /* initialize jump environment to warp back to protected mode */
        regs->cs = CODE_SELECTOR;
@@ -1022,6 +993,16 @@ set_mode(struct regs *regs, enum vm86_mo
        case VM86_REAL_TO_PROTECTED:
                if (mode == VM86_REAL) {
                        regs->eflags |= EFLAGS_TF;
+                       saved_rm_regs.vds = regs->vds;
+                       saved_rm_regs.ves = regs->ves;
+                       saved_rm_regs.vfs = regs->vfs;
+                       saved_rm_regs.vgs = regs->vgs;
+                       saved_rm_regs.uss = regs->uss;
+                       oldctx.ds_sel = 0;
+                       oldctx.es_sel = 0;
+                       oldctx.fs_sel = 0;
+                       oldctx.gs_sel = 0;
+                       oldctx.ss_sel = 0;
                        break;
                } else if (mode == VM86_REAL_TO_PROTECTED) {
                        break;
@@ -1282,6 +1263,10 @@ opcode(struct regs *regs)
                        else
                                regs->ves = pop16(regs);
                        TRACE((regs, regs->eip - eip, "pop %%es"));
+                       if (mode == VM86_REAL_TO_PROTECTED) {
+                               saved_rm_regs.ves = 0;
+                               oldctx.es_sel = regs->ves;
+                       }
                        return OPC_EMULATED;
 
                case 0x0F: /* two byte opcode */
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target       Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/Makefile.target       Fri Nov 10 11:11:04 2006 -0700
@@ -368,6 +368,7 @@ VL_OBJS+= piix4acpi.o
 VL_OBJS+= piix4acpi.o
 VL_OBJS+= xenstore.o
 VL_OBJS+= xen_platform.o
+VL_OBJS+= tpm_tis.o
 DEFINES += -DHAS_AUDIO
 endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/hw/ne2000.c   Fri Nov 10 11:11:04 2006 -0700
@@ -137,6 +137,7 @@ typedef struct NE2000State {
     uint8_t curpag;
     uint8_t mult[8]; /* multicast mask array */
     int irq;
+    int tainted;
     PCIDevice *pci_dev;
     VLANClientState *vc;
     uint8_t macaddr[6];
@@ -226,6 +227,27 @@ static int ne2000_can_receive(void *opaq
 
 #define MIN_BUF_SIZE 60
 
+static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr)
+{
+    addr <<= 8;
+    return addr < s->stop && addr >= s->start;
+}
+
+static inline int ne2000_check_state(NE2000State *s)
+{
+    if (!s->tainted)
+        return 0;
+
+    if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE)
+        return -EINVAL;
+
+    if (!ne2000_valid_ring_addr(s, s->curpag))
+        return -EINVAL;
+
+    s->tainted = 0;
+    return 0;
+}
+
 static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
 {
     NE2000State *s = opaque;
@@ -238,6 +260,12 @@ static void ne2000_receive(void *opaque,
 #if defined(DEBUG_NE2000)
     printf("NE2000: received len=%d\n", size);
 #endif
+
+    if (ne2000_check_state(s))
+        return;
+
+    if (!ne2000_valid_ring_addr(s, s->boundary))
+        return;
 
     if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
         return;
@@ -359,9 +387,11 @@ static void ne2000_ioport_write(void *op
         switch(offset) {
         case EN0_STARTPG:
             s->start = val << 8;
+            s->tainted = 1;
             break;
         case EN0_STOPPG:
             s->stop = val << 8;
+            s->tainted = 1;
             break;
         case EN0_BOUNDARY:
             s->boundary = val;
@@ -406,6 +436,7 @@ static void ne2000_ioport_write(void *op
             break;
         case EN1_CURPAG:
             s->curpag = val;
+            s->tainted = 1;
             break;
         case EN1_MULT ... EN1_MULT + 7:
             s->mult[offset - EN1_MULT] = val;
@@ -509,7 +540,7 @@ static inline void ne2000_mem_writel(NE2
 {
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 || 
-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
         cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
     }
 }
@@ -539,7 +570,7 @@ static inline uint32_t ne2000_mem_readl(
 {
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 || 
-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
         return le32_to_cpupu((uint32_t *)(s->mem + addr));
     } else {
         return 0xffffffff;
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/hw/pc.c       Fri Nov 10 11:11:04 2006 -0700
@@ -875,6 +875,9 @@ static void pc_init1(uint64_t ram_size, 
         }
     }
 
+    if (has_tpm_device())
+        tpm_tis_init(&pic_set_irq_new, isa_pic, 11);
+
     kbd_init();
     DMA_init(0);
 #ifdef HAS_AUDIO
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/hw/serial.c   Fri Nov 10 11:11:04 2006 -0700
@@ -93,6 +93,15 @@ struct SerialState {
     int last_break_enable;
     target_ulong base;
     int it_shift;
+
+    /*
+     * If a character transmitted via UART cannot be written to its
+     * destination immediately we remember it here and retry a few times via
+     * a polling timer.
+     */
+    int write_retries;
+    char write_chr;
+    QEMUTimer *write_retry_timer;
 };
 
 static void serial_update_irq(SerialState *s)
@@ -204,10 +213,32 @@ static void serial_get_token(void)
     tokens_avail--;
 }
 
+static void serial_chr_write(void *opaque)
+{
+    SerialState *s = opaque;
+
+    qemu_del_timer(s->write_retry_timer);
+
+    /* Retry every 100ms for 300ms total. */
+    if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
+        if (s->write_retries++ >= 3)
+            printf("serial: write error\n");
+        else
+            qemu_mod_timer(s->write_retry_timer,
+                           qemu_get_clock(vm_clock) + ticks_per_sec / 10);
+        return;
+    }
+
+    /* Success: Notify guest that THR is empty. */
+    s->thr_ipending = 1;
+    s->lsr |= UART_LSR_THRE;
+    s->lsr |= UART_LSR_TEMT;
+    serial_update_irq(s);
+}
+
 static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     SerialState *s = opaque;
-    unsigned char ch;
     
     addr &= 7;
 #ifdef DEBUG_SERIAL
@@ -223,12 +254,9 @@ static void serial_ioport_write(void *op
             s->thr_ipending = 0;
             s->lsr &= ~UART_LSR_THRE;
             serial_update_irq(s);
-            ch = val;
-            qemu_chr_write(s->chr, &ch, 1);
-            s->thr_ipending = 1;
-            s->lsr |= UART_LSR_THRE;
-            s->lsr |= UART_LSR_TEMT;
-            serial_update_irq(s);
+            s->write_chr = val;
+            s->write_retries = 0;
+            serial_chr_write(s);
         }
         break;
     case 1:
@@ -424,6 +452,7 @@ SerialState *serial_init(SetIRQFunc *set
     s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
     s->iir = UART_IIR_NO_INT;
     s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
+    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
 
     register_savevm("serial", base, 1, serial_save, serial_load, s);
 
@@ -511,6 +540,7 @@ SerialState *serial_mm_init (SetIRQFunc 
     s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
     s->base = base;
     s->it_shift = it_shift;
+    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
 
     register_savevm("serial", base, 1, serial_save, serial_load, s);
 
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/keymaps/ja
--- a/tools/ioemu/keymaps/ja    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/keymaps/ja    Fri Nov 10 11:11:04 2006 -0700
@@ -102,3 +102,6 @@ Henkan_Mode 0x79
 Henkan_Mode 0x79
 Katakana 0x70
 Muhenkan 0x7b
+Henkan_Mode_Real 0x79
+Henkan_Mode_Ultra 0x79
+backslash_ja 0x73
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/cpu.h
--- a/tools/ioemu/target-i386-dm/cpu.h  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/cpu.h  Fri Nov 10 11:11:04 2006 -0700
@@ -55,8 +55,6 @@ typedef struct CPUX86State {
     int interrupt_request;
 
     CPU_COMMON
-
-    int send_event;
 } CPUX86State;
 
 CPUX86State *cpu_x86_init(void);
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/exec-dm.c      Fri Nov 10 11:11:04 2006 -0700
@@ -32,6 +32,8 @@
 #include <unistd.h>
 #include <inttypes.h>
 
+#include <xen/hvm/e820.h>
+
 #include "cpu.h"
 #include "exec-all.h"
 
@@ -407,22 +409,36 @@ int iomem_index(target_phys_addr_t addr)
         return 0;
 }
 
+static inline int paddr_is_ram(target_phys_addr_t addr)
+{
+    /* Is this guest physical address RAM-backed? */
+#if defined(CONFIG_DM) && (defined(__i386__) || defined(__x86_64__))
+    if (ram_size <= HVM_BELOW_4G_RAM_END)
+        /* RAM is contiguous */
+        return (addr < ram_size);
+    else
+        /* There is RAM below and above the MMIO hole */
+        return ((addr < HVM_BELOW_4G_MMIO_START) ||
+                ((addr >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH)
+                 && (addr < ram_size + HVM_BELOW_4G_MMIO_LENGTH)));
+#else
+    return (addr < ram_size);
+#endif
+}
+
 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
                             int len, int is_write)
 {
     int l, io_index;
     uint8_t *ptr;
     uint32_t val;
-    target_phys_addr_t page;
-    unsigned long pd;
     
     while (len > 0) {
-        page = addr & TARGET_PAGE_MASK;
-        l = (page + TARGET_PAGE_SIZE) - addr;
+        /* How much can we copy before the next page boundary? */
+        l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK); 
         if (l > len)
             l = len;
        
-        pd = page;
         io_index = iomem_index(addr);
         if (is_write) {
             if (io_index) {
@@ -442,15 +458,11 @@ void cpu_physical_memory_rw(target_phys_
                     io_mem_write[io_index][0](io_mem_opaque[io_index], addr, 
val);
                     l = 1;
                 }
-            } else {
-                unsigned long addr1;
-
-                addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
-                /* RAM case */
-                ptr = phys_ram_base + addr1;
-                memcpy(ptr, buf, l);
+            } else if (paddr_is_ram(addr)) {
+                /* Reading from RAM */
+                memcpy(phys_ram_base + addr, buf, l);
 #ifdef __ia64__
-                sync_icache((unsigned long)ptr, l);
+                sync_icache((unsigned long)(phys_ram_base + addr), l);
 #endif 
             }
         } else {
@@ -471,14 +483,12 @@ void cpu_physical_memory_rw(target_phys_
                     stb_raw(buf, val);
                     l = 1;
                 }
-            } else if (addr < ram_size) {
-                /* RAM case */
-                ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
-                    (addr & ~TARGET_PAGE_MASK);
-                memcpy(buf, ptr, l);
+            } else if (paddr_is_ram(addr)) {
+                /* Reading from RAM */
+                memcpy(buf, phys_ram_base + addr, l);
             } else {
-                /* unreported MMIO space */
-                memset(buf, 0xff, len);
+                /* Neither RAM nor known MMIO space */
+                memset(buf, 0xff, len); 
             }
         }
         len -= l;
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/helper2.c      Fri Nov 10 11:11:04 2006 -0700
@@ -193,10 +193,10 @@ void sp_info()
     for (i = 0; i < vcpus; i++) {
         req = &(shared_page->vcpu_iodata[i].vp_ioreq);
         term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
-        term_printf("  req state: %x, pvalid: %x, addr: %"PRIx64", "
+        term_printf("  req state: %x, ptr: %x, addr: %"PRIx64", "
                     "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
-                    req->state, req->pdata_valid, req->addr,
-                    req->u.data, req->count, req->size);
+                    req->state, req->data_is_ptr, req->addr,
+                    req->data, req->count, req->size);
         term_printf("  IO totally occurred on this vcpu: %"PRIx64"\n",
                     req->io_count);
     }
@@ -209,18 +209,19 @@ static ioreq_t *__cpu_get_ioreq(int vcpu
 
     req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
 
-    if (req->state == STATE_IOREQ_READY) {
-        req->state = STATE_IOREQ_INPROCESS;
-        rmb();
-        return req;
-    }
-
-    fprintf(logfile, "False I/O request ... in-service already: "
-            "%x, pvalid: %x, port: %"PRIx64", "
-            "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
-            req->state, req->pdata_valid, req->addr,
-            req->u.data, req->count, req->size);
-    return NULL;
+    if (req->state != STATE_IOREQ_READY) {
+        fprintf(logfile, "I/O request not ready: "
+                "%x, ptr: %x, port: %"PRIx64", "
+                "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
+                req->state, req->data_is_ptr, req->addr,
+                req->data, req->count, req->size);
+        return NULL;
+    }
+
+    rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
+
+    req->state = STATE_IOREQ_INPROCESS;
+    return req;
 }
 
 //use poll to get the port notification
@@ -305,26 +306,26 @@ void cpu_ioreq_pio(CPUState *env, ioreq_
     sign = req->df ? -1 : 1;
 
     if (req->dir == IOREQ_READ) {
-        if (!req->pdata_valid) {
-            req->u.data = do_inp(env, req->addr, req->size);
+        if (!req->data_is_ptr) {
+            req->data = do_inp(env, req->addr, req->size);
         } else {
             unsigned long tmp;
 
             for (i = 0; i < req->count; i++) {
                 tmp = do_inp(env, req->addr, req->size);
-                write_physical((target_phys_addr_t) req->u.pdata
+                write_physical((target_phys_addr_t) req->data
                   + (sign * i * req->size),
                   req->size, &tmp);
             }
         }
     } else if (req->dir == IOREQ_WRITE) {
-        if (!req->pdata_valid) {
-            do_outp(env, req->addr, req->size, req->u.data);
+        if (!req->data_is_ptr) {
+            do_outp(env, req->addr, req->size, req->data);
         } else {
             for (i = 0; i < req->count; i++) {
                 unsigned long tmp;
 
-                read_physical((target_phys_addr_t) req->u.pdata
+                read_physical((target_phys_addr_t) req->data
                   + (sign * i * req->size),
                   req->size, &tmp);
                 do_outp(env, req->addr, req->size, tmp);
@@ -339,18 +340,18 @@ void cpu_ioreq_move(CPUState *env, ioreq
 
     sign = req->df ? -1 : 1;
 
-    if (!req->pdata_valid) {
+    if (!req->data_is_ptr) {
         if (req->dir == IOREQ_READ) {
             for (i = 0; i < req->count; i++) {
                 read_physical(req->addr
                   + (sign * i * req->size),
-                  req->size, &req->u.data);
+                  req->size, &req->data);
             }
         } else if (req->dir == IOREQ_WRITE) {
             for (i = 0; i < req->count; i++) {
                 write_physical(req->addr
                   + (sign * i * req->size),
-                  req->size, &req->u.data);
+                  req->size, &req->data);
             }
         }
     } else {
@@ -361,13 +362,13 @@ void cpu_ioreq_move(CPUState *env, ioreq
                 read_physical(req->addr
                   + (sign * i * req->size),
                   req->size, &tmp);
-                write_physical((target_phys_addr_t )req->u.pdata
+                write_physical((target_phys_addr_t )req->data
                   + (sign * i * req->size),
                   req->size, &tmp);
             }
         } else if (req->dir == IOREQ_WRITE) {
             for (i = 0; i < req->count; i++) {
-                read_physical((target_phys_addr_t) req->u.pdata
+                read_physical((target_phys_addr_t) req->data
                   + (sign * i * req->size),
                   req->size, &tmp);
                 write_physical(req->addr
@@ -382,51 +383,66 @@ void cpu_ioreq_and(CPUState *env, ioreq_
 {
     unsigned long tmp1, tmp2;
 
-    if (req->pdata_valid != 0)
+    if (req->data_is_ptr != 0)
         hw_error("expected scalar value");
 
     read_physical(req->addr, req->size, &tmp1);
     if (req->dir == IOREQ_WRITE) {
-        tmp2 = tmp1 & (unsigned long) req->u.data;
+        tmp2 = tmp1 & (unsigned long) req->data;
         write_physical(req->addr, req->size, &tmp2);
     }
-    req->u.data = tmp1;
-}
-
-void cpu_ioreq_or(CPUState *env, ioreq_t *req)
+    req->data = tmp1;
+}
+
+void cpu_ioreq_add(CPUState *env, ioreq_t *req)
 {
     unsigned long tmp1, tmp2;
 
-    if (req->pdata_valid != 0)
+    if (req->data_is_ptr != 0)
         hw_error("expected scalar value");
 
     read_physical(req->addr, req->size, &tmp1);
     if (req->dir == IOREQ_WRITE) {
-        tmp2 = tmp1 | (unsigned long) req->u.data;
+        tmp2 = tmp1 + (unsigned long) req->data;
         write_physical(req->addr, req->size, &tmp2);
     }
-    req->u.data = tmp1;
-}
-
-void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
+    req->data = tmp1;
+}
+
+void cpu_ioreq_or(CPUState *env, ioreq_t *req)
 {
     unsigned long tmp1, tmp2;
 
-    if (req->pdata_valid != 0)
+    if (req->data_is_ptr != 0)
         hw_error("expected scalar value");
 
     read_physical(req->addr, req->size, &tmp1);
     if (req->dir == IOREQ_WRITE) {
-        tmp2 = tmp1 ^ (unsigned long) req->u.data;
+        tmp2 = tmp1 | (unsigned long) req->data;
         write_physical(req->addr, req->size, &tmp2);
     }
-    req->u.data = tmp1;
+    req->data = tmp1;
+}
+
+void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
+{
+    unsigned long tmp1, tmp2;
+
+    if (req->data_is_ptr != 0)
+        hw_error("expected scalar value");
+
+    read_physical(req->addr, req->size, &tmp1);
+    if (req->dir == IOREQ_WRITE) {
+        tmp2 = tmp1 ^ (unsigned long) req->data;
+        write_physical(req->addr, req->size, &tmp2);
+    }
+    req->data = tmp1;
 }
 
 void __handle_ioreq(CPUState *env, ioreq_t *req)
 {
-    if (!req->pdata_valid && req->dir == IOREQ_WRITE && req->size != 4)
-       req->u.data &= (1UL << (8 * req->size)) - 1;
+    if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
+       req->data &= (1UL << (8 * req->size)) - 1;
 
     switch (req->type) {
     case IOREQ_TYPE_PIO:
@@ -437,6 +453,9 @@ void __handle_ioreq(CPUState *env, ioreq
         break;
     case IOREQ_TYPE_AND:
         cpu_ioreq_and(env, req);
+        break;
+    case IOREQ_TYPE_ADD:
+        cpu_ioreq_add(env, req);
         break;
     case IOREQ_TYPE_OR:
         cpu_ioreq_or(env, req);
@@ -486,12 +505,19 @@ void cpu_handle_ioreq(void *opaque)
     if (req) {
         __handle_ioreq(env, req);
 
-        /* No state change if state = STATE_IORESP_HOOK */
-        if (req->state == STATE_IOREQ_INPROCESS) {
-            mb();
-            req->state = STATE_IORESP_READY;
-        }
-        env->send_event = 1;
+        if (req->state != STATE_IOREQ_INPROCESS) {
+            fprintf(logfile, "Badness in I/O request ... not in service?!: "
+                    "%x, ptr: %x, port: %"PRIx64", "
+                    "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
+                    req->state, req->data_is_ptr, req->addr,
+                    req->data, req->count, req->size);
+            destroy_hvm_domain();
+            return;
+        }
+
+        wmb(); /* Update ioreq contents /then/ update state. */
+        req->state = STATE_IORESP_READY;
+        xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
     }
 }
 
@@ -507,8 +533,6 @@ int main_loop(void)
     qemu_mod_timer(buffered_io_timer, qemu_get_clock(rt_clock));
 
     qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
-
-    env->send_event = 0;
 
     while (1) {
         if (vm_running) {
@@ -522,11 +546,6 @@ int main_loop(void)
 
         /* Wait up to 10 msec. */
         main_loop_wait(10);
-
-        if (env->send_event) {
-            env->send_event = 0;
-            xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
-        }
     }
     destroy_hvm_domain();
     return 0;
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/i8259-dm.c
--- a/tools/ioemu/target-i386-dm/i8259-dm.c     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/i8259-dm.c     Fri Nov 10 11:11:04 2006 -0700
@@ -22,58 +22,18 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
-
-/* debug PIC */
-//#define DEBUG_PIC
-
-//#define DEBUG_IRQ_LATENCY
-//#define DEBUG_IRQ_COUNT
-
 #include "xenctrl.h"
 #include <xen/hvm/ioreq.h>
 #include <stdio.h>
 #include "cpu.h"
 #include "cpu-all.h"
 
-extern shared_iopage_t *shared_page;
-
 struct PicState2 {
 };
 
 void pic_set_irq_new(void *opaque, int irq, int level)
 {
-    /* PicState2 *s = opaque; */
-    global_iodata_t  *gio;
-    int  mask;
-
-    gio = &shared_page->sp_global;
-    mask = 1 << irq;
-    if ( gio->pic_elcr & mask ) {
-        /* level */
-       if ( level ) {
-           atomic_clear_bit(irq, &gio->pic_clear_irr);
-           atomic_set_bit(irq, &gio->pic_irr);
-           cpu_single_env->send_event = 1;
-       }
-       else {
-           atomic_clear_bit(irq, &gio->pic_irr);
-           atomic_set_bit(irq, &gio->pic_clear_irr);
-           cpu_single_env->send_event = 1;
-       }
-    }
-    else {
-       /* edge */
-       if ( level ) {
-           if ( (mask & gio->pic_last_irr) == 0 ) { 
-               atomic_set_bit(irq, &gio->pic_irr);
-               atomic_set_bit(irq, &gio->pic_last_irr);
-               cpu_single_env->send_event = 1;
-           }
-       }
-       else {
-           atomic_clear_bit(irq, &gio->pic_last_irr);
-       }
-    }
+    xc_hvm_set_irq_level(xc_handle, domid, irq, level);
 }
 
 /* obsolete function */
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/target-i386-dm/qemu-dm.debug
--- a/tools/ioemu/target-i386-dm/qemu-dm.debug  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/target-i386-dm/qemu-dm.debug  Fri Nov 10 11:11:04 2006 -0700
@@ -1,5 +1,10 @@
 #!/bin/sh
 
+if [ "`arch`" = "x86_64" ]; then
+    LIBDIR="lib64"
+else
+    LIBDIR="lib"
+fi
 echo $* > /tmp/args
 echo $DISPLAY >> /tmp/args
-exec /usr/lib/xen/bin/qemu-dm $*
+exec /usr/$LIBDIR/xen/bin/qemu-dm $*
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/vl.c  Fri Nov 10 11:11:04 2006 -0700
@@ -1684,7 +1684,7 @@ static void tty_serial_init(int fd, int 
 
     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                           |INLCR|IGNCR|ICRNL|IXON);
-    tty.c_oflag |= OPOST;
+    tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */
     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
     tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS);
     switch(data_bits) {
@@ -6390,17 +6390,17 @@ int main(int argc, char **argv)
             exit(1);
     }
 
-    /* init the memory */
-    phys_ram_size = ram_size + vga_ram_size + bios_size;
-
-#ifdef CONFIG_DM
-
-    xc_handle = xc_interface_open();
-
 #if defined (__ia64__)
     if (ram_size > MMIO_START)
         ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */
 #endif
+
+    /* init the memory */
+    phys_ram_size = ram_size + vga_ram_size + bios_size;
+
+#ifdef CONFIG_DM
+
+    xc_handle = xc_interface_open();
 
     nr_pages = ram_size/PAGE_SIZE;
     tmp_nr_pages = nr_pages;
@@ -6420,14 +6420,13 @@ int main(int argc, char **argv)
     }
 
 #if defined(__i386__) || defined(__x86_64__)
-    if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
+    for ( i = 0; i < tmp_nr_pages; i++)
+        page_array[i] = i;
+    if (xc_domain_translate_gpfn_list(xc_handle, domid, tmp_nr_pages,
+                                      page_array, page_array)) {
         fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
         exit(-1);
     }
-
-    if (ram_size > HVM_BELOW_4G_RAM_END)
-        for (i = 0; i < nr_pages - (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT); i++)
-            page_array[tmp_nr_pages - 1 - i] = page_array[nr_pages - 1 - i];
 
     phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
                                          PROT_READ|PROT_WRITE, page_array,
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/vl.h  Fri Nov 10 11:11:04 2006 -0700
@@ -929,6 +929,10 @@ void piix4_pm_init(PCIBus *bus, int devf
 void piix4_pm_init(PCIBus *bus, int devfn);
 void acpi_bios_init(void);
 
+/* tpm_tis.c */
+int has_tpm_device(void);
+void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);
+
 /* piix4acpi.c */
 extern void pci_piix4_acpi_init(PCIBus *bus, int devfn);
 
@@ -1213,6 +1217,25 @@ void xenstore_write_vncport(int vnc_disp
 void xenstore_write_vncport(int vnc_display);
 int xenstore_read_vncpasswd(int domid);
 
+int xenstore_domain_has_devtype(struct xs_handle *handle,
+                                const char *devtype);
+char **xenstore_domain_get_devices(struct xs_handle *handle,
+                                   const char *devtype, unsigned int *num);
+char *xenstore_read_hotplug_status(struct xs_handle *handle,
+                                   const char *devtype, const char *inst);
+char *xenstore_backend_read_variable(struct xs_handle *,
+                                     const char *devtype, const char *inst,
+                                     const char *var);
+int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
+                                         const char *devtype,
+                                         const char *inst,
+                                         const char *token);
+int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
+                                             const char *devtype,
+                                             const char *inst,
+                                             const char *token);
+
+
 /* xen_platform.c */
 void pci_xen_platform_init(PCIBus *bus);
 
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/vnc_keysym.h
--- a/tools/ioemu/vnc_keysym.h  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/vnc_keysym.h  Fri Nov 10 11:11:04 2006 -0700
@@ -271,5 +271,15 @@ static name2keysym_t name2keysym[]={
 {"Num_Lock", 0xff7f},    /* XK_Num_Lock */
 {"Pause", 0xff13},       /* XK_Pause */
 {"Escape", 0xff1b},      /* XK_Escape */
+
+    /* localized keys */
+{"BackApostrophe", 0xff21},
+{"Muhenkan", 0xff22},
+{"Katakana", 0xff25},
+{"Zenkaku_Hankaku", 0xff29},
+{"Henkan_Mode_Real", 0xff23},
+{"Henkan_Mode_Ultra", 0xff3e},
+{"backslash_ja", 0xffa5},
+
 {0,0},
 };
diff -r 11b718eb22c9 -r ebed72718263 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/ioemu/xenstore.c    Fri Nov 10 11:11:04 2006 -0700
@@ -264,3 +264,140 @@ int xenstore_read_vncpasswd(int domid)
 
     return rc;
 }
+
+
+/*
+ * get all device instances of a certain type
+ */
+char **xenstore_domain_get_devices(struct xs_handle *handle,
+                                   const char *devtype, unsigned int *num)
+{
+    char *path;
+    char *buf = NULL;
+    char **e  = NULL;
+
+    path = xs_get_domain_path(handle, domid);
+    if (path == NULL)
+        goto out;
+
+    if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
+       goto out;
+
+    e = xs_directory(handle, XBT_NULL, buf, num);
+
+ out:
+    free(path);
+    free(buf);
+    return e;
+}
+
+/*
+ * Check whether a domain has devices of the given type
+ */
+int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype)
+{
+    int rc = 0;
+    unsigned int num;
+    char **e = xenstore_domain_get_devices(handle, devtype, &num);
+    if (e)
+        rc = 1;
+    free(e);
+    return rc;
+}
+
+/*
+ * Function that creates a path to a variable of an instance of a
+ * certain device
+ */
+static char *get_device_variable_path(const char *devtype, const char *inst,
+                                      const char *var)
+{
+    char *buf = NULL;
+    if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s",
+                  devtype,
+                  domid,
+                  inst,
+                  var) == -1) {
+        free(buf);
+        buf = NULL;
+    }
+    return buf;
+}
+
+char *xenstore_backend_read_variable(struct xs_handle *handle,
+                                     const char *devtype, const char *inst,
+                                     const char *var)
+{
+    char *value = NULL;
+    char *buf = NULL;
+    unsigned int len;
+
+    buf = get_device_variable_path(devtype, inst, var);
+    if (NULL == buf)
+       goto out;
+
+    value = xs_read(handle, XBT_NULL, buf, &len);
+
+    free(buf);
+
+out:
+    return value;
+}
+
+/*
+  Read the hotplug status variable from the backend given the type
+  of device and its instance.
+*/
+char *xenstore_read_hotplug_status(struct xs_handle *handle,
+                                   const char *devtype, const char *inst)
+{
+    return xenstore_backend_read_variable(handle, devtype, inst,
+                                          "hotplug-status");
+}
+
+/*
+   Subscribe to the hotplug status of a device given the type of device and
+   its instance.
+   In case an error occurrs, a negative number is returned.
+ */
+int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
+                                         const char *devtype,
+                                         const char *inst,
+                                         const char *token)
+{
+    int rc = 0;
+    char *path = get_device_variable_path(devtype, inst, "hotplug-status");
+
+    if (path == NULL)
+        return -1;
+
+    if (0 == xs_watch(handle, path, token))
+        rc = -2;
+
+    free(path);
+
+    return rc;
+}
+
+/*
+ * Unsubscribe from a subscription to the status of a hotplug variable of
+ * a device.
+ */
+int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
+                                             const char *devtype,
+                                             const char *inst,
+                                             const char *token)
+{
+    int rc = 0;
+    char *path;
+    path = get_device_variable_path(devtype, inst, "hotplug-status");
+    if (path == NULL)
+        return -1;
+
+    if (0 == xs_unwatch(handle, path, token))
+        rc = -2;
+
+    free(path);
+
+    return rc;
+}
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c      Fri Nov 10 11:11:04 2006 -0700
@@ -618,7 +618,7 @@ int
 int
 xc_hvm_build(int xc_handle, uint32_t domid, int memsize,
              const char *image_name, unsigned int vcpus, unsigned int pae,
-             unsigned int acpi, unsigned int apic, unsigned int store_evtchn,
+             unsigned int acpi, unsigned int store_evtchn,
              unsigned long *store_mfn)
 {
     struct xen_domctl launch_domctl, domctl;
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_core.c     Fri Nov 10 11:11:04 2006 -0700
@@ -62,7 +62,7 @@ xc_domain_dumpcore_via_callback(int xc_h
 
     nr_pages = info.nr_pages;
 
-    header.xch_magic = XC_CORE_MAGIC;
+    header.xch_magic = info.hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
     header.xch_nr_vcpus = nr_vcpus;
     header.xch_nr_pages = nr_pages;
     header.xch_ctxt_offset = sizeof(struct xc_core_header);
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_domain.c   Fri Nov 10 11:11:04 2006 -0700
@@ -12,6 +12,7 @@ int xc_domain_create(int xc_handle,
 int xc_domain_create(int xc_handle,
                      uint32_t ssidref,
                      xen_domain_handle_t handle,
+                     uint32_t flags,
                      uint32_t *pdomid)
 {
     int err;
@@ -20,6 +21,7 @@ int xc_domain_create(int xc_handle,
     domctl.cmd = XEN_DOMCTL_createdomain;
     domctl.domain = (domid_t)*pdomid;
     domctl.u.createdomain.ssidref = ssidref;
+    domctl.u.createdomain.flags   = flags;
     memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
     if ( (err = do_domctl(xc_handle, &domctl)) != 0 )
         return err;
@@ -169,15 +171,16 @@ int xc_domain_getinfo(int xc_handle,
             break;
         info->domid      = (uint16_t)domctl.domain;
 
-        info->dying    = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_DYING);
-        info->shutdown = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN);
-        info->paused   = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED);
-        info->blocked  = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_BLOCKED);
-        info->running  = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_RUNNING);
+        info->dying    = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_dying);
+        info->shutdown = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_shutdown);
+        info->paused   = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_paused);
+        info->blocked  = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_blocked);
+        info->running  = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_running);
+        info->hvm      = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
 
         info->shutdown_reason =
-            (domctl.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) &
-            DOMFLAGS_SHUTDOWNMASK;
+            (domctl.u.getdomaininfo.flags>>XEN_DOMINF_shutdownshift) &
+            XEN_DOMINF_shutdownmask;
 
         if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
         {
@@ -200,7 +203,8 @@ int xc_domain_getinfo(int xc_handle,
         info++;
     }
 
-    if( !nr_doms ) return rc;
+    if ( nr_doms == 0 )
+        return rc;
 
     return nr_doms;
 }
@@ -345,7 +349,7 @@ int xc_domain_memory_increase_reservatio
     if ( err == nr_extents )
         return 0;
 
-    if ( err > 0 )
+    if ( err >= 0 )
     {
         DPRINTF("Failed allocation for dom %d: "
                 "%ld pages order %d addr_bits %d\n",
@@ -384,11 +388,11 @@ int xc_domain_memory_decrease_reservatio
     if ( err == nr_extents )
         return 0;
 
-    if ( err > 0 )
+    if ( err >= 0 )
     {
         DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n",
                 domid, nr_extents, extent_order);
-        errno = EBUSY;
+        errno = EINVAL;
         err = -1;
     }
 
@@ -415,7 +419,7 @@ int xc_domain_memory_populate_physmap(in
     if ( err == nr_extents )
         return 0;
 
-    if ( err > 0 )
+    if ( err >= 0 )
     {
         DPRINTF("Failed allocation for dom %d: %ld pages order %d\n",
                 domid, nr_extents, extent_order);
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_hvm_build.c        Fri Nov 10 11:11:04 2006 -0700
@@ -12,7 +12,6 @@
 #include <unistd.h>
 #include <zlib.h>
 #include <xen/hvm/hvm_info_table.h>
-#include <xen/hvm/ioreq.h>
 #include <xen/hvm/params.h>
 #include <xen/hvm/e820.h>
 
@@ -57,88 +56,67 @@ static void build_e820map(void *e820_pag
     unsigned char nr_map = 0;
 
     /*
-     * physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved
+     * Physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved
      * for PCI devices MMIO. So if HVM has more than HVM_BELOW_4G_RAM_END
      * RAM, memory beyond HVM_BELOW_4G_RAM_END will go to 4G above.
      */
-    if ( mem_size > HVM_BELOW_4G_RAM_END ) {
+    if ( mem_size > HVM_BELOW_4G_RAM_END )
+    {
         extra_mem_size = mem_size - HVM_BELOW_4G_RAM_END;
         mem_size = HVM_BELOW_4G_RAM_END;
     }
 
+    /* 0x0-0x9F000: Ordinary RAM. */
     e820entry[nr_map].addr = 0x0;
     e820entry[nr_map].size = 0x9F000;
     e820entry[nr_map].type = E820_RAM;
     nr_map++;
 
+    /*
+     * 0x9F000-0x9F800: SMBIOS tables.
+     * 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA).
+     * TODO: SMBIOS tables should be moved higher (>=0xE0000).
+     *       They are unusually low in our memory map: could cause problems?
+     */
     e820entry[nr_map].addr = 0x9F000;
     e820entry[nr_map].size = 0x1000;
     e820entry[nr_map].type = E820_RESERVED;
     nr_map++;
 
-    e820entry[nr_map].addr = 0xA0000;
+    /*
+     * Following regions are standard regions of the PC memory map.
+     * They are not covered by e820 regions. OSes will not use as RAM.
+     * 0xA0000-0xC0000: VGA memory-mapped I/O. Not covered by E820.
+     * 0xC0000-0xE0000: 16-bit devices, expansion ROMs (inc. vgabios).
+     * TODO: hvmloader should free pages which turn out to be unused.
+     */
+
+    /*
+     * 0xE0000-0x0F0000: PC-specific area. We place ACPI tables here.
+     *                   We *cannot* mark as E820_ACPI, for two reasons:
+     *                    1. ACPI spec. says that E820_ACPI regions below
+     *                       16MB must clip INT15h 0x88 and 0xe801 queries.
+     *                       Our rombios doesn't do this.
+     *                    2. The OS is allowed to reclaim ACPI memory after
+     *                       parsing the tables. But our FACS is in this
+     *                       region and it must not be reclaimed (it contains
+     *                       the ACPI global lock!).
+     * 0xF0000-0x100000: System BIOS.
+     * TODO: hvmloader should free pages which turn out to be unused.
+     */
+    e820entry[nr_map].addr = 0xE0000;
     e820entry[nr_map].size = 0x20000;
-    e820entry[nr_map].type = E820_IO;
-    nr_map++;
-
-    e820entry[nr_map].addr = 0xEA000;
-    e820entry[nr_map].size = 0x01000;
-    e820entry[nr_map].type = E820_ACPI;
-    nr_map++;
-
-    e820entry[nr_map].addr = 0xF0000;
-    e820entry[nr_map].size = 0x10000;
     e820entry[nr_map].type = E820_RESERVED;
     nr_map++;
 
-/* buffered io page.    */
-#define BUFFERED_IO_PAGES   1
-/* xenstore page.       */
-#define XENSTORE_PAGES      1
-/* shared io page.      */
-#define SHARED_IO_PAGES     1
-/* totally 16 static pages are reserved in E820 table */
-
-    /* Most of the ram goes here */
+    /* Low RAM goes here. Remove 3 pages for ioreq, bufioreq, and xenstore. */
     e820entry[nr_map].addr = 0x100000;
-    e820entry[nr_map].size = mem_size - 0x100000 - PAGE_SIZE *
-                                                (BUFFERED_IO_PAGES +
-                                                 XENSTORE_PAGES +
-                                                 SHARED_IO_PAGES);
+    e820entry[nr_map].size = mem_size - 0x100000 - PAGE_SIZE * 3;
     e820entry[nr_map].type = E820_RAM;
     nr_map++;
 
-    /* Statically allocated special pages */
-
-    /* For buffered IO requests */
-    e820entry[nr_map].addr = mem_size - PAGE_SIZE *
-                                        (BUFFERED_IO_PAGES +
-                                         XENSTORE_PAGES +
-                                         SHARED_IO_PAGES);
-    e820entry[nr_map].size = PAGE_SIZE * BUFFERED_IO_PAGES;
-    e820entry[nr_map].type = E820_BUFFERED_IO;
-    nr_map++;
-
-    /* For xenstore */
-    e820entry[nr_map].addr = mem_size - PAGE_SIZE *
-                                        (XENSTORE_PAGES +
-                                         SHARED_IO_PAGES);
-    e820entry[nr_map].size = PAGE_SIZE * XENSTORE_PAGES;
-    e820entry[nr_map].type = E820_XENSTORE;
-    nr_map++;
-
-    /* Shared ioreq_t page */
-    e820entry[nr_map].addr = mem_size - PAGE_SIZE * SHARED_IO_PAGES;
-    e820entry[nr_map].size = PAGE_SIZE * SHARED_IO_PAGES;
-    e820entry[nr_map].type = E820_SHARED_PAGE;
-    nr_map++;
-
-    e820entry[nr_map].addr = 0xFEC00000;
-    e820entry[nr_map].size = 0x1400000;
-    e820entry[nr_map].type = E820_IO;
-    nr_map++;
-
-    if ( extra_mem_size ) {
+    if ( extra_mem_size )
+    {
         e820entry[nr_map].addr = (1ULL << 32);
         e820entry[nr_map].size = extra_mem_size;
         e820entry[nr_map].type = E820_RAM;
@@ -197,28 +175,22 @@ static int setup_guest(int xc_handle,
 static int setup_guest(int xc_handle,
                        uint32_t dom, int memsize,
                        char *image, unsigned long image_size,
-                       unsigned long nr_pages,
                        vcpu_guest_context_t *ctxt,
                        unsigned long shared_info_frame,
                        unsigned int vcpus,
                        unsigned int pae,
                        unsigned int acpi,
-                       unsigned int apic,
                        unsigned int store_evtchn,
                        unsigned long *store_mfn)
 {
     xen_pfn_t *page_array = NULL;
-    unsigned long count, i;
-    unsigned long long ptr;
-    xc_mmu_t *mmu = NULL;
-
+    unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
+    unsigned long shared_page_nr;
     shared_info_t *shared_info;
     void *e820_page;
-
     struct domain_setup_info dsi;
     uint64_t v_end;
-
-    unsigned long shared_page_nr;
+    int rc;
 
     memset(&dsi, 0, sizeof(struct domain_setup_info));
 
@@ -231,7 +203,6 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-    /* memsize is in megabytes */
     v_end = (unsigned long long)memsize << 20;
 
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
@@ -256,40 +227,33 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
-    {
-        PERROR("Could not get the page frame list.\n");
+    for ( i = 0; i < nr_pages; i++ )
+        page_array[i] = i;
+    for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < nr_pages; i++ )
+        page_array[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
+
+    /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
+    rc = xc_domain_memory_populate_physmap(
+        xc_handle, dom, (nr_pages > 0xa0) ? 0xa0 : nr_pages,
+        0, 0, &page_array[0x00]);
+    if ( (rc == 0) && (nr_pages > 0xc0) )
+        rc = xc_domain_memory_populate_physmap(
+            xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]);
+    if ( rc != 0 )
+    {
+        PERROR("Could not allocate memory for HVM guest.\n");
+        goto error_out;
+    }
+
+    if ( xc_domain_translate_gpfn_list(xc_handle, dom, nr_pages,
+                                       page_array, page_array) )
+    {
+        PERROR("Could not translate addresses of HVM guest.\n");
         goto error_out;
     }
 
     loadelfimage(image, xc_handle, dom, page_array, &dsi);
 
-    if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
-        goto error_out;
-
-    /* Write the machine->phys table entries. */
-    for ( count = 0; count < nr_pages; count++ )
-    {
-        unsigned long gpfn_count_skip;
-
-        ptr = (unsigned long long)page_array[count] << PAGE_SHIFT;
-
-        gpfn_count_skip = 0;
-
-        /*
-         * physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved
-         * for PCI devices MMIO. So if HVM has more than HVM_BELOW_4G_RAM_END
-         * RAM, memory beyond HVM_BELOW_4G_RAM_END will go to 4G above.
-         */
-        if ( count >= (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT) )
-            gpfn_count_skip = HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
-
-        if ( xc_add_mmu_update(xc_handle, mmu,
-                               ptr | MMU_MACHPHYS_UPDATE,
-                               count + gpfn_count_skip) )
-            goto error_out;
-    }
-
     if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi) )
     {
         ERROR("Couldn't set hvm info for HVM guest.\n");
@@ -297,7 +261,6 @@ static int setup_guest(int xc_handle,
     }
 
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
-    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_APIC_ENABLED, apic);
 
     if ( (e820_page = xc_map_foreign_range(
               xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
@@ -316,6 +279,8 @@ static int setup_guest(int xc_handle,
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
         shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
+    memset(&shared_info->evtchn_mask[0], 0xff,
+           sizeof(shared_info->evtchn_mask));
     munmap(shared_info, PAGE_SIZE);
 
     if ( v_end > HVM_BELOW_4G_RAM_END )
@@ -323,39 +288,25 @@ static int setup_guest(int xc_handle,
     else
         shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
 
+    /* Paranoia: clean pages. */
+    if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr]) ||
+         xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-1]) ||
+         xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-2]) )
+        goto error_out;
+
     *store_mfn = page_array[shared_page_nr - 1];
-
-    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr - 1);
+    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
-
-    /* Paranoia */
-    /* clean the shared IO requests page */
-    if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr]) )
-        goto error_out;
-
-    /* clean the buffered IO requests page */
-    if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr - 2]) )
-        goto error_out;
-
-    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
-        goto error_out;
-
-    /* Send the page update requests down to the hypervisor. */
-    if ( xc_finish_mmu_updates(xc_handle, mmu) )
-        goto error_out;
-
-    free(mmu);
+    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
+    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
+
     free(page_array);
 
-    /*
-     * Initial register values:
-     */
     ctxt->user_regs.eip = dsi.v_kernentry;
 
     return 0;
 
  error_out:
-    free(mmu);
     free(page_array);
     return -1;
 }
@@ -368,45 +319,17 @@ static int xc_hvm_build_internal(int xc_
                                  unsigned int vcpus,
                                  unsigned int pae,
                                  unsigned int acpi,
-                                 unsigned int apic,
                                  unsigned int store_evtchn,
                                  unsigned long *store_mfn)
 {
     struct xen_domctl launch_domctl, domctl;
-    int rc, i;
-    vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
-    unsigned long nr_pages;
-    xen_capabilities_info_t xen_caps;
+    vcpu_guest_context_t ctxt;
+    int rc;
 
     if ( (image == NULL) || (image_size == 0) )
     {
         ERROR("Image required");
         goto error_out;
-    }
-
-    if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
-    {
-        PERROR("Failed to get xen version info");
-        goto error_out;
-    }
-
-    if ( !strstr(xen_caps, "hvm") )
-    {
-        PERROR("CPU doesn't support HVM extensions or "
-               "the extensions are not enabled");
-        goto error_out;
-    }
-
-    if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
-    {
-        PERROR("Could not find total pages for domain");
-        goto error_out;
-    }
-
-    if ( lock_pages(&st_ctxt, sizeof(st_ctxt) ) )
-    {
-        PERROR("%s: ctxt mlock failed", __func__);
-        return 1;
     }
 
     domctl.cmd = XEN_DOMCTL_getdomaininfo;
@@ -418,68 +341,30 @@ static int xc_hvm_build_internal(int xc_
         goto error_out;
     }
 
-    /* HVM domains must be put into shadow mode at the start of day */
-    if ( xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_ENABLE,
-                           NULL, 0, NULL, 
-                           XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT  |
-                           XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE |
-                           XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL, 
-                           NULL) )
-    {
-        PERROR("Could not enable shadow paging for domain.\n");
-        goto error_out;
-    }        
-
-    memset(ctxt, 0, sizeof(*ctxt));
-
-    ctxt->flags = VGCF_HVM_GUEST;
-    if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
-                     ctxt, domctl.u.getdomaininfo.shared_info_frame,
-                     vcpus, pae, acpi, apic, store_evtchn, store_mfn) < 0)
+    memset(&ctxt, 0, sizeof(ctxt));
+
+    if ( setup_guest(xc_handle, domid, memsize, image, image_size,
+                     &ctxt, domctl.u.getdomaininfo.shared_info_frame,
+                     vcpus, pae, acpi, store_evtchn, store_mfn) < 0)
     {
         ERROR("Error constructing guest OS");
         goto error_out;
     }
 
-    /* FPU is set up to default initial state. */
-    memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
-
-    /* Virtual IDT is empty at start-of-day. */
-    for ( i = 0; i < 256; i++ )
-    {
-        ctxt->trap_ctxt[i].vector = i;
-        ctxt->trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-    }
-
-    /* No LDT. */
-    ctxt->ldt_ents = 0;
-
-    /* Use the default Xen-provided GDT. */
-    ctxt->gdt_ents = 0;
-
-    /* No debugging. */
-    memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
-
-    /* No callback handlers. */
-#if defined(__i386__)
-    ctxt->event_callback_cs     = FLAT_KERNEL_CS;
-    ctxt->event_callback_eip    = 0;
-    ctxt->failsafe_callback_cs  = FLAT_KERNEL_CS;
-    ctxt->failsafe_callback_eip = 0;
-#elif defined(__x86_64__)
-    ctxt->event_callback_eip    = 0;
-    ctxt->failsafe_callback_eip = 0;
-    ctxt->syscall_callback_eip  = 0;
-#endif
+    if ( lock_pages(&ctxt, sizeof(ctxt) ) )
+    {
+        PERROR("%s: ctxt mlock failed", __func__);
+        goto error_out;
+    }
 
     memset(&launch_domctl, 0, sizeof(launch_domctl));
-
     launch_domctl.domain = (domid_t)domid;
     launch_domctl.u.vcpucontext.vcpu   = 0;
-    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
-
+    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt);
     launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
     rc = xc_domctl(xc_handle, &launch_domctl);
+
+    unlock_pages(&ctxt, sizeof(ctxt));
 
     return rc;
 
@@ -626,7 +511,6 @@ int xc_hvm_build(int xc_handle,
                  unsigned int vcpus,
                  unsigned int pae,
                  unsigned int acpi,
-                 unsigned int apic,
                  unsigned int store_evtchn,
                  unsigned long *store_mfn)
 {
@@ -640,7 +524,7 @@ int xc_hvm_build(int xc_handle,
 
     sts = xc_hvm_build_internal(xc_handle, domid, memsize,
                                 image, image_size,
-                                vcpus, pae, acpi, apic,
+                                vcpus, pae, acpi,
                                 store_evtchn, store_mfn);
 
     free(image);
@@ -662,7 +546,6 @@ int xc_hvm_build_mem(int xc_handle,
                      unsigned int vcpus,
                      unsigned int pae,
                      unsigned int acpi,
-                     unsigned int apic,
                      unsigned int store_evtchn,
                      unsigned long *store_mfn)
 {
@@ -687,7 +570,7 @@ int xc_hvm_build_mem(int xc_handle,
 
     sts = xc_hvm_build_internal(xc_handle, domid, memsize,
                                 img, img_len,
-                                vcpus, pae, acpi, apic,
+                                vcpus, pae, acpi,
                                 store_evtchn, store_mfn);
 
     /* xc_inflate_buffer may return the original buffer pointer (for
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_linux_build.c      Fri Nov 10 11:11:04 2006 -0700
@@ -25,17 +25,16 @@
 #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
 #endif
 
-#ifdef __ia64__
-#define get_tot_pages xc_get_max_pages
-#else
-#define get_tot_pages xc_get_tot_pages
-#endif
-
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
 
 struct initrd_info {
     enum { INITRD_none, INITRD_file, INITRD_mem } type;
+    /*
+     * .len must be filled in by the user for type==INITRD_mem. It is
+     * filled in by load_initrd() for INITRD_file and unused for
+     * INITRD_none.
+     */
     unsigned long len;
     union {
         gzFile file_handle;
@@ -134,30 +133,42 @@ static int load_initrd(int xc_handle, do
                 xen_pfn_t *phys_to_mach)
 {
     char page[PAGE_SIZE];
-    unsigned long pfn_start, pfn, nr_pages;
+    unsigned long pfn_start, pfn;
 
     if ( initrd->type == INITRD_none )
         return 0;
 
     pfn_start = physbase >> PAGE_SHIFT;
-    nr_pages  = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-    for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
-    {
-        if ( initrd->type == INITRD_mem )
+
+    if ( initrd->type == INITRD_mem )
+    {
+        unsigned long nr_pages  = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+        for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
         {
             xc_copy_to_domain_page(
                 xc_handle, dom, phys_to_mach[pfn],
                 &initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
         }
-        else
-        {
-            if ( gzread(initrd->u.file_handle, page, PAGE_SIZE) == -1 )
+    }
+    else
+    {
+        int readlen;
+
+        pfn = pfn_start;
+        initrd->len = 0;
+
+        /* gzread returns 0 on EOF */
+        while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) )
+        {
+            if ( readlen < 0 )
             {
                 PERROR("Error reading initrd image, could not");
                 return -EINVAL;
             }
-            xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn], page);
+
+            initrd->len += readlen;
+            xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page);
         }
     }
 
@@ -485,10 +496,17 @@ static int setup_guest(int xc_handle,
     if ( rc != 0 )
         goto error_out;
 
-    dsi.v_start      = round_pgdown(dsi.v_start);
-    vinitrd_start    = round_pgup(dsi.v_end);
-    vinitrd_end      = vinitrd_start + initrd->len;
-    v_end            = round_pgup(vinitrd_end);
+    dsi.v_start = round_pgdown(dsi.v_start);
+    (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
+                           &dsi);
+
+    vinitrd_start = round_pgup(dsi.v_end);
+    if ( load_initrd(xc_handle, dom, initrd,
+                     vinitrd_start - dsi.v_start, page_array) )
+        goto error_out;
+
+    vinitrd_end    = vinitrd_start + initrd->len;
+    v_end          = round_pgup(vinitrd_end);
     start_info_mpa = (nr_pages - 3) << PAGE_SHIFT;
 
     /* Build firmware.  */
@@ -524,13 +542,6 @@ static int setup_guest(int xc_handle,
            _p(vinitrd_start),   _p(vinitrd_end),
            _p(dsi.v_start),     _p(v_end));
     IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
-
-    (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
-                           &dsi);
-
-    if ( load_initrd(xc_handle, dom, initrd,
-                     vinitrd_start - dsi.v_start, page_array) )
-        goto error_out;
 
     *pvke = dsi.v_kernentry;
 
@@ -657,7 +668,6 @@ static int setup_guest(int xc_handle,
     int hypercall_page_defined;
     start_info_t *start_info;
     shared_info_t *shared_info;
-    xc_mmu_t *mmu = NULL;
     const char *p;
     DECLARE_DOMCTL;
     int rc;
@@ -699,7 +709,7 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-    if (!compat_check(xc_handle, &dsi))
+    if ( !compat_check(xc_handle, &dsi) )
         goto error_out;
 
     /* Parse and validate kernel features. */
@@ -727,6 +737,28 @@ static int setup_guest(int xc_handle,
 
     shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
                                            required_features);
+
+    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
+    {
+        PERROR("Could not allocate memory");
+        goto error_out;
+    }
+
+    for ( i = 0; i < nr_pages; i++ )
+        page_array[i] = i;
+
+    if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
+                                           0, 0, page_array) )
+    {
+        PERROR("Could not allocate memory for PV guest.\n");
+        goto error_out;
+    }
+
+    rc = (load_funcs.loadimage)(image, image_size,
+                           xc_handle, dom, page_array,
+                           &dsi);
+    if ( rc != 0 )
+        goto error_out;
 
     /*
      * Why do we need this? The number of page-table frames depends on the
@@ -741,9 +773,14 @@ static int setup_guest(int xc_handle,
         ERROR("End of mapped kernel image too close to end of memory");
         goto error_out;
     }
+
     vinitrd_start = v_end;
+    if ( load_initrd(xc_handle, dom, initrd,
+                     vinitrd_start - dsi.v_start, page_array) )
+        goto error_out;
     if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
         goto error_out;
+
     vphysmap_start = v_end;
     if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
         goto error_out;
@@ -845,31 +882,8 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
-    {
-        PERROR("Could not allocate memory");
-        goto error_out;
-    }
-
-    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
-    {
-        PERROR("Could not get the page frame list");
-        goto error_out;
-    }
-
-    rc = (load_funcs.loadimage)(image, image_size,
-                           xc_handle, dom, page_array,
-                           &dsi);
-    if ( rc != 0 )
-        goto error_out;
-
-    if ( load_initrd(xc_handle, dom, initrd,
-                     vinitrd_start - dsi.v_start, page_array) )
-        goto error_out;
-
-    /* setup page tables */
 #if defined(__i386__)
-    if (dsi.pae_kernel != PAEKERN_no)
+    if ( dsi.pae_kernel != PAEKERN_no )
         rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
                                  dsi.v_start, v_end,
                                  page_array, vpt_start, vpt_end,
@@ -886,16 +900,16 @@ static int setup_guest(int xc_handle,
                             page_array, vpt_start, vpt_end,
                             shadow_mode_enabled);
 #endif
-    if (0 != rc)
-        goto error_out;
-
-#if defined(__i386__)
+    if ( rc != 0 )
+        goto error_out;
+
     /*
      * Pin down l2tab addr as page dir page - causes hypervisor to provide
      * correct protection for the page
      */
     if ( !shadow_mode_enabled )
     {
+#if defined(__i386__)
         if ( dsi.pae_kernel != PAEKERN_no )
         {
             if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
@@ -908,40 +922,24 @@ static int setup_guest(int xc_handle,
                            xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
                 goto error_out;
         }
-    }
+#elif defined(__x86_64__)
+        /*
+         * Pin down l4tab addr as page dir page - causes hypervisor to  provide
+         * correct protection for the page
+         */
+        if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
+                       xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
+            goto error_out;
 #endif
-
-#if defined(__x86_64__)
-    /*
-     * Pin down l4tab addr as page dir page - causes hypervisor to  provide
-     * correct protection for the page
-     */
-    if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
-                   xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
-        goto error_out;
-#endif
-
-    if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
-        goto error_out;
-
-    /* Write the phys->machine and machine->phys table entries. */
+    }
+
+    /* Write the phys->machine table entries (machine->phys already done). */
     physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
     physmap = physmap_e = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
         page_array[physmap_pfn++]);
-
     for ( count = 0; count < nr_pages; count++ )
     {
-        if ( xc_add_mmu_update(
-            xc_handle, mmu,
-            ((uint64_t)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
-            count) )
-        {
-            DPRINTF("m2p update failure p=%lx m=%"PRIx64"\n",
-                    count, (uint64_t)page_array[count]);
-            munmap(physmap, PAGE_SIZE);
-            goto error_out;
-        }
         *physmap_e++ = page_array[count];
         if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 )
         {
@@ -952,10 +950,6 @@ static int setup_guest(int xc_handle,
         }
     }
     munmap(physmap, PAGE_SIZE);
-
-    /* Send the page update requests down to the hypervisor. */
-    if ( xc_finish_mmu_updates(xc_handle, mmu) )
-        goto error_out;
 
     if ( shadow_mode_enabled )
     {
@@ -1063,10 +1057,6 @@ static int setup_guest(int xc_handle,
 
     munmap(shared_info, PAGE_SIZE);
 
-    /* Send the page update requests down to the hypervisor. */
-    if ( xc_finish_mmu_updates(xc_handle, mmu) )
-        goto error_out;
-
     hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
                                          &hypercall_page_defined);
     if ( hypercall_page_defined )
@@ -1082,7 +1072,6 @@ static int setup_guest(int xc_handle,
             goto error_out;
     }
 
-    free(mmu);
     free(page_array);
 
     *pvsi = vstartinfo_start;
@@ -1092,7 +1081,6 @@ static int setup_guest(int xc_handle,
     return 0;
 
  error_out:
-    free(mmu);
     free(page_array);
     return -1;
 }
@@ -1100,6 +1088,7 @@ static int setup_guest(int xc_handle,
 
 static int xc_linux_build_internal(int xc_handle,
                                    uint32_t domid,
+                                   unsigned int mem_mb,
                                    char *image,
                                    unsigned long image_size,
                                    struct initrd_info *initrd,
@@ -1114,8 +1103,7 @@ static int xc_linux_build_internal(int x
     struct xen_domctl launch_domctl;
     DECLARE_DOMCTL;
     int rc, i;
-    vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
-    unsigned long nr_pages;
+    struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt;
     unsigned long vstartinfo_start, vkern_entry, vstack_start;
     uint32_t      features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
 
@@ -1126,12 +1114,6 @@ static int xc_linux_build_internal(int x
             PERROR("Failed to parse configured features\n");
             goto error_out;
         }
-    }
-
-    if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 )
-    {
-        PERROR("Could not find total pages for domain");
-        goto error_out;
     }
 
 #ifdef VALGRIND
@@ -1157,7 +1139,7 @@ static int xc_linux_build_internal(int x
 
     if ( setup_guest(xc_handle, domid, image, image_size,
                      initrd,
-                     nr_pages,
+                     mem_mb << (20 - PAGE_SHIFT),
                      &vstartinfo_start, &vkern_entry,
                      &vstack_start, ctxt, cmdline,
                      domctl.u.getdomaininfo.shared_info_frame,
@@ -1253,6 +1235,7 @@ static int xc_linux_build_internal(int x
 
 int xc_linux_build_mem(int xc_handle,
                        uint32_t domid,
+                       unsigned int mem_mb,
                        const char *image_buffer,
                        unsigned long image_size,
                        const char *initrd,
@@ -1301,7 +1284,7 @@ int xc_linux_build_mem(int xc_handle,
         }
     }
 
-    sts = xc_linux_build_internal(xc_handle, domid, img_buf, img_len,
+    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len,
                                   &initrd_info, cmdline, features, flags,
                                   store_evtchn, store_mfn,
                                   console_evtchn, console_mfn);
@@ -1321,6 +1304,7 @@ int xc_linux_build_mem(int xc_handle,
 
 int xc_linux_build(int xc_handle,
                    uint32_t domid,
+                   unsigned int mem_mb,
                    const char *image_name,
                    const char *initrd_name,
                    const char *cmdline,
@@ -1350,7 +1334,6 @@ int xc_linux_build(int xc_handle,
             goto error_out;
         }
 
-        initrd_info.len = xc_get_filesz(fd);
         if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
         {
             PERROR("Could not allocate decompression state for initrd");
@@ -1358,7 +1341,7 @@ int xc_linux_build(int xc_handle,
         }
     }
 
-    sts = xc_linux_build_internal(xc_handle, domid, image, image_size,
+    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size,
                                   &initrd_info, cmdline, features, flags,
                                   store_evtchn, store_mfn,
                                   console_evtchn, console_mfn);
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_linux_save.c       Fri Nov 10 11:11:04 2006 -0700
@@ -978,12 +978,14 @@ int xc_linux_save(int xc_handle, int io_
             }
 
             if(!write_exact(io_fd, &batch, sizeof(unsigned int))) {
-                ERROR("Error when writing to state file (2)");
+                ERROR("Error when writing to state file (2) (errno %d)",
+                      errno);
                 goto out;
             }
 
             if(!write_exact(io_fd, pfn_type, sizeof(unsigned long)*j)) {
-                ERROR("Error when writing to state file (3)");
+                ERROR("Error when writing to state file (3) (errno %d)",
+                      errno);
                 goto out;
             }
 
@@ -1013,7 +1015,8 @@ int xc_linux_save(int xc_handle, int io_
                         goto out; 
 
                     if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
-                        ERROR("Error when writing to state file (4)");
+                        ERROR("Error when writing to state file (4)"
+                              " (errno %d)", errno);
                         goto out;
                     }
 
@@ -1021,7 +1024,8 @@ int xc_linux_save(int xc_handle, int io_
 
                     /* We have a normal page: just write it directly. */
                     if (ratewrite(io_fd, spage, PAGE_SIZE) != PAGE_SIZE) {
-                        ERROR("Error when writing to state file (5)");
+                        ERROR("Error when writing to state file (5)"
+                              " (errno %d)", errno);
                         goto out;
                     }
                 }
@@ -1056,7 +1060,8 @@ int xc_linux_save(int xc_handle, int io_
 
             /* send "-1" to put receiver into debug mode */
             if(!write_exact(io_fd, &minusone, sizeof(int))) {
-                ERROR("Error when writing to state file (6)");
+                ERROR("Error when writing to state file (6) (errno %d)",
+                      errno);
                 goto out;
             }
 
@@ -1110,7 +1115,7 @@ int xc_linux_save(int xc_handle, int io_
     /* Zero terminate */
     i = 0;
     if (!write_exact(io_fd, &i, sizeof(int))) {
-        ERROR("Error when writing to state file (6)");
+        ERROR("Error when writing to state file (6') (errno %d)", errno);
         goto out;
     }
 
@@ -1125,7 +1130,7 @@ int xc_linux_save(int xc_handle, int io_
         }
 
         if(!write_exact(io_fd, &j, sizeof(unsigned int))) {
-            ERROR("Error when writing to state file (6a)");
+            ERROR("Error when writing to state file (6a) (errno %d)", errno);
             goto out;
         }
 
@@ -1137,7 +1142,8 @@ int xc_linux_save(int xc_handle, int io_
             i++;
             if (j == 1024 || i == max_pfn) {
                 if(!write_exact(io_fd, &pfntab, sizeof(unsigned long)*j)) {
-                    ERROR("Error when writing to state file (6b)");
+                    ERROR("Error when writing to state file (6b) (errno %d)",
+                          errno);
                     goto out;
                 }
                 j = 0;
@@ -1170,7 +1176,7 @@ int xc_linux_save(int xc_handle, int io_
 
     if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
         !write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
-        ERROR("Error when writing to state file (1)");
+        ERROR("Error when writing to state file (1) (errno %d)", errno);
         goto out;
     }
 
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_misc.c     Fri Nov 10 11:11:04 2006 -0700
@@ -5,6 +5,7 @@
  */
 
 #include "xc_private.h"
+#include <xen/hvm/hvm_op.h>
 
 int xc_readconsolering(int xc_handle,
                        char **pbuffer,
@@ -89,6 +90,33 @@ int xc_perfc_control(int xc_handle,
     return rc;
 }
 
+int xc_hvm_set_irq_level(int xc_handle, domid_t dom, int irq, int level)
+{
+    DECLARE_HYPERCALL;
+    struct xen_hvm_set_irq_level arg;
+    int rc;
+
+    hypercall.op     = __HYPERVISOR_hvm_op;
+    hypercall.arg[0] = HVMOP_set_irq_level;
+    hypercall.arg[1] = (unsigned long)&arg;
+
+    arg.domid = dom;
+    arg.irq   = irq;
+    arg.level = level;
+
+    if ( mlock(&arg, sizeof(arg)) != 0 )
+    {
+        PERROR("Could not lock memory");
+        return -1;
+    }
+
+    rc = do_xen_hypercall(xc_handle, &hypercall);
+
+    safe_munlock(&arg, sizeof(arg));
+
+    return rc;
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_private.c  Fri Nov 10 11:11:04 2006 -0700
@@ -344,28 +344,6 @@ int xc_clear_domain_page(int xc_handle,
     return 0;
 }
 
-unsigned long xc_get_filesz(int fd)
-{
-    uint16_t sig;
-    uint32_t _sz = 0;
-    unsigned long sz;
-
-    lseek(fd, 0, SEEK_SET);
-    if ( read(fd, &sig, sizeof(sig)) != sizeof(sig) )
-        return 0;
-    sz = lseek(fd, 0, SEEK_END);
-    if ( sig == 0x8b1f ) /* GZIP signature? */
-    {
-        lseek(fd, -4, SEEK_END);
-        if ( read(fd, &_sz, 4) != 4 )
-            return 0;
-        sz = _sz;
-    }
-    lseek(fd, 0, SEEK_SET);
-
-    return sz;
-}
-
 void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
                    int xch, uint32_t dom, xen_pfn_t *parray,
                    unsigned long vstart)
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_private.h  Fri Nov 10 11:11:04 2006 -0700
@@ -158,4 +158,9 @@ int xc_map_foreign_ranges(int xc_handle,
 int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
                           privcmd_mmap_entry_t *entries, int nr);
 
+void *map_domain_va_core(unsigned long domfd, int cpu, void *guest_va,
+                         vcpu_guest_context_t *ctxt);
+int xc_waitdomain_core(int xc_handle, int domain, int *status,
+    int options, vcpu_guest_context_t *ctxt);
+
 #endif /* __XC_PRIVATE_H__ */
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_ptrace.c   Fri Nov 10 11:11:04 2006 -0700
@@ -36,8 +36,9 @@ static char *ptrace_names[] = {
 };
 #endif
 
-static int                      current_domid = -1;
-static int                      current_isfile;
+static int current_domid = -1;
+static int current_isfile;
+static int current_is_hvm;
 
 static uint64_t                 online_cpumap;
 static uint64_t                 regs_valid;
@@ -45,7 +46,6 @@ static vcpu_guest_context_t     ctxt[MAX
 
 extern int ffsll(long long int);
 #define FOREACH_CPU(cpumap, i)  for ( cpumap = online_cpumap; (i = 
ffsll(cpumap)); cpumap &= ~(1 << (index - 1)) )
-
 
 static int
 fetch_regs(int xc_handle, int cpu, int *online)
@@ -172,7 +172,7 @@ to_ma(int cpu,
 {
     unsigned long maddr = in_addr;
 
-    if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
+    if ( current_is_hvm && paging_enabled(&ctxt[cpu]) )
         maddr = page_array[maddr >> PAGE_SHIFT] << PAGE_SHIFT;
     return maddr;
 }
@@ -443,7 +443,7 @@ __xc_waitdomain(
         goto done;
     }
 
-    if ( !(domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED) )
+    if ( !(domctl.u.getdomaininfo.flags & XEN_DOMINF_paused) )
     {
         nanosleep(&ts,NULL);
         goto retry;
@@ -482,11 +482,11 @@ xc_ptrace(
     case PTRACE_PEEKTEXT:
     case PTRACE_PEEKDATA:
         if (current_isfile)
-            guest_va = (unsigned long *)map_domain_va_core(current_domid,
-                                cpu, addr, ctxt);
+            guest_va = (unsigned long *)map_domain_va_core(
+                current_domid, cpu, addr, ctxt);
         else
-            guest_va = (unsigned long *)map_domain_va(xc_handle,
-                                cpu, addr, PROT_READ);
+            guest_va = (unsigned long *)map_domain_va(
+                xc_handle, cpu, addr, PROT_READ);
         if ( guest_va == NULL )
             goto out_error;
         retval = *guest_va;
@@ -496,11 +496,11 @@ xc_ptrace(
     case PTRACE_POKEDATA:
         /* XXX assume that all CPUs have the same address space */
         if (current_isfile)
-            guest_va = (unsigned long *)map_domain_va_core(current_domid,
-                                cpu, addr, ctxt);
+            guest_va = (unsigned long *)map_domain_va_core(
+                current_domid, cpu, addr, ctxt);
         else
-            guest_va = (unsigned long *)map_domain_va(xc_handle,
-                                cpu, addr, PROT_READ|PROT_WRITE);
+            guest_va = (unsigned long *)map_domain_va(
+                xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
         if ( guest_va == NULL )
             goto out_error;
         *guest_va = (unsigned long)data;
@@ -590,10 +590,11 @@ xc_ptrace(
         retval = do_domctl(xc_handle, &domctl);
         if ( retval || (domctl.domain != current_domid) )
             goto out_error_domctl;
-        if ( domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
+        if ( domctl.u.getdomaininfo.flags & XEN_DOMINF_paused )
             IPRINTF("domain currently paused\n");
         else if ((retval = xc_domain_pause(xc_handle, current_domid)))
             goto out_error_domctl;
+        current_is_hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
         domctl.cmd = XEN_DOMCTL_setdebugging;
         domctl.domain = current_domid;
         domctl.u.setdebugging.enable = 1;
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xc_ptrace_core.c      Fri Nov 10 11:11:04 2006 -0700
@@ -7,6 +7,7 @@
 
 /* XXX application state */
 
+static int    current_is_hvm = 0;
 static long   nr_pages = 0;
 static unsigned long  *p2m_array = NULL;
 static unsigned long  *m2p_array = NULL;
@@ -24,8 +25,8 @@ map_mtop_offset(unsigned long ma)
 
 
 void *
-map_domain_va_core(unsigned long domfd, int cpu, void * guest_va,
-                        vcpu_guest_context_t *ctxt)
+map_domain_va_core(unsigned long domfd, int cpu, void *guest_va,
+                   vcpu_guest_context_t *ctxt)
 {
     unsigned long pde, page;
     unsigned long va = (unsigned long)guest_va;
@@ -55,7 +56,7 @@ map_domain_va_core(unsigned long domfd, 
     }
     if ((pde = cr3_virt[cpu][l2_table_offset_i386(va)]) == 0) /* logical 
address */
         return NULL;
-    if (ctxt[cpu].flags & VGCF_HVM_GUEST)
+    if (current_is_hvm)
         pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
     if (pde != pde_phys[cpu])
     {
@@ -71,7 +72,7 @@ map_domain_va_core(unsigned long domfd, 
     }
     if ((page = pde_virt[cpu][l1_table_offset_i386(va)]) == 0) /* logical 
address */
         return NULL;
-    if (ctxt[cpu].flags & VGCF_HVM_GUEST)
+    if (current_is_hvm)
         page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
     if (page != page_phys[cpu])
     {
@@ -104,17 +105,18 @@ xc_waitdomain_core(
     int i;
     xc_core_header_t header;
 
-    if (nr_pages == 0)
+    if ( nr_pages == 0 )
     {
-
         if (read(domfd, &header, sizeof(header)) != sizeof(header))
             return -1;
 
-        if (header.xch_magic != XC_CORE_MAGIC) {
-                IPRINTF("Magic number missmatch: 0x%08x (file) != "
-                                        " 0x%08x (code)\n", header.xch_magic,
-                                        XC_CORE_MAGIC);
-                return -1;
+        current_is_hvm = (header.xch_magic == XC_CORE_MAGIC_HVM);
+        if ( !current_is_hvm && (header.xch_magic != XC_CORE_MAGIC) )
+        {
+            IPRINTF("Magic number missmatch: 0x%08x (file) != "
+                    " 0x%08x (code)\n", header.xch_magic,
+                    XC_CORE_MAGIC);
+            return -1;
         }
 
         nr_pages = header.xch_nr_pages;
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xenctrl.h     Fri Nov 10 11:11:04 2006 -0700
@@ -47,10 +47,9 @@
 #define rmb() __asm__ __volatile__ ( "lfence" : : : "memory")
 #define wmb() __asm__ __volatile__ ( "" : : : "memory")
 #elif defined(__ia64__)
-/* FIXME */
-#define mb()
-#define rmb()
-#define wmb()
+#define mb()   __asm__ __volatile__ ("mf" ::: "memory")
+#define rmb()  __asm__ __volatile__ ("mf" ::: "memory")
+#define wmb()  __asm__ __volatile__ ("mf" ::: "memory")
 #elif defined(__powerpc__)
 /* XXX loosen these up later */
 #define mb()   __asm__ __volatile__ ("sync" : : : "memory")
@@ -113,25 +112,13 @@ typedef struct xc_core_header {
     unsigned int xch_pages_offset;
 } xc_core_header_t;
 
-#define XC_CORE_MAGIC 0xF00FEBED
+#define XC_CORE_MAGIC     0xF00FEBED
+#define XC_CORE_MAGIC_HVM 0xF00FEBEE
 
 #ifdef __linux__
 
 #include <sys/ptrace.h>
 #include <thread_db.h>
-
-void * map_domain_va_core(
-    unsigned long domfd,
-    int cpu,
-    void *guest_va,
-    vcpu_guest_context_t *ctxt);
-
-int xc_waitdomain_core(
-    int xc_handle,
-    int domain,
-    int *status,
-    int options,
-    vcpu_guest_context_t *ctxt);
 
 typedef void (*thr_ev_handler_t)(long);
 
@@ -158,11 +145,12 @@ int xc_waitdomain(
  * DOMAIN MANAGEMENT FUNCTIONS
  */
 
-typedef struct {
+typedef struct xc_dominfo {
     uint32_t      domid;
     uint32_t      ssidref;
     unsigned int  dying:1, crashed:1, shutdown:1,
-                  paused:1, blocked:1, running:1;
+                  paused:1, blocked:1, running:1,
+                  hvm:1;
     unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
     unsigned long nr_pages;
     unsigned long shared_info_frame;
@@ -177,6 +165,7 @@ int xc_domain_create(int xc_handle,
 int xc_domain_create(int xc_handle,
                      uint32_t ssidref,
                      xen_domain_handle_t handle,
+                     uint32_t flags,
                      uint32_t *pdomid);
 
 
@@ -677,4 +666,6 @@ evtchn_port_t xc_evtchn_pending(int xce_
  */
 int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
 
+int xc_hvm_set_irq_level(int xce_handle, domid_t dom, int irq, int level);
+
 #endif
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xenguest.h    Fri Nov 10 11:11:04 2006 -0700
@@ -48,8 +48,9 @@ int xc_linux_restore(int xc_handle, int 
  *
  * @parm xc_handle a handle to an open hypervisor interface
  * @parm domid the id of the domain
- * @param image_name name of the kernel image file
- * @param ramdisk_name name of the ramdisk image file
+ * @parm mem_mb memory size in megabytes
+ * @parm image_name name of the kernel image file
+ * @parm ramdisk_name name of the ramdisk image file
  * @parm cmdline command line string
  * @parm flags domain creation flags
  * @parm store_evtchn the store event channel for this domain to use
@@ -60,6 +61,7 @@ int xc_linux_restore(int xc_handle, int 
  */
 int xc_linux_build(int xc_handle,
                    uint32_t domid,
+                   unsigned int mem_mb,
                    const char *image_name,
                    const char *ramdisk_name,
                    const char *cmdline,
@@ -74,22 +76,24 @@ int xc_linux_build(int xc_handle,
  * This function will create a domain for a paravirtualized Linux
  * using buffers for kernel and initrd
  *
- * @param xc_handle a handle to an open hypervisor interface
- * @param domid the id of the domain
- * @param image_buffer buffer containing kernel image
- * @param image_size size of the kernel image buffer
- * @param initrd_buffer name of the ramdisk image file
- * @param initrd_size size of the ramdisk buffer
- * @param cmdline command line string
- * @param flags domain creation flags
- * @param store_evtchn the store event channel for this domain to use
- * @param store_mfn returned with the mfn of the store page
- * @param console_evtchn the console event channel for this domain to use
- * @param conole_mfn returned with the mfn of the console page
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the id of the domain
+ * @parm mem_mb memory size in megabytes
+ * @parm image_buffer buffer containing kernel image
+ * @parm image_size size of the kernel image buffer
+ * @parm initrd_buffer name of the ramdisk image file
+ * @parm initrd_size size of the ramdisk buffer
+ * @parm cmdline command line string
+ * @parm flags domain creation flags
+ * @parm store_evtchn the store event channel for this domain to use
+ * @parm store_mfn returned with the mfn of the store page
+ * @parm console_evtchn the console event channel for this domain to use
+ * @parm conole_mfn returned with the mfn of the console page
  * @return 0 on success, -1 on failure
  */
 int xc_linux_build_mem(int xc_handle,
                        uint32_t domid,
+                       unsigned int mem_mb,
                        const char *image_buffer,
                        unsigned long image_size,
                        const char *initrd_buffer,
@@ -109,7 +113,6 @@ int xc_hvm_build(int xc_handle,
                  unsigned int vcpus,
                  unsigned int pae,
                  unsigned int acpi,
-                 unsigned int apic,
                  unsigned int store_evtchn,
                  unsigned long *store_mfn);
 
@@ -121,7 +124,6 @@ int xc_hvm_build_mem(int xc_handle,
                      unsigned int vcpus,
                      unsigned int pae,
                      unsigned int acpi,
-                     unsigned int apic,
                      unsigned int store_evtchn,
                      unsigned long *store_mfn);
 
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xg_private.c  Fri Nov 10 11:11:04 2006 -0700
@@ -31,7 +31,7 @@ char *xc_read_image(const char *filename
 {
     int kernel_fd = -1;
     gzFile kernel_gfd = NULL;
-    char *image = NULL;
+    char *image = NULL, *tmp;
     unsigned int bytes;
 
     if ( (filename == NULL) || (size == NULL) )
@@ -43,33 +43,58 @@ char *xc_read_image(const char *filename
         goto out;
     }
 
-    if ( (*size = xc_get_filesz(kernel_fd)) == 0 )
-    {
-        PERROR("Could not read kernel image");
-        goto out;
-    }
-
     if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
     {
         PERROR("Could not allocate decompression state for state file");
         goto out;
     }
 
-    if ( (image = malloc(*size)) == NULL )
-    {
-        PERROR("Could not allocate memory for kernel image");
-        goto out;
-    }
-
-    if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
-    {
-        PERROR("Error reading kernel image, could not"
-               " read the whole image (%d != %ld).", bytes, *size);
-        free(image);
-        image = NULL;
-    }
+    *size = 0;
+
+#define CHUNK 1*1024*1024
+    while(1)
+    {
+           if ( (tmp = realloc(image, *size + CHUNK)) == NULL )
+           {
+                   PERROR("Could not allocate memory for kernel image");
+                   free(image);
+                   image = NULL;
+                   goto out;
+           }
+           image = tmp;
+
+           bytes = gzread(kernel_gfd, image + *size, CHUNK);
+           switch (bytes)
+           {
+           case -1:
+                   PERROR("Error reading kernel image");
+                   free(image);
+                   image = NULL;
+                   goto out;
+           case 0: /* EOF */
+                   goto out;
+           default:
+                   *size += bytes;
+                   break;
+           }
+    }
+#undef CHUNK
 
  out:
+    if ( *size == 0 )
+    {
+           PERROR("Could not read kernel image");
+           free(image);
+           image = NULL;
+    }
+    else if ( image )
+    {
+           /* Shrink allocation to fit image. */
+           tmp = realloc(image, *size);
+           if ( tmp )
+                   image = tmp;
+    }
+
     if ( kernel_gfd != NULL )
         gzclose(kernel_gfd);
     else if ( kernel_fd >= 0 )
@@ -171,7 +196,6 @@ __attribute__((weak)) int xc_hvm_build(
     unsigned int vcpus,
     unsigned int pae,
     unsigned int acpi,
-    unsigned int apic,
     unsigned int store_evtchn,
     unsigned long *store_mfn)
 {
diff -r 11b718eb22c9 -r ebed72718263 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/libxc/xg_private.h  Fri Nov 10 11:11:04 2006 -0700
@@ -193,8 +193,6 @@ int xc_copy_to_domain_page(int xc_handle
 int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
                             unsigned long dst_pfn, const char *src_page);
 
-unsigned long xc_get_filesz(int fd);
-
 void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
                    int xch, uint32_t dom, xen_pfn_t *parray,
                    unsigned long vstart);
diff -r 11b718eb22c9 -r ebed72718263 tools/pygrub/setup.py
--- a/tools/pygrub/setup.py     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/pygrub/setup.py     Fri Nov 10 11:11:04 2006 -0700
@@ -3,48 +3,27 @@ import os
 import os
 import sys
 
-extra_compile_args  = [ "-fno-strict-aliasing", "-Wall", "-Werror" ]
+extra_compile_args  = [ "-fno-strict-aliasing", "-Werror" ]
 
-fsys_mods = []
-fsys_pkgs = []
+XEN_ROOT = "../.."
 
-if os.path.exists("/usr/include/ext2fs/ext2_fs.h"):
-    ext2defines = []
-    cc = new_compiler()
-    cc.add_library("ext2fs")
-    if hasattr(cc, "has_function") and cc.has_function("ext2fs_open2"):
-        ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) )
-    else:
-        sys.stderr.write("WARNING: older version of e2fsprogs installed, not 
building full\n")
-        sys.stderr.write("         disk support for ext2.\n")
-        
-    ext2 = Extension("grub.fsys.ext2._pyext2",
-                     extra_compile_args = extra_compile_args,
-                     libraries = ["ext2fs"],
-                     define_macros = ext2defines,
-                     sources = ["src/fsys/ext2/ext2module.c"])
-    fsys_mods.append(ext2)
-    fsys_pkgs.append("grub.fsys.ext2")
+fsimage = Extension("fsimage",
+    extra_compile_args = extra_compile_args,
+    include_dirs = [ XEN_ROOT + "/tools/libfsimage/common/" ],
+    library_dirs = [ XEN_ROOT + "/tools/libfsimage/common/" ],
+    libraries = ["fsimage"],
+    sources = ["src/fsimage/fsimage.c"])
 
-if os.path.exists("/usr/include/reiserfs/reiserfs.h"):
-    reiser = Extension("grub.fsys.reiser._pyreiser",
-                     extra_compile_args = extra_compile_args,
-                     libraries = ["reiserfs"],
-                     sources = ["src/fsys/reiser/reisermodule.c"])
-    fsys_mods.append(reiser)
-    fsys_pkgs.append("grub.fsys.reiser")
+pkgs = [ 'grub' ]
 
-pkgs = ['grub', 'grub.fsys']
-pkgs.extend(fsys_pkgs)
 setup(name='pygrub',
       version='0.3',
       description='Boot loader that looks a lot like grub for Xen',
       author='Jeremy Katz',
       author_email='katzj@xxxxxxxxxx',
       license='GPL',
-      package_dir={'grub': 'src'},
+      package_dir={'grub': 'src', 'fsimage': 'src'},
       scripts = ["src/pygrub"],
       packages=pkgs,
-      ext_modules = fsys_mods
+      ext_modules = [ fsimage ]
       )
-               
diff -r 11b718eb22c9 -r ebed72718263 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/pygrub/src/pygrub   Fri Nov 10 11:11:04 2006 -0700
@@ -22,8 +22,8 @@ import getopt
 
 sys.path = [ '/usr/lib/python' ] + sys.path
 
+import fsimage
 import grub.GrubConf
-import grub.fsys
 
 PYGRUB_VER = 0.5
 
@@ -113,17 +113,21 @@ class GrubLineEditor(curses.textpad.Text
         elif ch == curses.ascii.SOH:  # ^a
             self.pos = 0
         elif ch in (curses.ascii.STX,curses.KEY_LEFT):
-            self.pos -= 1
+            if self.pos > 0:
+                self.pos -= 1
         elif ch in (curses.ascii.BS,curses.KEY_BACKSPACE):
             if self.pos > 0:
                 self.pos -= 1
+                if self.pos < len(self.line):
+                    self.line.pop(self.pos)
+        elif ch == curses.ascii.EOT:                           # ^d
+            if self.pos < len(self.line):
                 self.line.pop(self.pos)
-        elif ch == curses.ascii.EOT:                           # ^d
-            self.line.pop(self.pos)
         elif ch == curses.ascii.ENQ:                           # ^e
             self.pos = len(self.line)
         elif ch in (curses.ascii.ACK, curses.KEY_RIGHT):
-            self.pos +=1
+            if self.pos < len(self.line):
+                self.pos +=1
         elif ch == curses.ascii.VT:                            # ^k
             self.line = self.line[:self.pos]
         else:
@@ -313,25 +317,21 @@ class Grub:
                 raise RuntimeError, "Unable to find active partition on disk"
 
         # open the image and read the grub config
-        fs = None
-        for fstype in grub.fsys.fstypes.values():
-            if fstype.sniff_magic(fn, offset):
-                fs = fstype.open_fs(fn, offset)
-                break
+        fs = fsimage.open(fn, offset)
 
         if fs is not None:
             grubfile = None
             for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
                       "/grub/menu.lst", "/grub/grub.conf"):
-                if fs.file_exist(f):
+                if fs.file_exists(f):
                     grubfile = f
                     break
             if grubfile is None:
                 raise RuntimeError, "we couldn't find grub config file in the 
image provided."
             f = fs.open_file(grubfile)
             buf = f.read()
-            f.close()
-            fs.close()
+            del f
+            del fs
             # then parse the grub config
             self.cf.parse(buf)
         else:
@@ -511,14 +511,7 @@ if __name__ == "__main__":
             raise RuntimeError, "Unable to find active partition on disk"
 
     # read the kernel and initrd onto the hostfs
-    fs = None
-    for fstype in grub.fsys.fstypes.values():
-        if fstype.sniff_magic(file, offset):
-            fs = fstype.open_fs(file, offset)
-            break
-
-    if fs is None:
-        raise RuntimeError, "Unable to open filesystem"
+    fs = fsimage.open(file, offset)
 
     kernel = fs.open_file(img.kernel[1],).read()
     (tfd, fn) = tempfile.mkstemp(prefix="vmlinuz.", dir="/var/lib/xen")
diff -r 11b718eb22c9 -r ebed72718263 tools/python/setup.py
--- a/tools/python/setup.py     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/setup.py     Fri Nov 10 11:11:04 2006 -0700
@@ -4,8 +4,7 @@ import os
 
 XEN_ROOT = "../.."
 
-extra_compile_args  = [ "-fno-strict-aliasing", "-Wall", "-Werror" ]
-
+extra_compile_args  = [ "-fno-strict-aliasing", "-Werror" ]
 
 include_dirs = [ XEN_ROOT + "/tools/libxc",
                  XEN_ROOT + "/tools/xenstore",
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Nov 10 11:11:04 2006 -0700
@@ -65,18 +65,17 @@ static PyObject *pyxc_domain_create(XcOb
                                     PyObject *args,
                                     PyObject *kwds)
 {
-    uint32_t dom = 0;
-    int      ret, i;
-    uint32_t ssidref = 0;
+    uint32_t dom = 0, ssidref = 0, flags = 0;
+    int      ret, i, hvm = 0;
     PyObject *pyhandle = NULL;
     xen_domain_handle_t handle = { 
         0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
         0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
 
-    static char *kwd_list[] = { "dom", "ssidref", "handle", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiO", kwd_list,
-                                      &dom, &ssidref, &pyhandle))
+    static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
+                                      &dom, &ssidref, &pyhandle, &hvm))
         return NULL;
 
     if ( pyhandle != NULL )
@@ -94,7 +93,11 @@ static PyObject *pyxc_domain_create(XcOb
         }
     }
 
-    if ( (ret = xc_domain_create(self->xc_handle, ssidref, handle, &dom)) < 0 )
+    if ( hvm )
+        flags |= XEN_DOMCTL_CDF_hvm_guest;
+
+    if ( (ret = xc_domain_create(self->xc_handle, ssidref,
+                                 handle, flags, &dom)) < 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return PyInt_FromLong(dom);
@@ -144,7 +147,7 @@ static PyObject *pyxc_vcpu_setaffinity(X
     uint64_t  cpumap = ~0ULL;
     PyObject *cpulist = NULL;
 
-    static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL };
+    static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list, 
                                       &dom, &vcpu, &cpulist) )
@@ -171,7 +174,7 @@ static PyObject *pyxc_domain_setcpuweigh
     uint32_t dom;
     float cpuweight = 1;
 
-    static char *kwd_list[] = { "dom", "cpuweight", NULL };
+    static char *kwd_list[] = { "domid", "cpuweight", NULL };
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list, 
                                       &dom, &cpuweight) )
@@ -254,11 +257,12 @@ static PyObject *pyxc_domain_getinfo(XcO
         PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
         for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
             PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
-        info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
+        info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
                                   ",s:l,s:L,s:l,s:i,s:i}",
-                                  "dom",       info[i].domid,
+                                  "domid",       info[i].domid,
                                   "online_vcpus", info[i].nr_online_vcpus,
                                   "max_vcpu_id", info[i].max_vcpu_id,
+                                  "hvm",       info[i].hvm,
                                   "dying",     info[i].dying,
                                   "crashed",   info[i].crashed,
                                   "shutdown",  info[i].shutdown,
@@ -291,7 +295,7 @@ static PyObject *pyxc_vcpu_getinfo(XcObj
     int rc, i;
     uint64_t cpumap;
 
-    static char *kwd_list[] = { "dom", "vcpu", NULL };
+    static char *kwd_list[] = { "domid", "vcpu", NULL };
     
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
                                       &dom, &vcpu) )
@@ -331,24 +335,25 @@ static PyObject *pyxc_linux_build(XcObje
     char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
     int flags = 0;
     int store_evtchn, console_evtchn;
+    unsigned int mem_mb;
     unsigned long store_mfn = 0;
     unsigned long console_mfn = 0;
 
-    static char *kwd_list[] = { "dom", "store_evtchn",
+    static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
                                 "console_evtchn", "image",
                                 /* optional */
                                 "ramdisk", "cmdline", "flags",
                                 "features", NULL };
 
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssis", kwd_list,
-                                      &dom, &store_evtchn,
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
+                                      &dom, &store_evtchn, &mem_mb,
                                       &console_evtchn, &image,
                                       /* optional */
                                       &ramdisk, &cmdline, &flags,
                                       &features) )
         return NULL;
 
-    if ( xc_linux_build(self->xc_handle, dom, image,
+    if ( xc_linux_build(self->xc_handle, dom, mem_mb, image,
                         ramdisk, cmdline, features, flags,
                         store_evtchn, &store_mfn,
                         console_evtchn, &console_mfn) != 0 ) {
@@ -372,19 +377,18 @@ static PyObject *pyxc_hvm_build(XcObject
     int vcpus = 1;
     int pae  = 0;
     int acpi = 0;
-    int apic = 0;
     unsigned long store_mfn = 0;
 
-    static char *kwd_list[] = { "dom", "store_evtchn", "memsize", "image",
-                                "vcpus", "pae", "acpi", "apic",
-                                NULL };
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisiiii", kwd_list,
+    static char *kwd_list[] = { "domid", "store_evtchn",
+                               "memsize", "image", "vcpus", "pae", "acpi",
+                               NULL };
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisiii", kwd_list,
                                       &dom, &store_evtchn, &memsize,
-                                      &image, &vcpus, &pae, &acpi, &apic) )
+                                      &image, &vcpus, &pae, &acpi) )
         return NULL;
 
     if ( xc_hvm_build(self->xc_handle, dom, memsize, image,
-                      vcpus, pae, acpi, apic, store_evtchn, &store_mfn) != 0 )
+                      vcpus, pae, acpi, store_evtchn, &store_mfn) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
     return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
@@ -397,7 +401,7 @@ static PyObject *pyxc_evtchn_alloc_unbou
     uint32_t dom, remote_dom;
     int port;
 
-    static char *kwd_list[] = { "dom", "remote_dom", NULL };
+    static char *kwd_list[] = { "domid", "remote_dom", NULL };
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
                                       &dom, &remote_dom) )
@@ -416,7 +420,7 @@ static PyObject *pyxc_physdev_pci_access
     uint32_t dom;
     int bus, dev, func, enable, ret;
 
-    static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
+    static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL 
};
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list, 
                                       &dom, &bus, &dev, &func, &enable) )
@@ -557,7 +561,7 @@ static PyObject *pyxc_sedf_domain_set(Xc
     uint32_t domid;
     uint64_t period, slice, latency;
     uint16_t extratime, weight;
-    static char *kwd_list[] = { "dom", "period", "slice",
+    static char *kwd_list[] = { "domid", "period", "slice",
                                 "latency", "extratime", "weight",NULL };
     
     if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list, 
@@ -586,7 +590,7 @@ static PyObject *pyxc_sedf_domain_get(Xc
         return PyErr_SetFromErrno(xc_error);
 
     return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
-                         "domain",    domid,
+                         "domid",    domid,
                          "period",    period,
                          "slice",     slice,
                          "latency",   latency,
@@ -647,6 +651,15 @@ static PyObject *pyxc_shadow_mem_control
     return Py_BuildValue("i", mbarg);
 }
 
+static PyObject *pyxc_sched_id_get(XcObject *self) {
+    
+    int sched_id;
+    if (xc_sched_id(self->xc_handle, &sched_id) != 0)
+        return PyErr_SetFromErrno(xc_error);
+
+    return Py_BuildValue("i", sched_id);
+}
+
 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
                                               PyObject *args,
                                               PyObject *kwds)
@@ -654,7 +667,7 @@ static PyObject *pyxc_sched_credit_domai
     uint32_t domid;
     uint16_t weight;
     uint16_t cap;
-    static char *kwd_list[] = { "dom", "weight", "cap", NULL };
+    static char *kwd_list[] = { "domid", "weight", "cap", NULL };
     static char kwd_type[] = "I|HH";
     struct xen_domctl_sched_credit sdom;
     
@@ -714,7 +727,7 @@ static PyObject *pyxc_domain_memory_incr
     unsigned int extent_order = 0 , address_bits = 0;
     unsigned long nr_extents;
 
-    static char *kwd_list[] = { "dom", "mem_kb", "extent_order", 
"address_bits", NULL };
+    static char *kwd_list[] = { "domid", "mem_kb", "extent_order", 
"address_bits", NULL };
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list, 
                                       &dom, &mem_kb, &extent_order, 
&address_bits) )
@@ -739,7 +752,7 @@ static PyObject *pyxc_domain_ioport_perm
     uint32_t dom;
     int first_port, nr_ports, allow_access, ret;
 
-    static char *kwd_list[] = { "dom", "first_port", "nr_ports", 
"allow_access", NULL };
+    static char *kwd_list[] = { "domid", "first_port", "nr_ports", 
"allow_access", NULL };
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list, 
                                       &dom, &first_port, &nr_ports, 
&allow_access) )
@@ -762,7 +775,7 @@ static PyObject *pyxc_domain_irq_permiss
     uint32_t dom;
     int pirq, allow_access, ret;
 
-    static char *kwd_list[] = { "dom", "pirq", "allow_access", NULL };
+    static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list, 
                                       &dom, &pirq, &allow_access) )
@@ -785,7 +798,7 @@ static PyObject *pyxc_domain_iomem_permi
     uint32_t dom;
     unsigned long first_pfn, nr_pfns, allow_access, ret;
 
-    static char *kwd_list[] = { "dom", "first_pfn", "nr_pfns", "allow_access", 
NULL };
+    static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", 
"allow_access", NULL };
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list, 
                                       &dom, &first_pfn, &nr_pfns, 
&allow_access) )
@@ -975,6 +988,12 @@ static PyMethodDef pyxc_methods[] = {
       " image   [str]:      Name of HVM loader image file.\n"
       " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "sched_id_get",
+      (PyCFunction)pyxc_sched_id_get,
+      METH_NOARGS, "\n"
+      "Get the current scheduler type in use.\n"
+      "Returns: [int] sched_id.\n" },    
 
     { "sedf_domain_set",
       (PyCFunction)pyxc_sedf_domain_set,
@@ -1242,6 +1261,11 @@ PyMODINIT_FUNC initxc(void)
 
     Py_INCREF(xc_error);
     PyModule_AddObject(m, "Error", xc_error);
+
+    /* Expose some libxc constants to Python */
+    PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
+    PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
+
 }
 
 
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/util/blkif.py
--- a/tools/python/xen/util/blkif.py    Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/util/blkif.py    Fri Nov 10 11:11:04 2006 -0700
@@ -21,11 +21,17 @@ def blkdev_name_to_number(name):
     try:
         return os.stat(n).st_rdev
     except Exception, ex:
-        log.debug("exception looking up device number for %s: %s", name, ex)
         pass
 
-    if re.match( '/dev/sd[a-p]([1-9]|1[0-5])?', n):
-        return 8 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:] or 0)
+    scsi_major = [ 8, 65, 66, 67, 68, 69, 70, 71, 128, 129, 130, 131, 132, 
133, 134, 135 ]
+    if re.match( '/dev/sd[a-z]([1-9]|1[0-5])?$', n):
+        major = scsi_major[(ord(n[7:8]) - ord('a')) / 16]
+        minor = ((ord(n[7:8]) - ord('a')) % 16) * 16 + int(n[8:] or 0)
+        return major * 256 + minor
+    if re.match( '/dev/sd[a-i][a-z]([1-9]|1[0-5])?$', n):
+        major = scsi_major[((ord(n[7:8]) - ord('a') + 1) * 26 + (ord(n[8:9]) - 
ord('a'))) / 16 ]
+        minor = (((ord(n[7:8]) - ord('a') + 1 ) * 26 + (ord(n[8:9]) - 
ord('a'))) % 16) * 16 + int(n[9:] or 0)
+        return major * 256 + minor
 
     if re.match( '/dev/hd[a-t]([1-9]|[1-5][0-9]|6[0-3])?', n):
         ide_majors = [ 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 ]
@@ -53,7 +59,7 @@ def blkdev_segment(name):
     """
     val = None
     n = blkdev_name_to_number(name)
-    if n:
+    if not n is None:
         val = { 'device'       : n,
                 'start_sector' : long(0),
                 'nr_sectors'   : long(1L<<63),
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py       Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/util/xmlrpclib2.py       Fri Nov 10 11:11:04 2006 -0700
@@ -21,11 +21,11 @@ An enhanced XML-RPC client/server interf
 """
 
 import string
-import types
 import fcntl
+from types import *
+    
 
 from httplib import HTTPConnection, HTTP
-from xmlrpclib import Transport
 from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
 import SocketServer
 import xmlrpclib, socket, os, stat
@@ -39,6 +39,23 @@ except ImportError:
     # SSHTransport is disabled on Python <2.4, because it uses the subprocess
     # package.
     ssh_enabled = False
+
+#
+# Convert all integers to strings as described in the Xen API
+#
+
+
+def stringify(value):
+    if isinstance(value, IntType) and not isinstance(value, BooleanType):
+        return str(value)
+    elif isinstance(value, DictType):
+        for k, v in value.items():
+            value[k] = stringify(v)
+        return value
+    elif isinstance(value, (TupleType, ListType)):
+        return [stringify(v) for v in value]
+    else:
+        return value
 
 
 # A new ServerProxy that also supports httpu urls.  An http URL comes in the
@@ -81,18 +98,18 @@ class HTTPUnix(HTTP):
 class HTTPUnix(HTTP):
     _connection_class = HTTPUnixConnection
 
-class UnixTransport(Transport):
+class UnixTransport(xmlrpclib.Transport):
     def request(self, host, handler, request_body, verbose=0):
         self.__handler = handler
-        return Transport.request(self, host, '/RPC2', request_body, verbose)
+        return xmlrpclib.Transport.request(self, host, '/RPC2',
+                                           request_body, verbose)
     def make_connection(self, host):
         return HTTPUnix(self.__handler)
 
 
 # See _marshalled_dispatch below.
 def conv_string(x):
-    if (isinstance(x, types.StringType) or
-        isinstance(x, unicode)):
+    if isinstance(x, StringTypes):
         s = string.replace(x, "'", r"\047")
         exec "s = '" + s + "'"
         return s
@@ -134,7 +151,7 @@ class TCPXMLRPCServer(SocketServer.Threa
     allow_reuse_address = True
 
     def __init__(self, addr, requestHandler=XMLRPCRequestHandler,
-                 logRequests=1):
+                 logRequests = 1):
         SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests)
 
         flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
@@ -169,8 +186,7 @@ class TCPXMLRPCServer(SocketServer.Threa
             # to transmit the string using Python encoding.
             # Thanks to David Mertz <mertz@xxxxxxxxx> for the trick (buried
             # in xml_pickle.py).
-            if (isinstance(response, types.StringType) or
-                isinstance(response, unicode)):
+            if isinstance(response, StringTypes):
                 response = repr(response)[1:-1]
 
             response = (response,)
@@ -201,7 +217,7 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
 class UnixXMLRPCServer(TCPXMLRPCServer):
     address_family = socket.AF_UNIX
 
-    def __init__(self, addr, logRequests):
+    def __init__(self, addr, logRequests = 1):
         parent = os.path.dirname(addr)
         if os.path.exists(parent):
             os.chown(parent, os.geteuid(), os.getegid())
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/Args.py
--- a/tools/python/xen/xend/Args.py     Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/Args.py     Fri Nov 10 11:11:04 2006 -0700
@@ -18,7 +18,7 @@ import types
 import types
 import StringIO
 
-import sxp
+from xen.xend import sxp
 
 class ArgError(StandardError):
     pass
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/PrettyPrint.py
--- a/tools/python/xen/xend/PrettyPrint.py      Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/PrettyPrint.py      Fri Nov 10 11:11:04 2006 -0700
@@ -22,7 +22,7 @@ import sys
 import sys
 import types
 import StringIO
-import sxp
+from xen.xend import sxp
 
 class PrettyItem:
 
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendBootloader.py   Fri Nov 10 11:11:04 2006 -0700
@@ -14,8 +14,8 @@
 
 import os, select, errno
 import random
-import sxp
 import shlex
+from xen.xend import sxp
 
 from XendLogging import log
 from XendError import VmError
@@ -38,7 +38,7 @@ def bootloader(blexec, disk, quiet = 0, 
         raise VmError(msg)
 
     while True:
-        fifo = "/var/lib/xen/xenbl.%s" %(random.randint(0, 32000),)
+        fifo = "/var/lib/xen/xenbl.%s" % random.randint(0, 32000)
         if not os.path.exists(fifo):
             break
     os.mkfifo(fifo, 0600)
@@ -48,7 +48,7 @@ def bootloader(blexec, disk, quiet = 0, 
         args = [ blexec ]
         if quiet:
             args.append("-q")
-        args.append("--output=%s" %(fifo,))
+        args.append("--output=%s" % fifo)
         if blargs is not None:
             args.extend(shlex.split(blargs))
         args.append(disk)
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendCheckpoint.py   Fri Nov 10 11:11:04 2006 -0700
@@ -8,21 +8,18 @@ import os
 import os
 import re
 import string
-import sxp
 import threading
 from struct import pack, unpack, calcsize
 
 from xen.util.xpopen import xPopen3
-
 import xen.util.auxbin
-
 import xen.lowlevel.xc
 
-import balloon
-from XendError import XendError
-from XendLogging import log
-from XendDomainInfo import DEV_MIGRATE_STEP1, DEV_MIGRATE_STEP2
-from XendDomainInfo import DEV_MIGRATE_STEP3
+from xen.xend import balloon, sxp
+from xen.xend.XendError import XendError
+from xen.xend.XendLogging import log
+from xen.xend.XendConstants import *
+from xen.xend.XendConfig import XendConfig
 
 SIGNATURE = "LinuxGuestRecord"
 XC_SAVE = "xc_save"
@@ -43,13 +40,13 @@ def read_exact(fd, size, errmsg):
 def read_exact(fd, size, errmsg):
     buf  = '' 
     while size != 0: 
-        str = os.read(fd, size)
-        if not len(str):
+        readstr = os.read(fd, size)
+        if not len(readstr):
             log.error("read_exact: EOF trying to read %d (buf='%s')" % \
                       (size, buf))
             raise XendError(errmsg)
-        size = size - len(str)
-        buf  = buf + str
+        size = size - len(readstr)
+        buf  = buf + readstr
     return buf
 
 
@@ -111,7 +108,7 @@ def save(fd, dominfo, network, live, dst
         raise Exception, exn
 
 
-def restore(xd, fd):
+def restore(xd, fd, dominfo = None):
     signature = read_exact(fd, len(SIGNATURE),
         "not a valid guest state file: signature read")
     if signature != SIGNATURE:
@@ -131,7 +128,11 @@ def restore(xd, fd):
 
     vmconfig = p.get_val()
 
-    dominfo = xd.restore_(vmconfig)
+    if dominfo:
+        dominfo.update(XendConfig(sxp = vmconfig), refresh = False)
+        dominfo.resume()
+    else:
+        dominfo = xd.restore_(vmconfig)
 
     store_port   = dominfo.getStorePort()
     console_port = dominfo.getConsolePort()
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py       Fri Nov 10 11:11:04 2006 -0700
@@ -22,45 +22,60 @@
  Needs to be persistent for one uptime.
 """
 
-import logging
 import os
+import shutil
 import socket
-import sys
 import threading
 
 import xen.lowlevel.xc
 
-import XendDomainInfo
-
-from xen.xend import XendRoot
-from xen.xend import XendCheckpoint
+
+from xen.xend import XendRoot, XendCheckpoint, XendDomainInfo
+from xen.xend.PrettyPrint import prettyprint
+from xen.xend.XendConfig import XendConfig
 from xen.xend.XendError import XendError, XendInvalidDomain
 from xen.xend.XendLogging import log
+from xen.xend.XendConstants import XS_VMROOT
+from xen.xend.XendConstants import DOM_STATE_HALTED, DOM_STATE_RUNNING
+
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xswatch import xswatch
 from xen.util import security
-
+from xen.xend import uuid
 
 xc = xen.lowlevel.xc.xc()
-xroot = XendRoot.instance()
-
+xroot = XendRoot.instance() 
 
 __all__ = [ "XendDomain" ]
 
-PRIV_DOMAIN = 0
-VMROOT = '/vm/'
-
+CACHED_CONFIG_FILE = 'config.sxp'
+CHECK_POINT_FILE = 'checkpoint.chk'
+DOM0_UUID = "00000000-0000-0000-0000-000000000000"
+DOM0_NAME = "Domain-0"
+DOM0_ID   = 0
 
 class XendDomain:
     """Index of all domains. Singleton.
+
+    @ivar domains: map of domains indexed by domid
+    @type domains: dict of XendDomainInfo
+    @ivar managed_domains: domains that are not running and managed by Xend
+    @type managed_domains: dict of XendDomainInfo indexed by uuid
+    @ivar domains_lock: lock that must be held when manipulating self.domains
+    @type domains_lock: threaading.RLock
+    @ivar _allow_new_domains: Flag to set that allows creating of new domains.
+    @type _allow_new_domains: boolean
+    
     """
 
-    ## public:
-    
     def __init__(self):
         self.domains = {}
+        self.managed_domains = {}
         self.domains_lock = threading.RLock()
 
+        # xen api instance vars
+        # TODO: nothing uses this at the moment
+        self._allow_new_domains = True
 
     # This must be called only the once, by instance() below.  It is separate
     # from the constructor because XendDomainInfo calls back into this class
@@ -68,85 +83,277 @@ class XendDomain:
     # instance() must be able to return a valid instance of this class even
     # during this initialisation.
     def init(self):
-        xstransact.Mkdir(VMROOT)
-        xstransact.SetPermissions(VMROOT, { 'dom' : PRIV_DOMAIN })
-
-        self.domains_lock.acquire()
-        try:
-            self._add_domain(
-                XendDomainInfo.recreate(self.xen_domains()[PRIV_DOMAIN],
-                                        True))
-            self.dom0_setup()
+        """Singleton initialisation function."""
+
+        dom_path = self._managed_path()
+        try:
+            os.stat(dom_path)
+        except OSError:
+            log.info("Making %s", dom_path)
+            os.makedirs(dom_path, 0755)
+
+        xstransact.Mkdir(XS_VMROOT)
+        xstransact.SetPermissions(XS_VMROOT, {'dom': DOM0_ID})
+
+        self.domains_lock.acquire()
+        try:
+            try:
+                dom0info = [d for d in self._running_domains() \
+                            if d.get('domid') == DOM0_ID][0]
+                
+                dom0info['name'] = DOM0_NAME
+                dom0 = XendDomainInfo.recreate(dom0info, True)
+                self._add_domain(dom0)
+            except IndexError:
+                raise XendError('Unable to find Domain 0')
+            
+            self._setDom0CPUCount()
 
             # This watch registration needs to be before the refresh call, so
             # that we're sure that we haven't missed any releases, but inside
             # the domains_lock, as we don't want the watch to fire until after
             # the refresh call has completed.
-            xswatch("@introduceDomain", self.onChangeDomain)
-            xswatch("@releaseDomain",   self.onChangeDomain)
+            xswatch("@introduceDomain", self._on_domains_changed)
+            xswatch("@releaseDomain",   self._on_domains_changed)
+
+            self._init_domains()
+        finally:
+            self.domains_lock.release()
+
+    
+    def _on_domains_changed(self, _):
+        """ Callback method when xenstore changes.
+
+        Calls refresh which will keep the local cache of domains
+        in sync.
+
+        @rtype: int
+        @return: 1
+        """
+        self.domains_lock.acquire()
+        try:
+            self._refresh()
+        finally:
+            self.domains_lock.release()
+        return 1
+
+    def _init_domains(self):
+        """Does the initial scan of managed and active domains to
+        populate self.domains.
+
+        Note: L{XendDomainInfo._checkName} will call back into XendDomain
+        to make sure domain name is not a duplicate.
+
+        """
+        self.domains_lock.acquire()
+        try:
+            running = self._running_domains()
+            managed = self._managed_domains()
+
+            # add all active domains
+            for dom in running:
+                if dom['dying'] == 1:
+                    log.warn('Ignoring dying domain %d from now on' %
+                             dom['domid'])
+                    continue
+
+                if dom['domid'] != DOM0_ID:
+                    try:
+                        new_dom = XendDomainInfo.recreate(dom, False)
+                        self._add_domain(new_dom)
+                    except Exception:
+                        log.exception("Failed to create reference to running "
+                                      "domain id: %d" % dom['domid'])
+
+            # add all managed domains as dormant domains.
+            for dom in managed:
+                dom_uuid = dom.get('uuid')
+                if not dom_uuid:
+                    continue
+                
+                dom_name = dom.get('name', 'Domain-%s' % dom_uuid)
+                try:
+                    running_dom = self.domain_lookup_nr(dom_name)
+                    if not running_dom:
+                        # instantiate domain if not started.
+                        new_dom = XendDomainInfo.createDormant(dom)
+                        self._managed_domain_register(new_dom)
+                    else:
+                        self._managed_domain_register(running_dom)
+                except Exception:
+                    log.exception("Failed to create reference to managed "
+                                  "domain: %s" % dom_name)
+
+        finally:
+            self.domains_lock.release()
+
+
+    # -----------------------------------------------------------------
+    # Getting managed domains storage path names
+
+    def _managed_path(self, domuuid = None):
+        """Returns the path of the directory where managed domain
+        information is stored.
+
+        @keyword domuuid: If not None, will return the path to the domain
+                          otherwise, will return the path containing
+                          the directories which represent each domain.
+        @type: None or String.
+        @rtype: String
+        @return: Path.
+        """
+        dom_path = xroot.get_xend_domains_path()
+        if domuuid:
+            dom_path = os.path.join(dom_path, domuuid)
+        return dom_path
+
+    def _managed_config_path(self, domuuid):
+        """Returns the path to the configuration file of a managed domain.
+
+        @param domname: Domain uuid
+        @type domname: String
+        @rtype: String
+        @return: path to config file.
+        """
+        return os.path.join(self._managed_path(domuuid), CACHED_CONFIG_FILE)
+
+    def _managed_check_point_path(self, domuuid):
+        """Returns absolute path to check point file for managed domain.
+        
+        @param domuuid: Name of managed domain
+        @type domname: String
+        @rtype: String
+        @return: Path
+        """
+        return os.path.join(self._managed_path(domuuid), CHECK_POINT_FILE)
+
+    def _managed_config_remove(self, domuuid):
+        """Removes a domain configuration from managed list
+
+        @param domuuid: Name of managed domain
+        @type domname: String
+        @raise XendError: fails to remove the domain.
+        """
+        config_path = self._managed_path(domuuid)
+        try:
+            if os.path.exists(config_path) and os.path.isdir(config_path):
+                shutil.rmtree(config_path)
+        except IOError:
+            log.exception('managed_config_remove failed removing conf')
+            raise XendError("Unable to remove managed configuration"
+                            " for domain: %s" % domuuid)            
+
+    def managed_config_save(self, dominfo):
+        """Save a domain's configuration to disk
+        
+        @param domninfo: Managed domain to save.
+        @type dominfo: XendDomainInfo
+        @raise XendError: fails to save configuration.
+        @rtype: None
+        """
+        if not self.is_domain_managed(dominfo):
+            return # refuse to save configuration this domain isn't managed
+        
+        if dominfo:
+            domains_dir = self._managed_path()
+            dom_uuid = dominfo.get_uuid()            
+            domain_config_dir = self._managed_path(dom_uuid)
+        
+            # make sure the domain dir exists
+            if not os.path.exists(domains_dir):
+                os.makedirs(domains_dir, 0755)
+            elif not os.path.isdir(domains_dir):
+                log.error("xend_domain_dir is not a directory.")
+                raise XendError("Unable to save managed configuration "
+                                "because %s is not a directory." %
+                                domains_dir)
             
-            self.refresh(True)
-        finally:
-            self.domains_lock.release()
-
-
-    def list(self):
-        """Get list of domain objects.
-
-        @return: domain objects
-        """
-        self.domains_lock.acquire()
-        try:
-            self.refresh()
-            return self.domains.values()
-        finally:
-            self.domains_lock.release()
-
-
-    def list_sorted(self):
-        """Get list of domain objects, sorted by name.
-
-        @return: domain objects
-        """
-        doms = self.list()
-        doms.sort(lambda x, y: cmp(x.getName(), y.getName()))
+            if not os.path.exists(domain_config_dir):
+                try:
+                    os.makedirs(domain_config_dir, 0755)
+                except IOError:
+                    log.exception("Failed to create directory: %s" %
+                                  domain_config_dir)
+                    raise XendError("Failed to create directory: %s" %
+                                    domain_config_dir)
+                
+            try:
+                sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
+                prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
+                sxp_cache_file.close()
+            except IOError:
+                log.error("Error occurred saving configuration file to %s" %
+                          domain_config_dir)
+                raise XendError("Failed to save configuration file to: %s" %
+                                domain_config_dir)
+        else:
+            log.warn("Trying to save configuration for invalid domain")
+
+
+    def _managed_domains(self):
+        """ Returns list of domains that are managed.
+        
+        Expects to be protected by domains_lock.
+
+        @rtype: list of XendConfig
+        @return: List of domain configurations that are managed.
+        """
+        dom_path = self._managed_path()
+        dom_uuids = os.listdir(dom_path)
+        doms = []
+        for dom_uuid in dom_uuids:
+            try:
+                cfg_file = self._managed_config_path(dom_uuid)
+                cfg = XendConfig(filename = cfg_file)
+                if cfg.get('uuid') != dom_uuid:
+                    # something is wrong with the SXP
+                    log.error("UUID mismatch in stored configuration: %s" %
+                              cfg_file)
+                    continue
+                doms.append(cfg)
+            except Exception:
+                log.exception('Unable to open or parse config.sxp: %s' % \
+                              cfg_file)
         return doms
 
-    def list_names(self):
-        """Get list of domain names.
-
-        @return: domain names
-        """
-        doms = self.list_sorted()
-        return map(lambda x: x.getName(), doms)
-
-
-    ## private:
-
-    def onChangeDomain(self, _):
-        self.domains_lock.acquire()
-        try:
-            self.refresh()
-        finally:
-            self.domains_lock.release()
-        return 1
-
-
-    def xen_domains(self):
-        """Get table of domains indexed by id from xc.  Expects to be
-        protected by the domains_lock.
-        """
-        domlist = xc.domain_getinfo()
-        doms = {}
-        for d in domlist:
-            domid = d['dom']
-            doms[domid] = d
-        return doms
-
-
-    def dom0_setup(self):
-        """Expects to be protected by the domains_lock."""
-        dom0 = self.domains[PRIV_DOMAIN]
+    def _managed_domain_unregister(self, dom):
+        try:
+            if self.is_domain_managed(dom):
+                self._managed_config_remove(dom.get_uuid())
+                del self.managed_domains[dom.get_uuid()]
+        except ValueError:
+            log.warn("Domain is not registered: %s" % dom.get_uuid())
+
+    def _managed_domain_register(self, dom):
+        self.managed_domains[dom.get_uuid()] = dom
+
+    def is_domain_managed(self, dom = None):
+        return (dom.get_uuid() in self.managed_domains)
+
+    # End of Managed Domain Access
+    # --------------------------------------------------------------------
+
+    def _running_domains(self):
+        """Get table of domains indexed by id from xc.
+
+        @requires: Expects to be protected by domains_lock.
+        @rtype: list of dicts
+        @return: A list of dicts representing the running domains.
+        """
+        try:
+            return xc.domain_getinfo()
+        except RuntimeError, e:
+            log.exception("Unable to get domain information.")
+            return {}
+
+    def _setDom0CPUCount(self):
+        """Sets the number of VCPUs dom0 has. Retreived from the
+        Xend configuration, L{XendRoot}.
+
+        @requires: Expects to be protected by domains_lock.
+        @rtype: None
+        """
+        dom0 = self.privilegedDomain()
 
         # get max number of vcpus to use for dom0 from config
         target = int(xroot.get_dom0_vcpus())
@@ -157,74 +364,441 @@ class XendDomain:
             dom0.setVCpuCount(target)
 
 
+    def _refresh(self):
+        """Refresh the domain list. Needs to be called when
+        either xenstore has changed or when a method requires
+        up to date information (like uptime, cputime stats).
+
+        Expects to be protected by the domains_lock.
+
+        @rtype: None
+        """
+
+        # update information for all running domains
+        # - like cpu_time, status, dying, etc.
+        running = self._running_domains()
+        for dom in running:
+            domid = dom['domid']
+            if domid in self.domains and dom['dying'] != 1:
+                self.domains[domid].update(dom)
+
+        # remove domains that are not running from active domain list.
+        # The list might have changed by now, because the update call may
+        # cause new domains to be added, if the domain has rebooted.  We get
+        # the list again.
+        running_domids = [d['domid'] for d in running if d['dying'] != 1]
+        for domid, dom in self.domains.items():
+            if domid not in running_domids and domid != DOM0_ID:
+                self._remove_domain(dom, domid)
+
+
     def _add_domain(self, info):
-        """Add the given domain entry to this instance's internal cache.
-        Expects to be protected by the domains_lock.
-        """
+        """Add a domain to the list of running domains
+        
+        @requires: Expects to be protected by the domains_lock.
+        @param info: XendDomainInfo of a domain to be added.
+        @type info: XendDomainInfo
+        """
+        log.debug("Adding Domain: %s" % info.getDomid())
         self.domains[info.getDomid()] = info
 
-
-    def _delete_domain(self, domid):
-        """Remove the given domain from this instance's internal cache.
-        Expects to be protected by the domains_lock.
-        """
-        info = self.domains.get(domid)
+    def _remove_domain(self, info, domid = None):
+        """Remove the domain from the list of running domains
+        
+        @requires: Expects to be protected by the domains_lock.
+        @param info: XendDomainInfo of a domain to be removed.
+        @type info: XendDomainInfo
+        """
+
         if info:
-            del self.domains[domid]
-            info.cleanupDomain()
-
-
-    def refresh(self, initialising = False):
-        """Refresh domain list from Xen.  Expects to be protected by the
-        domains_lock.
-
-        @param initialising True if this is the first refresh after starting
-        Xend.  This does not change this method's behaviour, except for
-        logging.
-        """
-        doms = self.xen_domains()
-        for d in self.domains.values():
-            info = doms.get(d.getDomid())
-            if info:
-                d.update(info)
-            else:
-                self._delete_domain(d.getDomid())
-        for d in doms:
-            if d not in self.domains:
-                if doms[d]['dying']:
-                    log.log(initialising and logging.ERROR or logging.DEBUG,
-                            'Cannot recreate information for dying domain %d.'
-                            '  Xend will ignore this domain from now on.',
-                            doms[d]['dom'])
-                elif d == PRIV_DOMAIN:
-                    log.fatal(
-                        "No record of privileged domain %d!  Terminating.", d)
-                    sys.exit(1)
-                else:
-                    try:
-                        self._add_domain(
-                            XendDomainInfo.recreate(doms[d], False))
-                    except:
-                        log.exception(
-                            "Failed to recreate information for domain "
-                            "%d.  Destroying it in the hope of "
-                            "recovery.", d)
-                        try:
-                            xc.domain_destroy(d)
-                        except:
-                            log.exception('Destruction of %d failed.', d)
-
-
-    ## public:
+            if domid == None:
+                domid = info.getDomid()
+
+            if info.state != DOM_STATE_HALTED:
+                info.cleanupDomain()
+            
+            if domid in self.domains:
+                del self.domains[domid]
+        else:
+            log.warning("Attempted to remove non-existent domain.")
+
+    def restore_(self, config):
+        """Create a domain as part of the restore process.  This is called
+        only from L{XendCheckpoint}.
+
+        A restore request comes into XendDomain through L{domain_restore}
+        or L{domain_restore_fd}.  That request is
+        forwarded immediately to XendCheckpoint which, when it is ready, will
+        call this method.  It is necessary to come through here rather than go
+        directly to L{XendDomainInfo.restore} because we need to
+        serialise the domain creation process, but cannot lock
+        domain_restore_fd as a whole, otherwise we will deadlock waiting for
+        the old domain to die.
+
+        @param config: Configuration of domain to restore
+        @type config: SXP Object (eg. list of lists)
+        """
+        self.domains_lock.acquire()
+        try:
+            security.refresh_ssidref(config)
+            dominfo = XendDomainInfo.restore(config)
+            self._add_domain(dominfo)
+            return dominfo
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup(self, domid):
+        """Look up given I{domid} in the list of managed and running
+        domains.
+        
+        @note: Will cause a refresh before lookup up domains, for
+               a version that does not need to re-read xenstore
+               use L{domain_lookup_nr}.
+
+        @param domid: Domain ID or Domain Name.
+        @type domid: int or string
+        @return: Found domain.
+        @rtype: XendDomainInfo
+        @raise XendError: If domain is not found.
+        """
+        self.domains_lock.acquire()
+        try:
+            self._refresh()
+            dom = self.domain_lookup_nr(domid)
+            if not dom:
+                raise XendError("No domain named '%s'." % str(domid))
+            return dom
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_nr(self, domid):
+        """Look up given I{domid} in the list of managed and running
+        domains.
+
+        @param domid: Domain ID or Domain Name.
+        @type domid: int or string
+        @return: Found domain.
+        @rtype: XendDomainInfo or None
+        """
+        self.domains_lock.acquire()
+        try:
+            # lookup by name
+            match = [dom for dom in self.domains.values() \
+                     if dom.getName() == domid]
+            if match:
+                return match[0]
+
+            match = [dom for dom in self.managed_domains.values() \
+                     if dom.getName() == domid]
+            if match:
+                return match[0]
+
+            # lookup by id
+            try:
+                if int(domid) in self.domains:
+                    return self.domains[int(domid)]
+            except ValueError:
+                pass
+
+            # lookup by uuid for running domains
+            match = [dom for dom in self.domains.values() \
+                     if dom.get_uuid() == domid]
+            if match:
+                return match[0]
+
+            # lookup by uuid for inactive managed domains 
+            if domid in self.managed_domains:
+                return self.managed_domains[domid]
+
+            return None
+        finally:
+            self.domains_lock.release()
+
+    def privilegedDomain(self):
+        """ Get the XendDomainInfo of a dom0
+
+        @rtype: XendDomainInfo
+        """
+        self.domains_lock.acquire()
+        try:
+            return self.domains[DOM0_ID]
+        finally:
+            self.domains_lock.release()
+
+    def cleanup_domains(self):
+        """Clean up domains that are marked as autostop.
+        Should be called when Xend goes down. This is currently
+        called from L{xen.xend.servers.XMLRPCServer}.
+
+        """
+        log.debug('cleanup_domains')
+        self.domains_lock.acquire()
+        try:
+            for dom in self.domains.values():
+                if dom.getName() == DOM0_NAME:
+                    continue
+                
+                if dom.state == DOM_STATE_RUNNING:
+                    shutdownAction = dom.info.get('on_xend_stop', 'ignore')
+                    if shutdownAction == 'shutdown':
+                        log.debug('Shutting down domain: %s' % dom.getName())
+                        dom.shutdown("poweroff")
+                    elif shutdownAction == 'suspend':
+                        chkfile = self._managed_check_point_path(dom.getName())
+                        self.domain_save(dom.domid, chkfile)
+        finally:
+            self.domains_lock.release()
+
+
+
+    # ----------------------------------------------------------------
+    # Xen API 
+    
+
+    def set_allow_new_domains(self, allow_new_domains):
+        self._allow_new_domains = allow_new_domains
+
+    def allow_new_domains(self):
+        return self._allow_new_domains
+
+    def get_domain_refs(self):
+        result = []
+        try:
+            self.domains_lock.acquire()
+            result = [d.get_uuid() for d in self.domains.values()]
+            result += self.managed_domains.keys()
+            return result
+        finally:
+            self.domains_lock.release()
+
+    def get_vm_by_uuid(self, vm_uuid):
+        self.domains_lock.acquire()
+        try:
+            for dom in self.domains.values():
+                if dom.get_uuid() == vm_uuid:
+                    return dom
+
+            if vm_uuid in self.managed_domains:
+                return self.managed_domains[vm_uuid]
+
+            return None
+        finally:
+            self.domains_lock.release()
+
+    def get_vm_with_dev_uuid(self, klass, dev_uuid):
+        self.domains_lock.acquire()
+        try:
+            for dom in self.domains.values() + self.managed_domains.values():
+                if dom.has_device(klass, dev_uuid):
+                    return dom
+            return None
+        finally:
+            self.domains_lock.release()
+
+    def get_dev_property_by_uuid(self, klass, dev_uuid, field):
+        self.domains_lock.acquire()
+        try:
+            dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
+            if not dom:
+                return None
+
+            value = dom.get_device_property(klass, dev_uuid, field)
+            return value
+        except ValueError, e:
+            pass
+        
+        return None
+
+    def is_valid_vm(self, vm_ref):
+        return (self.get_vm_by_uuid(vm_ref) != None)
+
+    def is_valid_dev(self, klass, dev_uuid):
+        return (self.get_vm_with_dev_uuid(klass, dev_uuid) != None)
+
+    def do_legacy_api_with_uuid(self, fn, vm_uuid, *args):
+        self.domains_lock.acquire()
+        try:
+            for domid, dom in self.domains.items():
+                if dom.get_uuid == vm_uuid:
+                    return fn(domid, *args)
+                    
+            if vm_uuid in self.managed_domains:
+                domid = self.managed_domains[vm_uuid].getDomid()
+                if domid == None:
+                    domid = self.managed_domains[vm_uuid].getName()
+                return fn(domid, *args)
+            
+            raise XendInvalidDomain("Domain does not exist")
+        finally:
+            self.domains_lock.release()
+        
+
+    def create_domain(self, xenapi_vm):
+        self.domains_lock.acquire()
+        try:
+            try:
+                xeninfo = XendConfig(xenapi_vm = xenapi_vm)
+                dominfo = XendDomainInfo.createDormant(xeninfo)
+                log.debug("Creating new managed domain: %s: %s" %
+                          (dominfo.getName(), dominfo.get_uuid()))
+                self._managed_domain_register(dominfo)
+                self.managed_config_save(dominfo)
+                return dominfo.get_uuid()
+            except XendError, e:
+                raise
+            except Exception, e:
+                raise XendError(str(e))
+        finally:
+            self.domains_lock.release()        
+
+    def rename_domain(self, dom, new_name):
+        self.domains_lock.acquire()
+        try:
+            old_name = dom.getName()
+            dom.setName(new_name)
+
+        finally:
+            self.domains_lock.release()
+                
+    
+    #
+    # End of Xen API 
+    # ----------------------------------------------------------------
+
+    # ------------------------------------------------------------
+    # Xen Legacy API     
+
+    def list(self):
+        """Get list of domain objects.
+
+        @return: domains
+        @rtype: list of XendDomainInfo
+        """
+        self.domains_lock.acquire()
+        try:
+            self._refresh()
+            
+            # active domains
+            active_domains = self.domains.values()
+            active_uuids = [d.get_uuid() for d in active_domains]
+
+            # inactive domains
+            inactive_domains = []
+            for dom_uuid, dom in self.managed_domains.items():
+                if dom_uuid not in active_uuids:
+                    inactive_domains.append(dom)
+
+            return active_domains + inactive_domains
+        finally:
+            self.domains_lock.release()
+
+
+    def list_sorted(self):
+        """Get list of domain objects, sorted by name.
+
+        @return: domain objects
+        @rtype: list of XendDomainInfo
+        """
+        doms = self.list()
+        doms.sort(lambda x, y: cmp(x.getName(), y.getName()))
+        return doms
+
+    def list_names(self):
+        """Get list of domain names.
+
+        @return: domain names
+        @rtype: list of strings.
+        """
+        return [d.getName() for d in self.list_sorted()]
+
+    def domain_suspend(self, domname):
+        """Suspends a domain that is persistently managed by Xend
+
+        @param domname: Domain Name
+        @type domname: string
+        @rtype: None
+        @raise XendError: Failure during checkpointing.
+        """
+
+        try:
+            dominfo = self.domain_lookup_nr(domname)
+            if not dominfo:
+                raise XendInvalidDomain(domname)
+
+            if dominfo.getDomid() == DOM0_ID:
+                raise XendError("Cannot save privileged domain %s" % domname)
+
+            if dominfo.state != DOM_STATE_RUNNING:
+                raise XendError("Cannot suspend domain that is not running.")
+
+            if not os.path.exists(self._managed_config_path(domname)):
+                raise XendError("Domain is not managed by Xend lifecycle " +
+                                "support.")
+            
+            path = self._managed_check_point_path(domname)
+            fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
+            try:
+                # For now we don't support 'live checkpoint' 
+                XendCheckpoint.save(fd, dominfo, False, False, path)
+            finally:
+                os.close(fd)
+        except OSError, ex:
+            raise XendError("can't write guest state file %s: %s" %
+                            (path, ex[1]))
+
+    def domain_resume(self, domname):
+        """Resumes a domain that is persistently managed by Xend.
+
+        @param domname: Domain Name
+        @type domname: string
+        @rtype: None
+        @raise XendError: If failed to restore.
+        """
+        try:
+            dominfo = self.domain_lookup_nr(domname)
+            
+            if not dominfo:
+                raise XendInvalidDomain(domname)
+
+            if dominfo.getDomid() == DOM0_ID:
+                raise XendError("Cannot save privileged domain %s" % domname)
+
+            if dominfo.state != DOM_STATE_HALTED:
+                raise XendError("Cannot suspend domain that is not running.")
+
+            chkpath = self._managed_check_point_path(domname)
+            if not os.path.exists(chkpath):
+                raise XendError("Domain was not suspended by Xend")
+
+            # Restore that replaces the existing XendDomainInfo
+            try:
+                log.debug('Current DomainInfo state: %d' % dominfo.state)
+                XendCheckpoint.restore(self,
+                                       os.open(chkpath, os.O_RDONLY),
+                                       dominfo)
+                os.unlink(chkpath)
+            except OSError, ex:
+                raise XendError("Failed to read stored checkpoint file")
+            except IOError, ex:
+                raise XendError("Failed to delete checkpoint file")
+        except Exception, ex:
+            log.exception("Exception occurred when resuming")
+            raise XendError("Error occurred when resuming: %s" % str(ex))
+
 
     def domain_create(self, config):
         """Create a domain from a configuration.
 
         @param config: configuration
-        @return: domain
-        """
-        self.domains_lock.acquire()
-        try:
+        @type config: SXP Object (list of lists)
+        @rtype: XendDomainInfo
+        """
+        self.domains_lock.acquire()
+        try:
+            self._refresh()
+
             dominfo = XendDomainInfo.create(config)
             self._add_domain(dominfo)
             self.domain_sched_credit_set(dominfo.getDomid(),
@@ -235,10 +809,91 @@ class XendDomain:
             self.domains_lock.release()
 
 
+    def domain_new(self, config):
+        """Create a domain from a configuration but do not start it.
+        
+        @param config: configuration
+        @type config: SXP Object (list of lists)
+        @rtype: XendDomainInfo
+        """
+        self.domains_lock.acquire()
+        try:
+            try:
+                xeninfo = XendConfig(sxp = config)
+                dominfo = XendDomainInfo.createDormant(xeninfo)
+                log.debug("Creating new managed domain: %s" %
+                          dominfo.getName())
+                self._managed_domain_register(dominfo)
+                self.managed_config_save(dominfo)
+                # no return value because it isn't meaningful for client
+            except XendError, e:
+                raise
+            except Exception, e:
+                raise XendError(str(e))
+        finally:
+            self.domains_lock.release()
+
+    def domain_start(self, domid):
+        """Start a managed domain
+
+        @require: Domain must not be running.
+        @param domid: Domain name or domain ID.
+        @type domid: string or int
+        @rtype: None
+        @raise XendError: If domain is still running
+        @rtype: None
+        """
+        self.domains_lock.acquire()
+        try:
+            self._refresh()
+
+            dominfo = self.domain_lookup_nr(domid)
+            if not dominfo:
+                raise XendInvalidDomain(str(domid))
+
+            if dominfo.state != DOM_STATE_HALTED:
+                raise XendError("Domain is already running")
+            
+            dominfo.start(is_managed = True)
+            self._add_domain(dominfo)
+        finally:
+            self.domains_lock.release()
+        
+
+    def domain_delete(self, domid):
+        """Remove a managed domain from database
+
+        @require: Domain must not be running.
+        @param domid: Domain name or domain ID.
+        @type domid: string or int
+        @rtype: None
+        @raise XendError: If domain is still running
+        """
+        self.domains_lock.acquire()
+        try:
+            try:
+                dominfo = self.domain_lookup_nr(domid)
+                if not dominfo:
+                    raise XendInvalidDomain(str(domid))
+
+                if dominfo.state != DOM_STATE_HALTED:
+                    raise XendError("Domain is still running")
+
+                self._managed_domain_unregister(dominfo)
+                self._remove_domain(dominfo)
+                
+            except Exception, ex:
+                raise XendError(str(ex))
+        finally:
+            self.domains_lock.release()
+        
+
     def domain_configure(self, config):
         """Configure an existing domain.
 
         @param vmconfig: vm configuration
+        @type vmconfig: SXP Object (list of lists)
+        @todo: Not implemented
         """
         # !!!
         raise XendError("Unsupported")
@@ -246,9 +901,12 @@ class XendDomain:
     def domain_restore(self, src):
         """Restore a domain from file.
 
-        @param src:      source file
-        """
-
+        @param src: filename of checkpoint file to restore from
+        @type src: string
+        @return: Restored domain
+        @rtype: XendDomainInfo
+        @raise XendError: Failure to restore domain
+        """
         try:
             fd = os.open(src, os.O_RDONLY)
             try:
@@ -260,7 +918,13 @@ class XendDomain:
                             (src, ex[1]))
 
     def domain_restore_fd(self, fd):
-        """Restore a domain from the given file descriptor."""
+        """Restore a domain from the given file descriptor.
+
+        @param fd: file descriptor of the checkpoint file
+        @type fd: File object
+        @rtype: XendDomainInfo
+        @raise XendError: if failed to restore
+        """
 
         try:
             return XendCheckpoint.restore(self, fd)
@@ -270,151 +934,85 @@ class XendDomain:
             # poor, so we need to log this for debugging.
             log.exception("Restore failed")
             raise XendError("Restore failed")
-
-
-    def restore_(self, config):
-        """Create a domain as part of the restore process.  This is called
-        only from {@link XendCheckpoint}.
-
-        A restore request comes into XendDomain through {@link
-        #domain_restore} or {@link #domain_restore_fd}.  That request is
-        forwarded immediately to XendCheckpoint which, when it is ready, will
-        call this method.  It is necessary to come through here rather than go
-        directly to {@link XendDomainInfo.restore} because we need to
-        serialise the domain creation process, but cannot lock
-        domain_restore_fd as a whole, otherwise we will deadlock waiting for
-        the old domain to die.
-        """
-        self.domains_lock.acquire()
-        try:
-            security.refresh_ssidref(config)
-            dominfo = XendDomainInfo.restore(config)
-            self._add_domain(dominfo)
-            return dominfo
-        finally:
-            self.domains_lock.release()
-
-
-    def domain_lookup(self, domid):
-        self.domains_lock.acquire()
-        try:
-            self.refresh()
-            return self.domains.get(domid)
-        finally:
-            self.domains_lock.release()
-
-
-    def domain_lookup_nr(self, domid):
-        self.domains_lock.acquire()
-        try:
-            return self.domains.get(domid)
-        finally:
-            self.domains_lock.release()
-
-
-    def domain_lookup_by_name_or_id(self, name):
-        self.domains_lock.acquire()
-        try:
-            self.refresh()
-            return self.domain_lookup_by_name_or_id_nr(name)
-        finally:
-            self.domains_lock.release()
-
-
-    def domain_lookup_by_name_or_id_nr(self, name):
-        self.domains_lock.acquire()
-        try:
-            dominfo = self.domain_lookup_by_name_nr(name)
-
-            if dominfo:
-                return dominfo
-            else:
-                try:
-                    return self.domains.get(int(name))
-                except ValueError:
-                    return None
-        finally:
-            self.domains_lock.release()
-
-
-    def domain_lookup_by_name_nr(self, name):
-        self.domains_lock.acquire()
-        try:
-            matching = filter(lambda d: d.getName() == name,
-                              self.domains.values())
-            n = len(matching)
-            if n == 1:
-                return matching[0]
-            return None
-        finally:
-            self.domains_lock.release()
-
-
-    def privilegedDomain(self):
-        self.domains_lock.acquire()
-        try:
-            return self.domains[PRIV_DOMAIN]
-        finally:
-            self.domains_lock.release()
-
  
     def domain_unpause(self, domid):
-        """Unpause domain execution."""
-
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        """Unpause domain execution.
+
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @rtype: None
+        @raise XendError: Failed to unpause
+        @raise XendInvalidDomain: Domain is not valid        
+        """
+        try:
+            dominfo = self.domain_lookup_nr(domid)
+            if not dominfo:
+                raise XendInvalidDomain(str(domid))
+            
+            log.info("Domain %s (%d) unpaused.", dominfo.getName(),
+                     int(dominfo.getDomid()))
+            
+            dominfo.unpause()
+        except XendInvalidDomain:
+            log.exception("domain_unpause")
+            raise
+        except Exception, ex:
+            log.exception("domain_unpause")
+            raise XendError(str(ex))
+
+    def domain_pause(self, domid):
+        """Pause domain execution.
+
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @rtype: None
+        @raise XendError: Failed to pause
+        @raise XendInvalidDomain: Domain is not valid
+        """        
+        try:
+            dominfo = self.domain_lookup_nr(domid)
+            if not dominfo:
+                raise XendInvalidDomain(str(domid))
+            log.info("Domain %s (%d) paused.", dominfo.getName(),
+                     int(dominfo.getDomid()))
+            dominfo.pause()
+        except XendInvalidDomain:
+            log.exception("domain_pause")
+            raise
+        except Exception, ex:
+            log.exception("domain_pause")
+            raise XendError(str(ex))
+
+    def domain_dump(self, domid, filename, live, crash):
+        """Dump domain core."""
+
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
 
-        if dominfo.getDomid() == PRIV_DOMAIN:
-            raise XendError("Cannot unpause privileged domain %s" % domid)
-
-        try:
-            log.info("Domain %s (%d) unpaused.", dominfo.getName(),
-                     dominfo.getDomid())
-            return dominfo.unpause()
-        except Exception, ex:
-            raise XendError(str(ex))
-
-
-    def domain_pause(self, domid):
-        """Pause domain execution."""
-
-        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 pause privileged domain %s" % domid)
-
-        try:
-            log.info("Domain %s (%d) paused.", dominfo.getName(),
-                     dominfo.getDomid())
-            return dominfo.pause()
-        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:
+        if dominfo.getDomid() == DOM0_ID:
             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.",
+            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."""
-
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
-       if dominfo and dominfo.getDomid() == PRIV_DOMAIN:
+        """Terminate domain immediately.
+
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @rtype: None
+        @raise XendError: Failed to destroy
+        @raise XendInvalidDomain: Domain is not valid        
+        """
+
+        dominfo = self.domain_lookup_nr(domid)
+        if dominfo and dominfo.getDomid() == DOM0_ID:
             raise XendError("Cannot destroy privileged domain %s" % domid)
 
         if dominfo:
@@ -422,19 +1020,36 @@ class XendDomain:
         else:
             try:
                 val = xc.domain_destroy(int(domid))
-            except Exception, ex:
-                raise XendInvalidDomain(str(domid))
+            except ValueError:
+                raise XendInvalidDomain(domid)
+            except Exception, e:
+                raise XendError(str(e))
+
         return val       
 
     def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
-        """Start domain migration."""
-
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        """Start domain migration.
+        
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @param dst: Destination IP address
+        @type dst: string
+        @keyword port: relocation port on destination
+        @type port: int        
+        @keyword live: Live migration
+        @type live: bool
+        @keyword resource: not used??
+        @rtype: None
+        @raise XendError: Failed to migrate
+        @raise XendInvalidDomain: Domain is not valid        
+        """
+
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
 
-        if dominfo.getDomid() == PRIV_DOMAIN:
-            raise XendError("Cannot migrate privileged domain %s" % domid)
+        if dominfo.getDomid() == DOM0_ID:
+            raise XendError("Cannot migrate privileged domain %i" % domid)
 
         """ The following call may raise a XendError exception """
         dominfo.testMigrateDevices(True, dst)
@@ -460,21 +1075,26 @@ class XendDomain:
     def domain_save(self, domid, dst):
         """Start saving a domain to file.
 
-        @param dst:      destination file
-        """
-
-        try:
-            dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @param dst: Destination filename
+        @type dst: string
+        @rtype: None
+        @raise XendError: Failed to save domain
+        @raise XendInvalidDomain: Domain is not valid        
+        """
+        try:
+            dominfo = self.domain_lookup_nr(domid)
             if not dominfo:
                 raise XendInvalidDomain(str(domid))
 
-            if dominfo.getDomid() == PRIV_DOMAIN:
-                raise XendError("Cannot save privileged domain %s" % domid)
+            if dominfo.getDomid() == DOM0_ID:
+                raise XendError("Cannot save privileged domain %i" % domid)
 
             fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
             try:
                 # For now we don't support 'live checkpoint' 
-                return XendCheckpoint.save(fd, dominfo, False, False, dst)
+                XendCheckpoint.save(fd, dominfo, False, False, dst)
             finally:
                 os.close(fd)
         except OSError, ex:
@@ -484,9 +1104,15 @@ class XendDomain:
     def domain_pincpu(self, domid, vcpu, cpumap):
         """Set which cpus vcpu can use
 
-        @param cpumap:  string repr of list of usable cpus
-        """
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @param vcpu: vcpu to pin to
+        @type vcpu: int
+        @param cpumap:  string repr of usable cpus
+        @type cpumap: string
+        @rtype: 0
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
 
@@ -507,8 +1133,12 @@ class XendDomain:
     def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
                             weight):
         """Set Simple EDF scheduler parameters for a domain.
-        """
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @rtype: 0
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         try:
@@ -519,15 +1149,20 @@ class XendDomain:
 
     def domain_cpu_sedf_get(self, domid):
         """Get Simple EDF scheduler parameters for a domain.
-        """
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @rtype: SXP object
+        @return: The parameters for Simple EDF schedule for a domain.
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         try:
             sedf_info = xc.sedf_domain_get(dominfo.getDomid())
             # return sxpr
             return ['sedf',
-                    ['domain',    sedf_info['domain']],
+                    ['domid',    sedf_info['domid']],
                     ['period',    sedf_info['period']],
                     ['slice',     sedf_info['slice']],
                     ['latency',   sedf_info['latency']],
@@ -538,7 +1173,14 @@ class XendDomain:
             raise XendError(str(ex))
 
     def domain_shadow_control(self, domid, op):
-        """Shadow page control."""
+        """Shadow page control.
+        
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @param op: operation
+        @type op: int
+        @rtype: 0
+        """
         dominfo = self.domain_lookup(domid)
         try:
             return xc.shadow_control(dominfo.getDomid(), op)
@@ -546,7 +1188,13 @@ class XendDomain:
             raise XendError(str(ex))
 
     def domain_shadow_mem_get(self, domid):
-        """Get shadow pagetable memory allocation."""
+        """Get shadow pagetable memory allocation.
+        
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @rtype: int
+        @return: shadow memory in MB
+        """
         dominfo = self.domain_lookup(domid)
         try:
             return xc.shadow_mem_control(dominfo.getDomid())
@@ -554,7 +1202,15 @@ class XendDomain:
             raise XendError(str(ex))
 
     def domain_shadow_mem_set(self, domid, mb):
-        """Set shadow pagetable memory allocation."""
+        """Set shadow pagetable memory allocation.
+        
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @param mb: shadow memory to set in MB
+        @type: mb: int
+        @rtype: int
+        @return: shadow memory in MB
+        """
         dominfo = self.domain_lookup(domid)
         try:
             return xc.shadow_mem_control(dominfo.getDomid(), mb=mb)
@@ -563,8 +1219,13 @@ class XendDomain:
 
     def domain_sched_credit_get(self, domid):
         """Get credit scheduler parameters for a domain.
-        """
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @rtype: dict with keys 'weight' and 'cap'
+        @return: credit scheduler parameters
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         try:
@@ -574,8 +1235,14 @@ class XendDomain:
     
     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)
+
+        @param domid: Domain ID or Name
+        @type domid: int or string.
+        @type weight: int
+        @type cap: int
+        @rtype: 0
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         try:
@@ -589,17 +1256,25 @@ class XendDomain:
             elif cap < 0 or cap > dominfo.getVCpuCount() * 100:
                 raise XendError("cap is out of range")
 
+            assert type(weight) == int
+            assert type(cap) == int
+
             return xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap)
         except Exception, ex:
+            log.exception(ex)
             raise XendError(str(ex))
 
     def domain_maxmem_set(self, domid, mem):
         """Set the memory limit for a domain.
 
+        @param domid: Domain ID or Name
+        @type domid: int or string.
         @param mem: memory limit (in MiB)
-        @return: 0 on success, -1 on error
-        """
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        @type mem: int
+        @raise XendError: fail to set memory
+        @rtype: 0
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         maxmem = int(mem) * 1024
@@ -613,9 +1288,10 @@ class XendDomain:
 
         @param first: first IO port
         @param last: last IO port
-        @return: 0 on success, -1 on error
-        """
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        @raise XendError: failed to set range
+        @rtype: 0
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         nr_ports = last - first + 1
@@ -632,9 +1308,10 @@ class XendDomain:
 
         @param first: first IO port
         @param last: last IO port
-        @return: 0 on success, -1 on error
-        """
-        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+        @raise XendError: failed to set range
+        @rtype: 0
+        """
+        dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
         nr_ports = last - first + 1
diff -r 11b718eb22c9 -r ebed72718263 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Nov 02 12:43:04 2006 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Nov 10 11:11:04 2006 -0700
@@ -24,90 +24,39 @@ Author: Mike Wray <mike.wray@xxxxxx>
 
 """
 
-import errno
 import logging
-import string
 import time
 import threading
+import re
+import copy
 import os
+from types import StringTypes
 
 import xen.lowlevel.xc
 from xen.util import asserts
 from xen.util.blkif import blkdev_uname_to_file
 from xen.util import security
-import balloon
-import image
-import sxp
-import uuid
-import XendDomain
-import XendRoot
+
+from xen.xend import balloon, sxp, uuid, image, arch
+from xen.xend import XendRoot, XendNode
 
 from xen.xend.XendBootloader import bootloader
+from xen.xend.XendConfig import XendConfig
 from xen.xend.XendError import XendError, VmError
-
+from xen.xend.XendDevices import XendDevices
 from xen.xend.xenstore.xstransact import xstransact, complete
 from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
 from xen.xend.xenstore.xswatch import xswatch
-
-from xen.xend import arch
-
-"""Shutdown code for poweroff."""
-DOMAIN_POWEROFF = 0
-
-"""Shutdown code for reboot."""
-DOMAIN_REBOOT   = 1
-
-"""Shutdown code for suspend."""
-DOMAIN_SUSPEND  = 2
-
-"""Shutdown code for crash."""
-DOMAIN_CRASH    = 3
-
-"""Shutdown code for halt."""
-DOMAIN_HALT     = 4
-
-"""Map shutdown codes to strings."""
-shutdown_reasons = {
-    DOMAIN_POWEROFF: "poweroff",
-    DOMAIN_REBOOT  : "reboot",
-    DOMAIN_SUSPEND : "suspend",
-    DOMAIN_CRASH   : "crash",
-    DOMAIN_HALT    : "halt"
-    }
-
-restart_modes = [
-    "restart",
-    "destroy",
-    "preserve",
-    "rename-restart"
-    ]
-
-STATE_DOM_OK       = 1
-STATE_DOM_SHUTDOWN = 2
-
-SHUTDOWN_TIMEOUT = 30.0
+from xen.xend.XendConstants import *
+from xen.xend.XendAPIConstants import *
+
 MIGRATE_TIMEOUT = 30.0
-
-ZOMBIE_PREFIX = 'Zombie-'
-
-"""Constants for the different stages of ext. device migration """
-DEV_MIGRATE_TEST  = 0
-DEV_MIGRATE_STEP1 = 1
-DEV_MIGRATE_STEP2 = 2
-DEV_MIGRATE_STEP3 = 3
-
-"""Minimum time between domain restarts in seconds."""
-MINIMUM_RESTART_TIME = 20
-
-RESTART_IN_PROGRESS = 'xend/restart_in_progress'
-
 
 xc = xen.lowlevel.xc.xc()
 xroot = XendRoot.instance()
 
 log = logging.getLogger("xend.XendDomainInfo")
 #log.setLevel(logging.TRACE)
-
 
 ##
 # All parameters of VMs that may be configured on-the-fly, or at start-up.
@@ -157,6 +106,8 @@ VM_STORE_ENTRIES = [
     ('shadow_memory', int),
     ('maxmem',        int),
     ('start_time',    float),
+    ('on_xend_start', str),
+    ('on_xend_stop', str),
     ]
 
 VM_STORE_ENTRIES += VM_CONFIG_PARAMS
@@ -182,77 +133,102 @@ VM_STORE_ENTRIES += VM_CONFIG_PARAMS
 
 
 def create(config):
-    """Create a VM from a configuration.
-
-    @param config    configuration
-    @raise: VmError for invalid configuration
+    """Creates and start a VM using the supplied configuration. 
+    (called from XMLRPCServer directly)
+
+    @param config: A configuration object involving lists of tuples.
+    @type  config: list of lists, eg ['vm', ['image', 'xen.gz']]
+
+    @rtype:  XendDomainInfo
+    @return: A up and running XendDomainInfo instance
+    @raise VmError: Invalid configuration or failure to start.
     """
 
     log.debug("XendDomainInfo.create(%s)", config)
-
-    vm = XendDomainInfo(parseConfig(config))
+    vm = XendDomainInfo(XendConfig(sxp = config))
     try:
-        vm.construct()
-        vm.initDomain()
-        vm.storeVmDetails()
-        vm.storeDomDetails()
-        vm.registerWatches()
-        vm.refreshShutdown()
-        return vm
+        vm.start()
     except:
         log.exception('Domain construction failed')
         vm.destroy()
         raise
 
-
-def recreate(xeninfo, priv):
+    return vm
+
+def recreate(info, priv):
     """Create the VM object for an existing domain.  The domain must not
     be dying, as the paths in the store should already have been removed,
-    and asking us to recreate them causes problems."""
-
-    log.debug("XendDomainInfo.recreate(%s)", xeninfo)
-
-    assert not xeninfo['dying']
-
-    domid = xeninfo['dom']
+    and asking us to recreate them causes problems.
+
+    @param xeninfo: Parsed configuration
+    @type  xeninfo: Dictionary
+    @param priv: TODO, unknown, something to do with memory
+    @type  priv: bool
+
+    @rtype:  XendDomainInfo
+    @return: A up and running XendDomainInfo instance
+    @raise VmError: Invalid configuration.
+    @raise XendError: Errors with configuration.
+    """
+
+    log.debug("XendDomainInfo.recreate(%s)", info)
+
+    assert not info['dying']
+
+    xeninfo = XendConfig(cfg = info)
+    domid = xeninfo['domid']
     uuid1 = xeninfo['handle']
     xeninfo['uuid'] = uuid.toString(uuid1)
+    needs_reinitialising = False
+    
     dompath = GetDomainPath(domid)
     if not dompath:
-        raise XendError(
-            'No domain path in store for existing domain %d' % domid)
-
-    log.info("Recreating domain %d, UUID %s.", domid, xeninfo['uuid'])
+        raise XendError('No domain path in store for existing '
+                        'domain %d' % domid)
+
+    log.info("Recreating domain %d, UUID %s. at %s" %
+             (domid, xeninfo['uuid'], dompath))
+
+    # need to verify the path and uuid if not Domain-0
+    # if the required uuid and vm aren't set, then that means
+    # we need to recreate the dom with our own values
+    #
+    # NOTE: this is probably not desirable, really we should just
+    #       abort or ignore, but there may be cases where xenstore's
+    #       entry disappears (eg. xenstore-rm /)
+    #
     try:
         vmpath = xstransact.Read(dompath, "vm")
         if not vmpath:
-            raise XendError(
-                'No vm path in store for existing domain %d' % domid)
+            log.warn('/local/domain/%d/vm is missing. recreate is '
+                     'confused, trying our best to recover' % domid)
+            needs_reinitialising = True
+            raise XendError('reinit')
+        
         uuid2_str = xstransact.Read(vmpath, "uuid")
         if not uuid2_str:
-            raise XendError(
-                'No vm/uuid path in store for existing domain %d' % domid)
-
+            log.warn('%s/uuid/ is missing. recreate is confused, '
+                     'trying our best to recover' % vmpath)
+            needs_reinitialising = True
+            raise XendError('reinit')
+        
         uuid2 = uuid.fromString(uuid2_str)
-
         if uuid1 != uuid2:
-            raise XendError(
-                'Uuid in store does not match uuid for existing domain %d: '
-                '%s != %s' % (domid, uuid2_str, xeninfo['uuid']))
-
-        vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
-
-    except Exception, exn:
-        if priv:
-            log.warn(str(exn))
-
-        vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
-        vm.recreateDom()
-        vm.removeVm()
-        vm.storeVmDetails()
-        vm.storeDomDetails()
-
-    vm.registerWatches()
+            log.warn('UUID in /vm does not match the UUID in /dom/%d.'
+                     'Trying out best to recover' % domid)
+            needs_reinitialising = True
+    except XendError:
+        pass # our best shot at 'goto' in python :)
+
+    vm = XendDomainInfo(xeninfo, domid, dompath, augment = True, priv = priv)
+    
+    if needs_reinitialising:
+        vm._recreateDom()
+        vm._removeVm()
+        vm._storeVmDetails()
+        vm._storeDomDetails()
+        
+    vm._registerWatches()
     vm.refreshShutdown(xeninfo)
     return vm
 
@@ -260,146 +236,52 @@ def restore(config):
 def restore(config):
     """Create a domain and a VM object to do a restore.
 
-    @param config: domain configuration
+    @param config: Domain configuration object
+    @type  config: list of lists. (see C{create})
+
+    @rtype:  XendDomainInfo
+    @return: A up and running XendDomainInfo instance
+    @raise VmError: Invalid configuration or failure to start.
+    @raise XendError: Errors with configuration.
     """
 
     log.debug("XendDomainInfo.restore(%s)", config)
-
-    vm = XendDomainInfo(parseConfig(config), None, None, False, False, True)
+    vm = XendDomainInfo(XendConfig(sxp = config), resume = True)
     try:
-        vm.construct()
-        vm.storeVmDetails()
-        vm.createDevices()
-        vm.createChannels()
-        vm.storeDomDetails()
-        vm.endRestore()
+        vm.resume()
         return vm
     except:
         vm.destroy()
         raise
 
-
-def parseConfig(config):
-    def get_cfg(name, conv = None):
-        val = sxp.child_value(config, name)
-
-        if conv and not val is None:
-            try:
-                return conv(val)
-            except TypeError, exn:
-                raise VmError(
-                    'Invalid setting %s = %s in configuration: %s' %
-                    (name, val, str(exn)))
-        else:
-            return val
-
-
-    log.debug("parseConfig: config is %s", config)
-
-    result = {}
-
-    for e in ROUNDTRIPPING_CONFIG_ENTRIES:
-        result[e[0]] = get_cfg(e[0], e[1])
-
-    result['cpu']   = get_cfg('cpu',  int)
-    result['cpus']  = get_cfg('cpus', str)
-    result['image'] = get_cfg('image')
-    tmp_security = get_cfg('security')
-    if tmp_security:
-        result['security'] = tmp_security
-
-    try:
-        if result['image']:
-            v = sxp.child_value(result['image'], 'vcpus')
-            if result['vcpus'] is None and v is not None:
-                result['vcpus'] = int(v)
-            elif v is not None and int(v) != result['vcpus']:
-                log.warn(('Image VCPUs setting overrides vcpus=%d elsewhere.'
-                          '  Using %s VCPUs for VM %s.') %
-                         (result['vcpus'], v, result['uuid']))
-                result['vcpus'] = int(v)
-    except TypeError, exn:
-        raise VmError(
-            'Invalid configuration setting: vcpus = %s: %s' %
-            (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
-
-    try:
-        # support legacy config files with 'cpu' parameter
-        # NB: prepending to list to support previous behavior
-        #     where 'cpu' parameter pinned VCPU0.
-        if result['cpu']:
-           if result['cpus']:
-               result['cpus'] = "%s,%s" % (str(result['cpu']), result['cpus'])
-           else:
-               result['cpus'] = str(result['cpu'])
-
-        # convert 'cpus' string to list of ints
-        # 'cpus' supports a list of ranges (0-3), seperated by
-        # commas, and negation, (^1).  
-        # Precedence is settled by  order of the string:
-        #     "0-3,^1"   -> [0,2,3]
-        #     "0-3,^1,1" -> [0,1,2,3]
-        if result['cpus']:
-            cpus = []
-            for c in result['cpus'].split(','):
-                if c.find('-') != -1:             
-                    (x,y) = c.split('-')
-                    for i in range(int(x),int(y)+1):
-                        cpus.append(int(i))
-                else:
-                    # remove this element from the list 
-                    if c[0] == '^':
-                        cpus = [x for x in cpus if x != int(c[1:])]
-                    else:
-                        cpus.append(int(c))
-
-            result['cpus'] = cpus
-        
-    except ValueError, exn:
-        raise VmError(
-            'Invalid configuration setting: cpus = %s: %s' %
-            (result['cpus'], exn))
-
-    result['backend'] = []
-    for c in sxp.children(config, 'backend'):
-        result['backend'].append(sxp.name(sxp.child0(c)))
-
-    result['device'] = []
-    for d in sxp.children(config, 'device'):
-        c = sxp.child0(d)
-        result['device'].append((sxp.name(c), c))
-
-    # Configuration option "restart" is deprecated.  Parse it, but
-    # let on_xyz override it if they are present.
-    restart = get_cfg('restart')
-    if restart:
-        def handle_restart(event, val):
-            if result[event] is None:
-                result[event] = val
-
-        if restart == "onreboot":
-            handle_restart('on_poweroff', 'destroy')
-            handle_restart('on_reboot',   'restart')
-            handle_restart('on_crash',    'destroy')
-        elif restart == "always":
-            handle_restart('on_poweroff', 'restart')
-            handle_restart('on_reboot',   'restart')
-            handle_restart('on_crash',    'restart')
-        elif restart == "never":
-            handle_restart('on_poweroff', 'destroy')
-            handle_restart('on_reboot',   'destroy')
-            handle_restart('on_crash',    'destroy')
-        else:
-            log.warn("Ignoring malformed and deprecated config option "
-                     "restart = %s", restart)
-
-    result['start_time'] = get_cfg('start_time', float)
-
-    log.debug("parseConfig: result is %s", result)
-    return result
-
+def createDormant(xeninfo):
+    """Create a dormant/inactive XenDomainInfo without creating VM.
+    This is for creating instances of persistent domains that are not
+    yet start.
+
+    @param xeninfo: Parsed configuration
+    @type  xeninfo: dictionary
+    
+    @rtype:  XendDomainInfo
+    @return: A up and running XendDomainInfo instance
+    @raise XendError: Errors with configuration.    
+    """
+    
+    log.debug("XendDomainInfo.createDormant(%s)", xeninfo)
+    
+    # domid does not make sense for non-running domains.
+    xeninfo.pop('domid', None)
+    vm = XendDomainInfo(XendConfig(cfg = xeninfo))
+    return vm    
 
 def domain_by_name(name):
+    """Get domain by name
+
+    @params name: Name of the domain
+    @type   name: string
+    @return: XendDomainInfo or None
+    """
+    from xen.xend import XendDomain
     return XendDomain.instance().domain_lookup_by_name_nr(name)
 
 
@@ -411,17 +293,19 @@ def shutdown_reason(code):
     @return: shutdown reason
     @rtype:  string
     """
-    return shutdown_reasons.get(code, "?")
+    return DOMAIN_SHUTDOWN_REASONS.get(code, "?")
 
 def dom_get(dom):
     """Get info from xen for an existing domain.
 
     @param dom: domain id
+    @type  dom: int
     @return: info or None
+    @rtype: dictionary
     """
     try:
         domlist = xc.domain_getinfo(dom, 1)
-        if domlist and dom == domlist[0]['dom']:
+        if domlist and dom == domlist[0]['domid']:
             return domlist[0]
     except Exception, err:
         # ignore missing domain
@@ -430,32 +314,87 @@ def dom_get(dom):
 
 
 class XendDomainInfo:
-
+    """An object represents a domain.
+
+    @TODO: try to unify dom and domid, they mean the same thing, but
+           xc refers to it as dom, and everywhere else, including
+           xenstore it is domid. The best way is to change xc's
+           python interface.
+
+    @ivar info: Parsed configuration
+    @type info: dictionary
+    @ivar domid: Domain ID (if VM has started)
+    @type domid: int or None
+    @ivar vmpath: XenStore path to this VM.
+    @type vmpath: string
+    @ivar dompath: XenStore path to this Domain.
+    @type dompath: string
+    @ivar image:  Reference to the VM Image.
+    @type image: xen.xend.image.ImageHandler
+    @ivar store_port: event channel to xenstored
+    @type store_port: int
+    @ivar console_port: event channel to xenconsoled
+    @type console_port: int
+    @ivar store_mfn: xenstored mfn
+    @type store_mfn: int
+    @ivar console_mfn: xenconsoled mfn
+    @type console_mfn: int
+    @ivar vmWatch: reference to a watch on the xenstored vmpath
+    @type vmWatch: xen.xend.xenstore.xswatch
+    @ivar shutdownWatch: reference to watch on the xenstored domain shutdown
+    @type shutdownWatch: xen.xend.xenstore.xswatch
+    @ivar shutdownStartTime: UNIX Time when domain started shutting down.
+    @type shutdownStartTime: float or None
+    @ivar state: Domain state
+    @type state: enum(DOM_STATE_HALTED, DOM_STATE_RUNNING, ...)
+    @ivar state_updated: lock for self.state
+    @type state_updated: threading.Condition
+    @ivar refresh_shutdown_lock: lock for polling shutdown state
+    @type refresh_shutdown_lock: threading.Condition
+    @ivar _deviceControllers: device controller cache for this domain
+    @type _deviceControllers: dict 'string' to DevControllers
+    """
+    
     def __init__(self, info, domid = None, dompath = None, augment = False,
                  priv = False, resume = False):
+        """Constructor for a domain
+
+        @param   info: parsed configuration
+        @type    info: dictionary
+        @keyword domid: Set initial domain id (if any)
+        @type    domid: int
+        @keyword dompath: Set initial dompath (if any)
+        @type    dompath: string
+        @keyword augment: Augment given info with xenstored VM info
+        @type    augment: bool
+        @keyword priv: Is a privledged domain (Dom 0) (TODO: really?)
+        @type    priv: bool
+        @keyword resume: Is this domain being resumed?
+        @type    resume: bool
+        """
 
         self.info = info
-
-        if not self.infoIsSet('uuid'):
-            self.info['uuid'] = uuid.toString(uuid.create())
-
-        if domid is not None:
+        if domid == None:
+            self.domid =  self.info.get('domid')
+        else:
             self.domid = domid
-        elif 'dom' in info:
-            self.domid = int(info['dom'])
-        else:
-            self.domid = None
-
-        self.vmpath  = XendDomain.VMROOT + self.info['uuid']
+        
+        #REMOVE: uuid is now generated in XendConfig
+        #if not self._infoIsSet('uuid'):
+        #    self.info['uuid'] = uuid.toString(uuid.create())
+
+        #REMOVE: domid logic can be shortened 
+        #if domid is not None:
+        #    self.domid = domid
+        #elif info.has_key('dom'):
+        #    self.domid = int(info['dom'])
+        #else:
+        #    self.domid = None
+
+        self.vmpath  = XS_VMROOT + self.info['uuid']
         self.dompath = dompath
 
-        if augment:
-            self.augmentInfo(priv)
-
-        self.validateInfo()
-
         self.image = None
-        self.security = None
         self.store_port = None
         self.store_mfn = None
         self.console_port = None
@@ -463,67 +402,215 @@ class XendDomainInfo:
 
         self.vmWatch = None
         self.shutdownWatch = None
-
         self.shutdownStartTime = None
         
-        self.state = STATE_DOM_OK
+        self.state = DOM_STATE_HALTED
         self.state_updated = threading.Condition()
         self.refresh_shutdown_lock = threading.Condition()
 
+        self._deviceControllers = {}
+
+        for state in DOM_STATES_OLD:
+            self.info[state] = 0
+
+        if augment:
+            self._augmentInfo(priv)
+
+        self._checkName(self.info['name'])
         self.setResume(resume)
-
-    ## private:
-
-    def readVMDetails(self, params):
-        """Read the specified parameters from the store.
+            
+
+    #
+    # Public functions available through XMLRPC
+    #
+
+
+    def start(self, is_managed = False):
+        """Attempts to start the VM by do the appropriate
+        initialisation if it not started.
+        """
+        from xen.xend import XendDomain
+        
+        if self.state == DOM_STATE_HALTED:
+            try:
+                self._constructDomain()
+                self._initDomain()
+                self._storeVmDetails()
+                self._storeDomDetails()
+                self._registerWatches()
+                self.refreshShutdown()
+                self.unpause()
+
+                # save running configuration if XendDomains believe domain is
+                # persistent
+                #
+                if is_managed:
+                    xendomains = XendDomain.instance()
+                    xendomains.managed_config_save(self)
+            except:
+                log.exception('VM start failed')
+                self.destroy()
+                raise
+        else:
+            raise XendError('VM already running')
+
+    def resume(self):
+        """Resumes a domain that has come back from suspension."""
+        if self.state in (DOM_STATE_HALTED, DOM_STATE_SUSPENDED):
+            try:
+                self._constructDomain()
+                self._storeVmDetails()
+                self._createDevices()
+                self._createChannels()
+                self._storeDomDetails()
+                self._endRestore()
+            except:
+                log.exception('VM resume failed')
+                raise
+        else:
+            raise XendError('VM already running')
+
+    def shutdown(self, reason):
+        """Shutdown a domain by signalling this via xenstored."""
+        log.debug('XendDomainInfo.shutdown')
+        if self.state in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
+            raise XendError('Domain cannot be shutdown')
+        
+        if not reason in DOMAIN_SHUTDOWN_REASONS.values():
+            raise XendError('Invalid reason: %s' % reason)
+        self._storeDom("control/shutdown", reason)
+                
+    def pause(self):
+        """Pause domain
+        
+        @raise XendError: Failed pausing a domain
         """
         try:
-            return self.gatherVm(*params)
+            xc.domain_pause(self.domid)
+            self._stateSet(DOM_STATE_PAUSED)
+        except Exception, ex:
+            raise XendError("Domain unable to be paused: %s" % str(ex))
+
+    def unpause(self):
+        """Unpause domain
+        
+        @raise XendError: Failed unpausing a domain
+        """
+        try:
+            xc.domain_unpause(self.domid)
+            self._stateSet(DOM_STATE_RUNNING)
+        except Exception, ex:
+            raise XendError("Domain unable to be unpaused: %s" % str(ex))
+
+    def send_sysrq(self, key):
+        """ Send a Sysrq equivalent key via xenstored."""
+        asserts.isCharConvertible(key)
+        self._storeDom("control/sysrq", '%c' % key)
+
+    def device_create(self, dev_config):
+        """Create a new device.
+
+        @param dev_config: device configuration
+        @type  dev_config: dictionary (parsed config)
+        """
+        log.debug("XendDomainInfo.device_create: %s" % dev_config)
+        dev_type = sxp.name(dev_config)
+        devid = self._createDevice(dev_type, dev_config)
+        self.info.device_add(dev_type, cfg_sxp = dev_config)        
+        self._waitForDevice(dev_type, devid)
+        return self.getDeviceController(dev_type).sxpr(devid)
+
+    def device_configure(self, dev_config, devid):
+        """Configure an existing device.
+        
+        @param dev_config: device configuration
+        @type  dev_config: dictionary (parsed config)
+        @param devid:      device id
+        @type  devid:      int
+        """
+        deviceClass = sxp.name(dev_config)
+        self._reconfigureDevice(deviceClass, devid, dev_config)
+
+    def waitForDevices(self):
+        """Wait for this domain's configured devices to connect.
+
+        @raise VmError: if any device fails to initialise.
+        """
+        for devclass in XendDevices.valid_devices():
+            self.getDeviceController(devclass).waitForDevices()
+
+    def destroyDevice(self, deviceClass, devid):
+        try:
+            devid = int(devid)
         except ValueError:
-            # One of the int/float entries in params has a corresponding store
-            # entry that is invalid.  We recover, because older versions of
-            # Xend may have put the entry there (memory/target, for example),
-            # but this is in general a bad situation to have reached.
-            log.exception(
-                "Store corrupted at %s!  Domain %d's configuration may be "
-                "affected.", self.vmpath, self.domid)
-            return []
-
-
-    def storeChanged(self, _):
-        log.trace("XendDomainInfo.storeChanged");
-
-        changed = False
-        
-        def f(x, y):
-            if y is not None and self.info[x[0]] != y:
-                self.info[x[0]] = y
-                changed = True
-
-        map(f, VM_CONFIG_PARAMS, self.readVMDetails(VM_CONFIG_PARAMS))
-
-        im = self.readVm('image')
-        current_im = self.info['image']
-        if (im is not None and
-            (current_im is None or sxp.to_string(current_im) != im)):
-            self.info['image'] = sxp.from_string(im)
-            changed = True
-
-        if changed:
-            # Update the domain section of the store, as this contains some
-            # parameters derived from the VM configuration.
-            self.storeDomDetails()
-
-        return 1
-
-
-    def augmentInfo(self, priv):
-        """Augment self.info, as given to us through {@link #recreate}, with
-        values taken from the store.  This recovers those values known to xend
-        but not to the hypervisor.
+            # devid is not a number, let's search for it in xenstore.
+            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)
+
+
+    def getDeviceSxprs(self, deviceClass):
+        return self.getDeviceController(deviceClass).sxprs()
+
+
+    def setMemoryTarget(self, target):
+        """Set the memory target of this domain.
+        @param target: In MiB.
+        """
+        log.debug("Setting memory target of domain %s (%d) to %d MiB.",
+                  self.info['name'], self.domid, target)
+        
+        if target <= 0:
+            raise XendError('Invalid memory size')
+        
+        self.info['memory'] = target
+        self.storeVm("memory", target)
+        self._storeDom("memory/target", target << 10)
+
+    def getVCPUInfo(self):
+        try:
+            # We include the domain name and ID, to help xm.
+            sxpr = ['domain',
+                    ['domid',      self.domid],
+                    ['name',       self.info['name']],
+                    ['vcpu_count', self.info['online_vcpus']]]
+
+            for i in range(0, self.info['max_vcpu_id']+1):
+                info = xc.vcpu_getinfo(self.domid, i)
+
+                sxpr.append(['vcpu',
+                             ['number',   i],
+                             ['online',   info['online']],
+                             ['blocked',  info['blocked']],
+                             ['running',  info['running']],
+                             ['cpu_time', info['cpu_time'] / 1e9],
+                             ['cpu',      info['cpu']],
+                             ['cpumap',   info['cpumap']]])
+
+            return sxpr
+
+        except RuntimeError, exn:
+            raise XendError(str(exn))
+
+    #
+    # internal functions ... TODO: re-categorised
+    # 
+
+    def _augmentInfo(self, priv):
+        """Augment self.info, as given to us through L{recreate}, with
+        values taken from the store.  This recovers those values known
+        to xend but not to the hypervisor.
         """
         def useIfNeeded(name, val):
-            if not self.infoIsSet(name) and val is not None:
+            if not self._infoIsSet(name) and val is not None:
                 self.info[name] = val
 
         if priv:
@@ -536,199 +623,64 @@ class XendDomainInfo:
         entries.append(('security', str))
 
         map(lambda x, y: useIfNeeded(x[0], y), entries,
-            self.readVMDetails(entries))
-
-        device = []
-        for c in controllerClasses:
-            devconfig = self.getDeviceConfigurations(c)
+            self._readVMDetails(entries))
+
+        devices = []
+
+        for devclass in XendDevices.valid_devices():
+            devconfig = self.getDeviceController(devclass).configurations()
             if devconfig:
-                device.extend(map(lambda x: (c, x), devconfig))
-        useIfNeeded('device', device)
-
-
-    def validateInfo(self):
-        """Validate and normalise the info block.  This has either been parsed
-        by parseConfig, or received from xc through recreate and augmented by
-        the current store contents.
-        """
-        def defaultInfo(name, val):
-            if not self.infoIsSet(name):
-                self.info[name] = val()
-
-        try:
-            defaultInfo('name',         lambda: "Domain-%d" % self.domid)
-            defaultInfo('on_poweroff',  lambda: "destroy")
-            defaultInfo('on_reboot',    lambda: "restart")
-            defaultInfo('on_crash',     lambda: "restart")
-            defaultInfo('features',     lambda: "")
-            defaultInfo('cpu',          lambda: None)
-            defaultInfo('cpus',         lambda: [])
-            defaultInfo('cpu_cap',      lambda: 0)
-            defaultInfo('cpu_weight',   lambda: 256)
-
-            # some domains don't have a config file (e.g. dom0 )
-            # to set number of vcpus so we derive available cpus
-            # from max_vcpu_id which is present for running domains.
-            if not self.infoIsSet('vcpus') and self.infoIsSet('max_vcpu_id'):
-                avail = int(self.info['max_vcpu_id'])+1
-            else:
-                avail = int(1)
-
-            defaultInfo('vcpus',        lambda: avail)
-            defaultInfo('online_vcpus', lambda: self.info['vcpus'])
-            defaultInfo('max_vcpu_id',  lambda: self.info['vcpus']-1)
-            defaultInfo('vcpu_avail',   lambda: (1 << self.info['vcpus']) - 1)
-
-            defaultInfo('memory',       lambda: 0)
-            defaultInfo('shadow_memory', lambda: 0)
-            defaultInfo('maxmem',       lambda: 0)
-            defaultInfo('bootloader',   lambda: None)
-            defaultInfo('bootloader_args', lambda: None)            
-            defaultInfo('backend',      lambda: [])
-            defaultInfo('device',       lambda: [])
-            defaultInfo('image',        lambda: None)
-            defaultInfo('security',     lambda: None)
-
-            self.check_name(self.info['name'])
-
-            if isinstance(self.info['image'], str):
-                self.info['image'] = sxp.from_string(self.info['image'])
-
-            if isinstance(self.info['security'], str):
-                self.info['security'] = sxp.from_string(self.info['security'])
-
-            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']
-
-            for (n, c) in self.info['device']:
-                if not n or not c or n not in controllerClasses:
-                    raise VmError('invalid device (%s, %s)' %
-                                  (str(n), str(c)))
-
-            for event in ['on_poweroff', 'on_reboot', 'on_crash']:
-                if self.info[event] not in restart_modes:
-                    raise VmError('invalid restart event: %s = %s' %
-                                  (event, str(self.info[event])))
-
-        except KeyError, exn:
-            log.exception(exn)
-            raise VmError('Unspecified domain detail: %s' % exn)
-
-
-    def readVm(self, *args):
+                devices.extend(map(lambda conf: (devclass, conf), devconfig))
+
+        if not self.info['device'] and devices is not None:
+            for device in devices:
+                self.info.device_add(device[0], cfg_sxp = device)
+
+    #
+    # Function to update xenstore /vm/*
+    #
+
+    def _readVm(self, *args):
         return xstransact.Read(self.vmpath, *args)
 
-    def writeVm(self, *args):
+    def _writeVm(self, *args):
         return xstransact.Write(self.vmpath, *args)
 
-    def removeVm(self, *args):
+    def _removeVm(self, *args):
         return xstransact.Remove(self.vmpath, *args)
 
-    def gatherVm(self, *args):
+    def _gatherVm(self, *args):
         return xstransact.Gather(self.vmpath, *args)
-
-
-    ## public:
 
     def storeVm(self, *args):
         return xstransact.Store(self.vmpath, *args)
 
-
-    ## private:
-
-    def readDom(self, *args):
+    #
+    # Function to update xenstore /dom/*
+    #
+
+    def _readDom(self, *args):
         return xstransact.Read(self.dompath, *args)
 
-    def writeDom(self, *args):
+    def _writeDom(self, *args):
         return xstransact.Write(self.dompath, *args)
 
-
-    ## public:
-
-    def removeDom(self, *args):
+    def _removeDom(self, *args):
         return xstransact.Remove(self.dompath, *args)
 
-    def recreateDom(self):
-        complete(self.dompath, lambda t: self._recreateDom(t))
-
-    def _recreateDom(self, t):
+    def _storeDom(self, *args):
+        return xstransact.Store(self.dompath, *args)
+
+    def _recreateDom(self):
+        complete(self.dompath, lambda t: self._recreateDomFunc(t))
+
+    def _recreateDomFunc(self, t):
         t.remove()
         t.mkdir()
         t.set_permissions({ 'dom' : self.domid })
-
-
-    ## private:
-
-    def storeDom(self, *args):
-        return xstransact.Store(self.dompath, *args)
-
-
-    ## public:
-
-    def completeRestore(self, store_mfn, console_mfn):
-
-        log.debug("XendDomainInfo.completeRestore")
-
-        self.store_mfn = store_mfn
-        self.console_mfn = console_mfn
-
-        self.introduceDomain()
-        self.storeDomDetails()
-        self.registerWatches()
-        self.refreshShutdown()
-
-        log.debug("XendDomainInfo.completeRestore done")
-
-
-    def storeVmDetails(self):
-        to_store = {}
-
-        for k in VM_STORE_ENTRIES:
-            if self.infoIsSet(k[0]):
-                to_store[k[0]] = str(self.info[k[0]])
-
-        if self.infoIsSet('image'):
-            to_store['image'] = sxp.to_string(self.info['image'])
-
-        if self.infoIsSet('security'):
-            security = self.info['security']
-            to_store['security'] = sxp.to_string(security)
-            for idx in range(0, len(security)):
-                if security[idx][0] == 'access_control':
-                    to_store['security/access_control'] = sxp.to_string([ 
security[idx][1] , security[idx][2] ])
-                    for aidx in range(1, len(security[idx])):
-                        if security[idx][aidx][0] == 'label':
-                            to_store['security/access_control/label'] = 
security[idx][aidx][1]
-                        if security[idx][aidx][0] == 'policy':
-                            to_store['security/access_control/policy'] = 
security[idx][aidx][1]
-                if security[idx][0] == 'ssidref':
-                    to_store['security/ssidref'] = str(security[idx][1])
-
-        if not self.readVm('xend/restart_count'):
-            to_store['xend/restart_count'] = str(0)
-
-        log.debug("Storing VM details: %s", to_store)
-
-        self.writeVm(to_store)
-        self.setVmPermissions()
-
-
-    def setVmPermissions(self):
-        """Allow the guest domain to read its UUID.  We don't allow it to
-        access any other entry, for security."""
-        xstransact.SetPermissions('%s/uuid' % self.vmpath,
-                                  { 'dom' : self.domid,
-                                    'read' : True,
-                                    'write' : False })
-
-
-    def storeDomDetails(self):
+        t.write('vm', self.vmpath)
+
+    def _storeDomDetails(self):
         to_store = {
             'domid':              str(self.domid),
             'vm':                 self.vmpath,
@@ -746,16 +698,13 @@ class XendDomainInfo:
         f('store/port',       self.store_port)
         f('store/ring-ref',   self.store_mfn)
 
-        to_store.update(self.vcpuDomDetails())
+        to_store.update(self._vcpuDomDetails())
 
         log.debug("Storing domain details: %s", to_store)
 
-        self.writeDom(to_store)
-
-
-    ## private:
-
-    def vcpuDomDetails(self):
+        self._writeDom(to_store)
+
+    def _vcpuDomDetails(self):
         def availability(n):
             if self.info['vcpu_avail'] & (1 << n):
                 return 'online'
@@ -767,25 +716,80 @@ class XendDomainInfo:
             result["cpu/%d/availability" % v] = availability(v)
         return result
 
-
-    ## public:
-
-    def registerWatches(self):
+    #
+    # xenstore watches
+    #
+
+    def _registerWatches(self):
         """Register a watch on this VM's entries in the store, and the
         domain's control/shutdown node, so that when they are changed
         externally, we keep up to date.  This should only be called by {@link
         #create}, {@link #recreate}, or {@link #restore}, once the domain's
         details have been written, but before the new instance is returned."""
-        self.vmWatch = xswatch(self.vmpath, self.storeChanged)
+        self.vmWatch = xswatch(self.vmpath, self._storeChanged)
         self.shutdownWatch = xswatch(self.dompath + '/control/shutdown',
-                                     self.handleShutdownWatch)
+                                     self._handleShutdownWatch)
+
+    def _storeChanged(self, _):
+        log.trace("XendDomainInfo.storeChanged");
+
+        changed = False
+        
+        def f(x, y):
+            if y is not None and self.info[x[0]] != y:
+                self.info[x[0]] = y
+                changed = True
+
+        map(f, VM_CONFIG_PARAMS, self._readVMDetails(VM_CONFIG_PARAMS))
+
+        im = self._readVm('image')
+        current_im = self.info['image']
+        if (im is not None and
+            (current_im is None or sxp.to_string(current_im) != im)):
+            self.info['image'] = sxp.from_string(im)
+            changed = True
+
+        if changed:
+            # Update the domain section of the store, as this contains some
+            # parameters derived from the VM configuration.
+            self._storeDomDetails()
+
+        return 1
+
+    def _handleShutdownWatch(self, _):
+        log.debug('XendDomainInfo.handleShutdownWatch')
+        
+        reason = self._readDom('control/shutdown')
+
+        if reason and reason != 'suspend':
+            sst = self._readDom('xend/shutdown_start_time')
+            now = time.time()
+            if sst:
+                self.shutdownStartTime = float(sst)
+                timeout = float(sst) + SHUTDOWN_TIMEOUT - now
+            else:
+                self.shutdownStartTime = now
+                self._storeDom('xend/shutdown_start_time', now)
+                timeout = SHUTDOWN_TIMEOUT
+
+            log.trace(
+                "Scheduling refreshShutdown on domain %d in %ds.",
+                self.domid, timeout)
+            threading.Timer(timeout, self.refreshShutdown).start()
+            
+        return True
+
+
+    #
+    # Public Attributes for the VM
+    #
 
 
     def getDomid(self):
         return self.domid
 
     def setName(self, name):
-        self.check_name(name)
+        self._checkName(name)
         self.info['name'] = name
         self.storeVm("name", name)
 
@@ -795,12 +799,13 @@ class XendDomainInfo:
     def getDomainPath(self):
         return self.dompath
 
+    def getShutdownReason(self):
+        return self._readDom('control/shutdown')
 
     def getStorePort(self):
         """For use only by image.py and XendCheckpoint.py."""
         return self.store_port
 
-
     def getConsolePort(self):
         """For use only by image.py and XendCheckpoint.py"""
         return self.console_port
@@ -812,11 +817,10 @@ class XendDomainInfo:
     def getVCpuCount(self):
         return self.info['vcpus']
 
-
     def setVCpuCount(self, vcpus):
         self.info['vcpu_avail'] = (1 << vcpus) - 1
         self.storeVm('vcpu_avail', self.info['vcpu_avail'])
-        self.writeDom(self.vcpuDomDetails())
+        self._writeDom(self._vcpuDomDetails())
 
     def getLabel(self):
         return security.get_security_info(self.info, 'label')
@@ -834,21 +838,23 @@ class XendDomainInfo:
     def getWeight(self):
         return self.info['cpu_weight']
 
-    def endRestore(self):
-        self.setResume(False)
-
     def setResume(self, state):
         self.info['resume'] = state
 
     def getRestartCount(self):
-        return self.readVm('xend/restart_count')
+        return self._readVm('xend/restart_count')
 
     def refreshShutdown(self, xeninfo = None):
+        """ Checks the domain for whether a shutdown is required.
+
+        Called from XendDomainInfo and also image.py for HVM images.
+        """
+        
         # If set at the end of this method, a restart is required, with the
         # given reason.  This restart has to be done out of the scope of
         # refresh_shutdown_lock.
         restart_reason = None
-        
+
         self.refresh_shutdown_lock.acquire()
         try:
             if xeninfo is None:
@@ -862,6 +868,7 @@ class XendDomainInfo:
                     # VM may have migrated to a different domain on this
                     # machine.
                     self.cleanupDomain()
+                    self._stateSet(DOM_STATE_HALTED)
                     return
 
             if xeninfo['dying']:
@@ -873,10 +880,11 @@ class XendDomainInfo:
                 # holding the pages, by calling cleanupDomain.  We can't
                 # clean up the VM, as above.
                 self.cleanupDomain()
+                self._stateSet(DOM_STATE_SHUTDOWN)
                 return
 
             elif xeninfo['crashed']:
-                if self.readDom('xend/shutdown_completed'):
+                if self._readDom('xend/shutdown_completed'):
                     # We've seen this shutdown already, but we are preserving
                     # the domain for debugging.  Leave it alone.
                     return
@@ -888,9 +896,11 @@ class XendDomainInfo:
                     self.dumpCore()
 
                 restart_reason = 'crash'
+                self._stateSet(DOM_STATE_HALTED)
 
             elif xeninfo['shutdown']:
-                if self.readDom('xend/shutdown_completed'):
+                self._stateSet(DOM_STATE_SHUTDOWN)
+                if self._readDom('xend/shutdown_completed'):
                     # We've seen this shutdown already, but we are preserving
                     # the domain for debugging.  Leave it alone.
                     return
@@ -901,15 +911,15 @@ class XendDomainInfo:
                     log.info('Domain has shutdown: name=%s id=%d reason=%s.',
                              self.info['name'], self.domid, reason)
 
-                    self.clearRestart()
+                    self._clearRestart()
 
                     if reason == 'suspend':
-                        self.state_set(STATE_DOM_SHUTDOWN)
+                        self._stateSet(DOM_STATE_SUSPENDED)
                         # Don't destroy the domain.  XendCheckpoint will do
                         # this once it has finished.  However, stop watching
                         # the VM path now, otherwise we will end up with one
                         # watch for the old domain, and one for the new.
-                        self.unwatchVm()
+                        self._unwatchVm()
                     elif reason in ['poweroff', 'reboot']:
                         restart_reason = reason
                     else:
@@ -923,7 +933,11 @@ class XendDomainInfo:
             else:
                 # Domain is alive.  If we are shutting it down, then check
                 # the timeout on that, and destroy it if necessary.
-
+                if xeninfo['paused']:
+                    self._stateSet(DOM_STATE_PAUSED)
+                else:
+                    self._stateSet(DOM_STATE_RUNNING)
+                    
                 if self.shutdownStartTime:
                     timeout = (SHUTDOWN_TIMEOUT - time.time() +
                                self.shutdownStartTime)
@@ -936,61 +950,133 @@ class XendDomainInfo:
             self.refresh_shutdown_lock.release()
 
         if restart_reason:
-            self.maybeRestart(restart_reason)
-
-
-    def handleShutdownWatch(self, _):
-        log.debug('XendDomainInfo.handleShutdownWatch')
-        
-        reason = self.readDom('control/shutdown')
-
-        if reason and reason != 'suspend':
-            sst = self.readDom('xend/shutdown_start_time')
-            now = time.time()
-            if sst:
-                self.shutdownStartTime = float(sst)
-                timeout = float(sst) + SHUTDOWN_TIMEOUT - now
-            else:
-                self.shutdownStartTime = now
-                self.storeDom('xend/shutdown_start_time', now)
-                timeout = SHUTDOWN_TIMEOUT
-
-            log.trace(
-                "Scheduling refreshShutdown on domain %d in %ds.",
-                self.domid, timeout)
-            threading.Timer(timeout, self.refreshShutdown).start()
-
-        return True
-
-
-    def shutdown(self, reason):
-        if not reason in shutdown_reasons.values():
-            raise XendError('Invalid reason: %s' % reason)
-        if self.domid == 0:
-            raise XendError("Can't specify Domain-0")
-        self.storeDom("control/shutdown", reason)
-
-
-    ## private:
-
-    def clearRestart(self):
-        self.removeDom("xend/shutdown_start_time")
-
-
-    def maybeRestart(self, reason):
+            self._maybeRestart(restart_reason)
+
+
+    #
+    # Restart functions - handling whether we come back up on shutdown.
+    #
+
+    def _clearRestart(self):
+        self._removeDom("xend/shutdown_start_time")
+
+
+    def _maybeRestart(self, reason):
         # Dispatch to the correct method based upon the configured on_{reason}
         # behaviour.
         {"destroy"        : self.destroy,
-         "restart"        : self.restart,
-         "preserve"       : self.preserve,
-         "rename-restart" : self.renameRestart}[self.info['on_' + reason]]()
-
-
-    def renameRestart(self):
-        self.restart(True)
-
-
-    def dumpCore(self,corefile=None):
+         "restart"        : self._restart,
+         "preserve"       : self._preserve,
+         "rename-restart" : self._renameRestart}[self.info['on_' + reason]]()
+
+
+    def _renameRestart(self):
+        self._restart(True)
+
+    def _restart(self, rename = False):
+        """Restart the domain after it has exited.
+
+        @param rename True if the old domain is to be renamed and preserved,
+        False if it is to be destroyed.
+        """
+        from xen.xend import XendDomain
+        
+        self._configureBootloader()
+        config = self.sxpr()
+
+        if self._infoIsSet('cpus') and len(self.info['cpus']) != 0:
+            config.append(['cpus', reduce(lambda x, y: str(x) + "," + str(y),
+                                          self.info['cpus'])])
+
+        if self._readVm(RESTART_IN_PROGRESS):
+            log.error('Xend failed during restart of domain %s.  '
+                      'Refusing to restart to avoid loops.',
+                      str(self.domid))
+            self.destroy()
+            return
+
+        old_domid = self.domid
+        self._writeVm(RESTART_IN_PROGRESS, 'True')
+
+        now = time.time()
+        rst = self._readVm('xend/previous_restart_time')
+        if rst:
+            rst = float(rst)
+            timeout = now - rst
+            if timeout < MINIMUM_RESTART_TIME:
+                log.error(
+                    'VM %s restarting too fast (%f seconds since the last '
+                    'restart).  Refusing to restart to avoid loops.',
+                    self.info['name'], timeout)
+                self.destroy()
+                return
+
+        self._writeVm('xend/previous_restart_time', str(now))
+
+        try:
+            if rename:
+                self._preserveForRestart()
+            else:
+                self._unwatchVm()
+                self.destroyDomain()
+
+            # new_dom's VM will be the same as this domain's VM, except where
+            # the rename flag has instructed us to call preserveForRestart.
+            # In that case, it is important that we remove the
+            # RESTART_IN_PROGRESS node from the new domain, not the old one,
+            # once the new one is available.
+
+            new_dom = None
+            try:
+                new_dom = XendDomain.instance().domain_create(config)
+                new_dom.unpause()
+                rst_cnt = self._readVm('xend/restart_count')
+                rst_cnt = int(rst_cnt) + 1
+                self._writeVm('xend/restart_count', str(rst_cnt))
+                new_dom._removeVm(RESTART_IN_PROGRESS)
+            except:
+                if new_dom:
+                    new_dom._removeVm(RESTART_IN_PROGRESS)
+                    new_dom.destroy()
+                else:
+                    self._removeVm(RESTART_IN_PROGRESS)
+                raise
+        except:
+            log.exception('Failed to restart domain %s.', str(old_domid))
+
+    def _preserveForRestart(self):
+        """Preserve a domain that has been shut down, by giving it a new UUID,
+        cloning the VM details, and giving it a new name.  This allows us to
+        keep this domain for debugging, but restart a new one in its place
+        preserving the restart semantics (name and UUID preserved).
+        """
+        
+        new_uuid = uuid.createString()
+        new_name = 'Domain-%s' % new_uuid
+        log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
+                 self.info['name'], self.domid, self.info['uuid'],
+                 new_name, new_uuid)
+        self._unwatchVm()
+        self._releaseDevices()
+        self.info['name'] = new_name
+        self.info['uuid'] = new_uuid
+        self.vmpath = XS_VMROOT + new_uuid
+        self._storeVmDetails()
+        self._preserve()
+
+
+    def _preserve(self):
+        log.info("Preserving dead domain %s (%d).", self.info['name'],
+                 self.domid)
+        self._unwatchVm()
+        self._storeDom('xend/shutdown_completed', 'True')
+        self._stateSet(DOM_STATE_HALTED)
+
+    #
+    # Debugging ..
+    #
+
+    def dumpCore(self, corefile = None):
         """Create a core dump for this domain.  Nothrow guarantee."""
         
         try:
@@ -1011,260 +1097,132 @@ class XendDomainInfo:
                           self.domid, self.info['name'])
             raise XendError("Failed to dump core: %s" %  str(ex))
 
-    ## public:
-
-    def setMemoryTarget(self, target):
-        """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)
-        
-        self.info['memory'] = target
-        self.storeVm("memory", target)
-        self.storeDom("memory/target", target << 10)
-
-
-    def update(self, info = None):
-        """Update with info from xc.domain_getinfo().
-        """
-
-        log.trace("XendDomainInfo.update(%s) on domain %d", info, self.domid)
-        if not info:
-            info = dom_get(self.domid)
-            if not info:
-                return
-            
-        #manually update ssidref / security fields
-        if security.on() and info.has_key('ssidref'):
-            if (info['ssidref'] != 0) and self.info.has_key('security'):
-                security_field = self.info['security']
-                if not security_field:
-                    #create new security element
-                    self.info.update({'security': [['ssidref', 
str(info['ssidref'])]]})
-            #ssidref field not used any longer
-        info.pop('ssidref')
-
-        self.info.update(info)
-        self.validateInfo()
-        self.refreshShutdown(info)
-
-        log.trace("XendDomainInfo.update done on domain %d: %s", self.domid,
-                  self.info)
-
-
-    ## private:
-
-    def state_set(self, state):
-        self.state_updated.acquire()
-        try:
-            if self.state != state:
-                self.state = state
-                self.state_updated.notifyAll()
-        finally:
-            self.state_updated.release()
-
-
-    ## public:
-
-    def waitForShutdown(self):
-        self.state_updated.acquire()
-        try:
-            while self.state == STATE_DOM_OK:
-                self.state_updated.wait()
-        finally:
-            self.state_updated.release()
-
-
-    def __str__(self):
-        s = "<domain"
-        s += " id=" + str(self.domid)
-        s += " name=" + self.info['name']
-        s += " memory=" + str(self.info['memory'])
-        s += ">"
-        return s
-
-    __repr__ = __str__
-
-
-    ## private:
-
-    def createDevice(self, deviceClass, devconfig):
-        return self.getDeviceController(deviceClass).createDevice(devconfig)
-
-
-    def waitForDevices_(self, deviceClass):
-        return self.getDeviceController(deviceClass).waitForDevices()
-
-
-    def waitForDevice(self, deviceClass, devid):
+    #
+    # Device creation/deletion functions
+    #
+
+    def _createDevice(self, deviceClass, devConfig):
+        return self.getDeviceController(deviceClass).createDevice(devConfig)
+
+    def _waitForDevice(self, deviceClass, devid):
         return self.getDeviceController(deviceClass).waitForDevice(devid)
 
-
-    def reconfigureDevice(self, deviceClass, devid, devconfig):
+    def _reconfigureDevice(self, deviceClass, devid, devconfig):
         return self.getDeviceController(deviceClass).reconfigureDevice(
             devid, devconfig)
 
-
-    ## 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
-        return self.getDeviceController(deviceClass).destroyDevice(devid)
-
-
-    def getDeviceSxprs(self, deviceClass):
-        return self.getDeviceController(deviceClass).sxprs()
+    def _createDevices(self):
+        """Create the devices for a vm.
+
+        @raise: VmError for invalid devices
+        """
+        for (devclass, config) in self.info.all_devices_sxpr():
+            log.info("createDevice: %s : %s" % (devclass, config))
+            self._createDevice(devclass, config)
+
+        if self.image:
+            self.image.createDeviceModel()
+
+    def _releaseDevices(self):
+        """Release all domain's devices.  Nothrow guarantee."""
+
+        while True:
+            t = xstransact("%s/device" % self.dompath)
+            for devclass in XendDevices.valid_devices():
+                for dev in t.list(devclass):
+                    try:
+                        t.remove(dev)
+                    except:
+                        # Log and swallow any exceptions in removal --
+                        # there's nothing more we can do.
+                        log.exception(
+                           "Device release failed: %s; %s; %s",
+                           self.info['name'], devclass, dev)
+            if t.commit():
+                break
+
+    def getDeviceController(self, name):
+        """Get the device controller for this domain, and if it
+        doesn't exist, create it.
+
+        @param name: device class name
+        @type name: string
+        @rtype: subclass of DevController
+        """
+        if name not in self._deviceControllers:
+            devController = XendDevices.make_controller(name, self)
+            if not devController:
+                raise XendError("Unknown device type: %s" % name)
+            self._deviceControllers[name] = devController
+    
+        return self._deviceControllers[name]
+
+    #
+    # Migration functions (public)
+    # 
+
+    def testMigrateDevices(self, network, dst):
+        """ Notify all device about intention of migration
+        @raise: XendError for a device that cannot be migrated
+        """
+        for (n, c) in self.info.all_devices_sxpr():
+            rc = self.migrateDevice(n, c, network, dst, DEV_MIGRATE_TEST)
+            if rc != 0:
+                raise XendError("Device of type '%s' refuses migration." % n)
+
+    def migrateDevices(self, network, dst, step, domName=''):
+        """Notify the devices about migration
+        """
+        ctr = 0
+        try:
+            for (dev_type, dev_conf) in self.info.all_devices_sxpr():
+                self.migrateDevice(dev_type, dev_conf, network, dst,
+                                   step, domName)
+                ctr = ctr + 1
+        except:
+            for dev_type, dev_conf in self.info.all_devices_sxpr():
+                if ctr == 0:
+                    step = step - 1
+                ctr = ctr - 1
+                self._recoverMigrateDevice(dev_type, dev_conf, network,
+                                           dst, step, domName)
+            raise
+
+    def migrateDevice(self, deviceClass, deviceConfig, network, dst,
+                      step, domName=''):
+        return self.getDeviceController(deviceClass).migrate(deviceConfig,
+                                        network, dst, step, domName)
+
+    def _recoverMigrateDevice(self, deviceClass, deviceConfig, network,
+                             dst, step, domName=''):
+        return self.getDeviceController(deviceClass).recover_migrate(
+                     deviceConfig, network, dst, step, domName)
 
 
     ## private:
 
-    def getDeviceConfigurations(self, deviceClass):
-        return self.getDeviceController(deviceClass).configurations()
-
-
-    def getDeviceController(self, name):
-        if name not in controllerClasses:
-            raise XendError("unknown device type: " + str(name))
-
-        return controllerClasses[name](self)

_______________________________________________
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®.