WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 15 Nov 2006 00:40:22 +0000
Delivery-date: Tue, 14 Nov 2006 16:41:12 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User 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

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