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: Sat, 09 Dec 2006 15:44:13 +0000
Delivery-date: Sat, 09 Dec 2006 07:46:17 -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 d603aed5ad6dfc3c318ef2b8bac2f7a427163cb9
# Parent  6fdbf173142d6b4da68d2019f594f9a81fa70d28
# Parent  275a8f9a07109375cd55a2bf90f111ffa09db06d
merge with xen-unstable.hg
---
 xen/arch/x86/hvm/vmx/io.c                                                     
|  202 -
 .hgignore                                                                     
|    2 
 Config.mk                                                                     
|    2 
 buildconfigs/linux-defconfig_xen0_x86_32                                      
|    1 
 buildconfigs/linux-defconfig_xen0_x86_64                                      
|    1 
 buildconfigs/linux-defconfig_xen_x86_32                                       
|    2 
 buildconfigs/linux-defconfig_xen_x86_64                                       
|    1 
 docs/xen-api/presentation.tex                                                 
|    5 
 docs/xen-api/todo.tex                                                         
|    2 
 docs/xen-api/wire-protocol.tex                                                
|   66 
 docs/xen-api/xenapi-datamodel-graph.dot                                       
|    3 
 docs/xen-api/xenapi-datamodel.tex                                             
|  320 ++
 extras/mini-os/events.c                                                       
|   27 
 extras/mini-os/include/events.h                                               
|    1 
 linux-2.6-xen-sparse/arch/i386/Kconfig                                        
|    2 
 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c                             
|   27 
 linux-2.6-xen-sparse/arch/ia64/kernel/setup.c                                 
|   10 
 linux-2.6-xen-sparse/arch/x86_64/Kconfig                                      
|    2 
 linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c                            
|    6 
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c                           
|   23 
 linux-2.6-xen-sparse/drivers/xen/Kconfig                                      
|   23 
 linux-2.6-xen-sparse/drivers/xen/Makefile                                     
|    2 
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c                          
|    3 
 linux-2.6-xen-sparse/drivers/xen/char/mem.c                                   
|    4 
 linux-2.6-xen-sparse/drivers/xen/console/console.c                            
|   28 
 linux-2.6-xen-sparse/drivers/xen/core/Makefile                                
|    1 
 linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c                         
|  184 +
 linux-2.6-xen-sparse/drivers/xen/fbfront/Makefile                             
|    2 
 linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c                              
|  682 +++++
 linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c                             
|  300 ++
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h                
|    8 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/agp.h                    
|   35 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h              
|    7 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h                 
|    2 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/xenoprof.h               
|    1 
 linux-2.6-xen-sparse/include/xen/xencons.h                                    
|    2 
 linux-2.6-xen-sparse/mm/memory.c                                              
|    1 
 patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch    
|   50 
 patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch    
|   75 
 patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch    
|  197 +
 patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch    
|  156 +
 patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch    
|   44 
 patches/linux-2.6.16.33/kexec-generic.patch                                   
|  167 +
 patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch   
|  114 
 patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch 
|  114 
 patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-i386.patch                 
|   49 
 patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-x86_64.patch               
|   88 
 patches/linux-2.6.16.33/series                                                
|   10 
 tools/Makefile                                                                
|    1 
 tools/blktap/drivers/block-aio.c                                              
|    8 
 tools/blktap/drivers/block-qcow.c                                             
|    9 
 tools/blktap/drivers/tapdisk.c                                                
|    3 
 tools/check/Makefile                                                          
|    6 
 tools/check/check_libvncserver                                                
|   27 
 tools/check/check_sdl                                                         
|   27 
 tools/firmware/vmxassist/setup.c                                              
|   22 
 tools/firmware/vmxassist/trap.S                                               
|   16 
 tools/firmware/vmxassist/util.c                                               
|    6 
 tools/firmware/vmxassist/vm86.c                                               
|   21 
 tools/firmware/vmxassist/vm86.h                                               
|    2 
 tools/ioemu/hw/pci.c                                                          
|   24 
 tools/ioemu/hw/usb-uhci.c                                                     
|    2 
 tools/ioemu/vl.h                                                              
|    7 
 tools/ioemu/vnc.c                                                             
|   20 
 tools/libxc/xc_linux.c                                                        
|    9 
 tools/libxc/xc_solaris.c                                                      
|    9 
 tools/libxc/xenctrl.h                                                         
|   16 
 tools/libxen/Makefile                                                         
|    4 
 tools/libxen/README                                                           
|    5 
 tools/libxen/include/xen_console.h                                            
|  207 +
 tools/libxen/include/xen_console_decl.h                                       
|   30 
 tools/libxen/include/xen_console_protocol.h                                   
|   82 
 tools/libxen/include/xen_console_protocol_internal.h                          
|   37 
 tools/libxen/include/xen_vm.h                                                 
|    9 
 tools/libxen/src/xen_console.c                                                
|  207 +
 tools/libxen/src/xen_console_protocol.c                                       
|   82 
 tools/libxen/src/xen_vm.c                                                     
|   22 
 tools/python/scripts/xapi.domcfg.py                                           
|    2 
 tools/python/scripts/xapi.py                                                  
|   46 
 tools/python/xen/lowlevel/xc/xc.c                                             
|    4 
 tools/python/xen/util/bugtool.py                                              
|    5 
 tools/python/xen/util/mkdir.py                                                
|   44 
 tools/python/xen/util/xmlrpclib2.py                                           
|   13 
 tools/python/xen/web/unix.py                                                  
|   12 
 tools/python/xen/xend/XendAPI.py                                              
|  620 ++--
 tools/python/xen/xend/XendCheckpoint.py                                       
|    4 
 tools/python/xen/xend/XendConfig.py                                           
| 1356 +++++-----
 tools/python/xen/xend/XendConstants.py                                        
|    2 
 tools/python/xen/xend/XendDevices.py                                          
|    4 
 tools/python/xen/xend/XendDomain.py                                           
|   54 
 tools/python/xen/xend/XendDomainInfo.py                                       
|  415 +--
 tools/python/xen/xend/XendLogging.py                                          
|    5 
 tools/python/xen/xend/XendStorageRepository.py                                
|    9 
 tools/python/xen/xend/image.py                                                
|  218 -
 tools/python/xen/xend/server/DevController.py                                 
|    7 
 tools/python/xen/xend/server/SrvDaemon.py                                     
|    4 
 tools/python/xen/xend/server/SrvServer.py                                     
|    2 
 tools/python/xen/xend/server/blkif.py                                         
|   21 
 tools/python/xen/xend/server/iopif.py                                         
|    4 
 tools/python/xen/xend/server/irqif.py                                         
|    2 
 tools/python/xen/xend/server/netif.py                                         
|   24 
 tools/python/xen/xend/server/pciif.py                                         
|   69 
 tools/python/xen/xend/server/pciquirk.py                                      
|   43 
 tools/python/xen/xend/server/tests/test_controllers.py                        
|    6 
 tools/python/xen/xend/server/tpmif.py                                         
|   12 
 tools/python/xen/xend/server/vfbif.py                                         
|   74 
 tools/python/xen/xm/create.py                                                 
|   34 
 tools/python/xen/xm/main.py                                                   
|    4 
 tools/tests/test_x86_emulator.c                                               
|  108 
 tools/xenfb/Makefile                                                          
|   35 
 tools/xenfb/sdlfb.c                                                           
|  342 ++
 tools/xenfb/vncfb.c                                                           
|  401 ++
 tools/xenfb/xenfb.c                                                           
|  711 +++++
 tools/xenfb/xenfb.h                                                           
|   35 
 tools/xm-test/grouptest/xapi                                                  
|    1 
 tools/xm-test/lib/XmTestLib/XenManagedDomain.py                               
|  176 +
 tools/xm-test/lib/XmTestLib/xapi.py                                           
|   66 
 tools/xm-test/tests/vtpm/09_vtpm-xapi.py                                      
|   76 
 tools/xm-test/tests/vtpm/Makefile.am                                          
|    3 
 xen/arch/ia64/xen/Makefile                                                    
|    2 
 xen/arch/ia64/xen/crash.c                                                     
|   19 
 xen/arch/ia64/xen/machine_kexec.c                                             
|   34 
 xen/arch/powerpc/Makefile                                                     
|    2 
 xen/arch/powerpc/crash.c                                                      
|   19 
 xen/arch/powerpc/machine_kexec.c                                              
|   34 
 xen/arch/x86/Makefile                                                         
|    2 
 xen/arch/x86/crash.c                                                          
|  128 
 xen/arch/x86/hvm/platform.c                                                   
|   18 
 xen/arch/x86/hvm/svm/emulate.c                                                
|   15 
 xen/arch/x86/hvm/svm/svm.c                                                    
|  232 +
 xen/arch/x86/hvm/svm/vmcb.c                                                   
|   22 
 xen/arch/x86/hvm/vlapic.c                                                     
|   11 
 xen/arch/x86/hvm/vmx/Makefile                                                 
|    2 
 xen/arch/x86/hvm/vmx/intr.c                                                   
|  196 +
 xen/arch/x86/hvm/vmx/vmx.c                                                    
|  318 +-
 xen/arch/x86/machine_kexec.c                                                  
|  105 
 xen/arch/x86/mm.c                                                             
|   98 
 xen/arch/x86/mm/shadow/common.c                                               
|  313 +-
 xen/arch/x86/mm/shadow/multi.c                                                
|   83 
 xen/arch/x86/mm/shadow/private.h                                              
|   19 
 xen/arch/x86/oprofile/op_model_athlon.c                                       
|    9 
 xen/arch/x86/setup.c                                                          
|   74 
 xen/arch/x86/traps.c                                                          
|    2 
 xen/arch/x86/x86_32/entry.S                                                   
|    2 
 xen/arch/x86/x86_64/entry.S                                                   
|    2 
 xen/arch/x86/x86_emulate.c                                                    
|  558 +---
 xen/common/Makefile                                                           
|    1 
 xen/common/domain.c                                                           
|    4 
 xen/common/kexec.c                                                            
|  350 ++
 xen/common/page_alloc.c                                                       
|   37 
 xen/drivers/char/console.c                                                    
|    3 
 xen/include/asm-ia64/elf.h                                                    
|   30 
 xen/include/asm-ia64/kexec.h                                                  
|   25 
 xen/include/asm-ia64/softirq.h                                                
|    6 
 xen/include/asm-powerpc/elf.h                                                 
|   30 
 xen/include/asm-powerpc/kexec.h                                               
|   25 
 xen/include/asm-powerpc/softirq.h                                             
|    6 
 xen/include/asm-x86/domain.h                                                  
|    2 
 xen/include/asm-x86/elf.h                                                     
|   24 
 xen/include/asm-x86/fixmap.h                                                  
|    4 
 xen/include/asm-x86/hvm/hvm.h                                                 
|   71 
 xen/include/asm-x86/hvm/svm/vmcb.h                                            
|   50 
 xen/include/asm-x86/hvm/vlapic.h                                              
|    1 
 xen/include/asm-x86/hvm/vmx/vmx.h                                             
|    7 
 xen/include/asm-x86/hypercall.h                                               
|    5 
 xen/include/asm-x86/kexec.h                                                   
|   20 
 xen/include/asm-x86/shadow.h                                                  
|    8 
 xen/include/asm-x86/softirq.h                                                 
|    6 
 xen/include/asm-x86/x86_32/elf.h                                              
|   72 
 xen/include/asm-x86/x86_32/kexec.h                                            
|   40 
 xen/include/asm-x86/x86_32/page.h                                             
|    2 
 xen/include/asm-x86/x86_64/elf.h                                              
|   92 
 xen/include/asm-x86/x86_64/kexec.h                                            
|   39 
 xen/include/asm-x86/x86_64/page.h                                             
|    2 
 xen/include/asm-x86/x86_emulate.h                                             
|  139 -
 xen/include/public/elfnote.h                                                  
|   19 
 xen/include/public/io/fbif.h                                                  
|  116 
 xen/include/public/io/kbdif.h                                                 
|  108 
 xen/include/public/kexec.h                                                    
|  138 +
 xen/include/xen/elf.h                                                         
|   20 
 xen/include/xen/elfcore.h                                                     
|  140 +
 xen/include/xen/hypercall.h                                                   
|    6 
 xen/include/xen/kexec.h                                                       
|   45 
 xen/include/xen/mm.h                                                          
|    1 
 xen/include/xen/softirq.h                                                     
|   13 
 185 files changed, 10427 insertions(+), 2646 deletions(-)

diff -r 6fdbf173142d -r d603aed5ad6d .hgignore
--- a/.hgignore Sat Dec 02 15:19:50 2006 -0700
+++ b/.hgignore Mon Dec 04 08:24:41 2006 -0700
@@ -158,6 +158,8 @@
 ^tools/xcutils/xc_restore$
 ^tools/xcutils/xc_save$
 ^tools/xcutils/readnotes$
+^tools/xenfb/sdlfb$
+^tools/xenfb/vncfb$
 ^tools/xenmon/xentrace_setmask$
 ^tools/xenmon/xenbaked$
 ^tools/xenstat/xentop/xentop$
diff -r 6fdbf173142d -r d603aed5ad6d Config.mk
--- a/Config.mk Sat Dec 02 15:19:50 2006 -0700
+++ b/Config.mk Mon Dec 04 08:24:41 2006 -0700
@@ -69,8 +69,8 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_
 
 # Optional components
 XENSTAT_XENTOP ?= y
-
 VTPM_TOOLS ?= n
 LIBXENAPI_BINDINGS ?= n
+XENFB_TOOLS ?= n
 
 -include $(XEN_ROOT)/.config
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32  Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_x86_32  Mon Dec 04 08:24:41 2006 -0700
@@ -179,6 +179,7 @@ CONFIG_HZ_100=y
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
+CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x100000
 
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64  Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_x86_64  Mon Dec 04 08:24:41 2006 -0700
@@ -126,6 +126,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_SWIOTLB=y
+CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x100000
 CONFIG_SECCOMP=y
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Mon Dec 04 08:24:41 2006 -0700
@@ -184,6 +184,7 @@ CONFIG_REGPARM=y
 CONFIG_REGPARM=y
 CONFIG_SECCOMP=y
 CONFIG_HZ_100=y
+CONFIG_KEXEC=y
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
@@ -2776,6 +2777,7 @@ CONFIG_NTFS_FS=m
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+# CONFIG_PROC_VMCORE is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Mon Dec 04 08:24:41 2006 -0700
@@ -139,6 +139,7 @@ CONFIG_PHYSICAL_START=0x100000
 CONFIG_PHYSICAL_START=0x100000
 CONFIG_SECCOMP=y
 CONFIG_HZ_100=y
+CONFIG_KEXEC=y
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/presentation.tex
--- a/docs/xen-api/presentation.tex     Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/presentation.tex     Mon Dec 04 08:24:41 2006 -0700
@@ -131,9 +131,6 @@ of that class that has the specified {\t
 ``{\tt get\_by\_name\_label(name)}'' RPC that returns a set of objects of that
 class that have the specified {\tt label}.
 
-\item Each class has a ``{\tt to\_XML()}'' RPC that serialises the
-state of all fields as an XML string.
-
 \item Each class has a ``{\tt destroy(Ref x)}'' RPC that explicitly deletes
 the persistent object specified by {\tt x} from the system.  This is a
 non-cascading delete -- if the object being removed is referenced by another
@@ -144,6 +141,6 @@ object then the {\tt destroy} call will 
 \subsection{Additional RPCs}
 
 As well as the RPCs enumerated above, some classes have additional RPCs
-associated with them. For example, the {\tt VM} class have RPCs for cloning,
+associated with them. For example, the {\tt VM} class has RPCs for cloning,
 suspending, starting etc. Such additional RPCs are described explicitly
 in the API reference.
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/todo.tex
--- a/docs/xen-api/todo.tex     Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/todo.tex     Mon Dec 04 08:24:41 2006 -0700
@@ -34,6 +34,8 @@ code, potential error description, but o
 
 \item Clarify behaviour of progress field on asyncrhonous request polling when
 that request fails.
+
+\item Clarify which calls have asynchronous counterparts by marking them as 
such in the reference. (Individual getters and setters are too small and quick 
to justify having async versions)
 
 \end{itemize}
 
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/wire-protocol.tex
--- a/docs/xen-api/wire-protocol.tex    Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/wire-protocol.tex    Mon Dec 04 08:24:41 2006 -0700
@@ -21,9 +21,9 @@ In our API Reference we specify the sign
 In our API Reference we specify the signatures of API functions in the 
following
 style:
 \begin{verbatim}
-    (ref_vm Set)   Host.ListAllVMs()
-\end{verbatim}
-This specifies that the function with name {\tt Host.ListAllVMs} takes
+    (ref_vm Set)   VM.get_all()
+\end{verbatim}
+This specifies that the function with name {\tt VM.get\_all} takes
 no parameters and returns a Set of {\tt ref\_vm}s.
 These types are mapped onto XML-RPC types in a straight-forward manner:
 \begin{itemize}
@@ -105,8 +105,8 @@ the struct contains a second element nam
 the struct contains a second element named {\tt ErrorDescription}:
 \begin{itemize}
 \item The element of the struct named {\tt ErrorDescription} contains
-an array of string values. The first element of the array represents an error 
code;
-the remainder of the array represents error parameters relating to that code.
+an array of string values. The first element of the array is an XML-RPC 32-bit 
{\tt i4} and represents an error code;
+the remainder of the array are strings representing error parameters relating 
to that code.
 \end{itemize}
 
 For example, an XML-RPC return value from the {\tt Host.ListAllVMs} function 
above
@@ -161,19 +161,19 @@ A session can be terminated with the {\t
 
 \subsection{Synchronous and Asynchronous invocation}
 
-Each method call (apart from those on ``Session'' and ``Task'' objects)
+Each method call (apart from methods on ``Session'' and ``Task'' objects 
+and ``getters'' and ``setters'' derived from fields)
 can be made either synchronously or asynchronously.
 A synchronous RPC call blocks until the
 return value is received; the return value of a synchronous RPC call is
 exactly as specified in Section~\ref{synchronous-result}.
 
-Each of the methods specified in the API Reference is synchronous.
-However, although not listed explicitly in this document, each
-method call has an asynchronous analogue in the {\tt Async}
-namespace. For example, synchronous call {\tt VM.Install(...)}
+Only synchronous API calls are listed explicitly in this document. 
+All asynchronous versions are in the special {\tt Async} namespace.
+For example, synchronous call {\tt VM.clone(...)}
 (described in Chapter~\ref{api-reference})
 has an asynchronous counterpart, {\tt
-Async.VM.Install(...)}, that is non-blocking.
+Async.VM.clone(...)}, that is non-blocking.
 
 Instead of returning its result directly, an asynchronous RPC call
 returns a {\tt task-id}; this identifier is subsequently used
@@ -186,39 +186,14 @@ The {\tt task-id} is provided in the {\t
 The {\tt task-id} is provided in the {\tt Value} field if {\tt Status} is set 
to
 {\tt Success}.
 
-Two special RPC calls are provided to poll the status of
-asynchronous calls:
-\begin{verbatim}
-    Array<task_id>  Async.Task.GetAllTasks (session_id s)
-    task_status     Async.Task.GetStatus   (session_id s, task_id t)
-\end{verbatim}
-
-{\tt Async.Task.GetAllTasks} returns a set of the currently
-executing asynchronous tasks belong to the current user\footnote{
-%
-The current user is determined by the username that was provided
-to {\tt Session.Login}.
-%
-}.
-
-{\tt Async.Task.GetStatus} returns a {\tt task\_status} result.
-This is an XML-RPC struct with three elements:
-\begin{itemize}
-  \item The first element is named {\tt Progress} and contains
-an {\tt Integer} between 0 and 100 representing the estimated percentage of
-the task currently completed.
-  \item The second element is named {\tt ETA} and contains a {\tt DateTime} 
-representing the estimated time the task will be complete.
-  \item The third element is named {\tt Result}. If {\tt Progress}
-is not 100 then {\tt Result} contains the empty string. If {\tt Progress}
-{\em is\/} set to 100, then {\tt Result} contains the function's return
-result (as specified in Section~\ref{synchronous-result})\footnote{
-%
-Recall that this itself is a struct potentially containing status, errorcode,
-value fields etc.
-%
-}.
-\end{itemize}
+The RPC call
+\begin{verbatim}
+    (ref_task Set)   Task.get_all(session_id s)
+\end{verbatim} 
+returns a set of all task IDs known to the system. The status (including any
+returned result and error codes) of these tasks
+can then be queried by accessing the fields of the Task object in the usual 
way. 
+Note that, in order to get a consistent snapshot of a task's state, it is 
advisable to call the ``get\_record'' function.
 
 \section{Example interactive session}
 
@@ -267,7 +242,8 @@ Next, the user may acquire a list of all
 \begin{verbatim}
 >>> all_vms = xen.VM.do_list(session)['Value']
 >>> all_vms
-['b7b92d9e-d442-4710-92a5-ab039fd7d89b', 
'23e1e837-abbf-4675-b077-d4007989b0cc', '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', 
'3202ae18-a046-4c32-9fda-e32e9631866e']
+['b7b92d9e-d442-4710-92a5-ab039fd7d89b', 
'23e1e837-abbf-4675-b077-d4007989b0cc',
+  '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', 
'3202ae18-a046-4c32-9fda-e32e9631866e']
 \end{verbatim}
 
 Note the VM references are internally UUIDs. Once a reference to a VM has been 
acquired a lifecycle operation may be invoked:
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/xenapi-datamodel-graph.dot
--- a/docs/xen-api/xenapi-datamodel-graph.dot   Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/xenapi-datamodel-graph.dot   Mon Dec 04 08:24:41 2006 -0700
@@ -1,5 +1,5 @@ digraph g{
 digraph g{
-node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM 
[ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ] 
network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR 
[ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [ 
URL="VTPM.html" ] user [ URL="user.html" ] debug [ URL="debug.html" ];
+node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM 
[ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ] 
network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR 
[ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [ 
URL="VTPM.html" ] console [ URL="console.html" ] user [ URL="user.html" ] debug 
[ URL="debug.html" ];
 session -> host [ label="this_host(1)" ]
 session -> user [ label="this_user(1)" ]
 host -> VM [ color="blue", arrowhead="crow", arrowtail="none" ]
@@ -14,4 +14,5 @@ VBD -> VM [ color="blue", arrowhead="non
 VBD -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
 VTPM -> VM [ label="backend(1)" ]
 VTPM -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
+console -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
 }
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/xenapi-datamodel.tex Mon Dec 04 08:24:41 2006 -0700
@@ -34,6 +34,7 @@ Name & Description \\
 {\tt VDI} & A virtual disk image \\
 {\tt VBD} & A virtual block device \\
 {\tt VTPM} & A virtual TPM device \\
+{\tt console} & A console \\
 {\tt user} & A user of the system \\
 {\tt debug} & A basic class for testing \\
 \hline
@@ -54,6 +55,7 @@ PIF.network & network.PIFs & one-to-many
 PIF.network & network.PIFs & one-to-many\\
 SR.VDIs & VDI.SR & many-to-one\\
 VTPM.VM & VM.VTPMs & one-to-many\\
+console.VM & VM.consoles & one-to-many\\
 host.resident\_VMs & VM.resident\_on & many-to-one\\
 host.host\_CPUs & host\_cpu.host & many-to-one\\
 \hline
@@ -96,6 +98,16 @@ Map (a $\rightarrow$ b) & a table mappin
 \end{tabular}\end{center}
 \subsection{Enumeration types}
 The following enumeration types are used:
+
+\begin{longtable}{|ll|}
+\hline
+{\tt enum console\_protocol} & \\
+\hline
+\hspace{0.5cm}{\tt vt100} & VT100 terminal \\
+\hspace{0.5cm}{\tt rfb} & Remote FrameBuffer protocol (as used in VNC) \\
+\hspace{0.5cm}{\tt rdp} & Remote Desktop Protocol \\
+\hline
+\end{longtable}
 
 \begin{longtable}{|ll|}
 \hline
@@ -947,6 +959,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt actions/after\_reboot} & on\_normal\_exit & action to 
take after the guest has rebooted itself \\
 $\mathit{RW}$ &  {\tt actions/after\_suspend} & on\_normal\_exit & action to 
take after the guest has suspended itself \\
 $\mathit{RW}$ &  {\tt actions/after\_crash} & on\_crash\_behaviour & action to 
take if the guest crashes \\
+$\mathit{RO}_\mathit{run}$ &  {\tt consoles} & (console ref) Set & virtual 
console devices \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VIFs} & (VIF ref) Set & virtual network 
interfaces \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VBDs} & (VBD ref) Set & virtual block 
devices \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VTPMs} & (VTPM ref) Set & virtual TPMs \\
@@ -2628,6 +2641,38 @@ void
 
 
 
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_consoles}
+
+{\bf Overview:} 
+Get the consoles field of the given VM.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((console ref) Set) get_consoles (session_id s, VM ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VM ref } & self & object instance \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+(console ref) Set
+}
+
+
+value of the field
 \vspace{0.3cm}
 \vspace{0.3cm}
 \vspace{0.3cm}
@@ -9187,6 +9232,281 @@ all fields from the object
 
 \vspace{1cm}
 \newpage
+\section{Class: console}
+\subsection{Fields for class: console}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf console} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A 
console}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object 
reference \\
+$\mathit{RO}_\mathit{run}$ &  {\tt protocol} & console\_protocol & the 
protocol used by this console \\
+$\mathit{RO}_\mathit{run}$ &  {\tt uri} & string & URI for the console service 
\\
+$\mathit{RO}_\mathit{run}$ &  {\tt VM} & VM ref & VM to which this console is 
attached \\
+\hline
+\end{longtable}
+\subsection{Additional RPCs associated with class: console}
+\subsubsection{RPC name:~get\_record}
+
+{\bf Overview:} 
+Get the current state of the given console.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (console record) get_record (session_id s, console ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+console record
+}
+
+
+all fields from the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_by\_uuid}
+
+{\bf Overview:} 
+Get a reference to the object with the specified UUID.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (console ref) get_by_uuid (session_id s, string 
uuid)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string } & uuid & UUID of object to return \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+console ref
+}
+
+
+reference to the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~create}
+
+{\bf Overview:} 
+Create a new console instance, and return its handle.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (console ref) create (session_id s, console record 
args)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console record } & args & All constructor arguments \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+console ref
+}
+
+
+reference to the newly created object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~destroy}
+
+{\bf Overview:} 
+Destroy the specified console instance.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void destroy (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_uuid}
+
+{\bf Overview:} 
+Get the uuid field of the given console.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_uuid (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+string
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_protocol}
+
+{\bf Overview:} 
+Get the protocol field of the given console.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (console_protocol) get_protocol (session_id s, console ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+console\_protocol
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_uri}
+
+{\bf Overview:} 
+Get the uri field of the given console.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_uri (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+string
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_VM}
+
+{\bf Overview:} 
+Get the VM field of the given console.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (VM ref) get_VM (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+VM ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
 \section{Class: user}
 \subsection{Fields for class: user}
 \begin{longtable}{|lllp{0.38\textwidth}|}
diff -r 6fdbf173142d -r d603aed5ad6d extras/mini-os/events.c
--- a/extras/mini-os/events.c   Sat Dec 02 15:19:50 2006 -0700
+++ b/extras/mini-os/events.c   Mon Dec 04 08:24:41 2006 -0700
@@ -31,26 +31,27 @@ typedef struct _ev_action_t {
     u32 count;
 } ev_action_t;
 
-
 static ev_action_t ev_actions[NR_EVS];
 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
+
+static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];
 
 void unbind_all_ports(void)
 {
     int i;
 
-       for(i=0;i<NR_EVS;i++)
-       {
-               if(ev_actions[i].handler != default_handler)
-               {
-                       struct evtchn_close close;
-                       mask_evtchn(i);
-                       close.port = i;
-                       HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
-               }
-       }
+    for (i = 0; i < NR_EVS; i++)
+    {
+        if (test_and_clear_bit(i, bound_ports))
+        {
+            struct evtchn_close close;
+            mask_evtchn(i);
+            close.port = i;
+            HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+        }
+    }
 }
-
+  
 /*
  * Demux events to different handlers.
  */
@@ -114,6 +115,7 @@ int bind_virq(uint32_t virq, evtchn_hand
                printk("Failed to bind virtual IRQ %d\n", virq);
                return 1;
     }
+    set_bit(op.port,bound_ports);
     bind_evtchn(op.port, handler, data);
        return 0;
 }
@@ -188,6 +190,7 @@ int evtchn_bind_interdomain(domid_t pal,
     int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
     if (err)
                return err;
+    set_bit(op.local_port,bound_ports);
        evtchn_port_t port = op.local_port;
     clear_evtchn(port);              /* Without, handler gets invoked now! */
     *local_port = bind_evtchn(port, handler, data);
diff -r 6fdbf173142d -r d603aed5ad6d extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h   Sat Dec 02 15:19:50 2006 -0700
+++ b/extras/mini-os/include/events.h   Mon Dec 04 08:24:41 2006 -0700
@@ -36,6 +36,7 @@ int evtchn_bind_interdomain(domid_t pal,
 int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
                                                        evtchn_handler_t 
handler, void *data,
                                                        evtchn_port_t 
*local_port);
+void unbind_all_ports(void);
 
 static inline int notify_remote_via_evtchn(evtchn_port_t port)
 {
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig    Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig    Mon Dec 04 08:24:41 2006 -0700
@@ -726,7 +726,7 @@ source kernel/Kconfig.hz
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && !X86_XEN
+       depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Sat Dec 02 15:19:50 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon Dec 04 08:24:41 
2006 -0700
@@ -68,6 +68,10 @@
 #include <xen/xencons.h>
 #include "setup_arch_pre.h"
 #include <bios_ebda.h>
+
+#ifdef CONFIG_XEN
+#include <xen/interface/kexec.h>
+#endif
 
 /* Forward Declaration. */
 void __init find_max_pfn(void);
@@ -943,6 +947,7 @@ static void __init parse_cmdline_early (
                 * after a kernel panic.
                 */
                else if (!memcmp(from, "crashkernel=", 12)) {
+#ifndef CONFIG_XEN
                        unsigned long size, base;
                        size = memparse(from+12, &from);
                        if (*from == '@') {
@@ -953,6 +958,10 @@ static void __init parse_cmdline_early (
                                crashk_res.start = base;
                                crashk_res.end   = base + size - 1;
                        }
+#else
+                       printk("Ignoring crashkernel command line, "
+                              "parameter will be supplied by xen\n");
+#endif
                }
 #endif
 #ifdef CONFIG_PROC_VMCORE
@@ -1322,9 +1331,13 @@ void __init setup_bootmem_allocator(void
        }
 #endif
 #ifdef CONFIG_KEXEC
+#ifdef CONFIG_XEN
+       xen_machine_kexec_setup_resources();
+#else
        if (crashk_res.start != crashk_res.end)
                reserve_bootmem(crashk_res.start,
                        crashk_res.end - crashk_res.start + 1);
+#endif
 #endif
 
        if (!xen_feature(XENFEAT_auto_translated_physmap))
@@ -1389,7 +1402,11 @@ legacy_init_iomem_resources(struct e820e
                        request_resource(res, data_resource);
 #endif
 #ifdef CONFIG_KEXEC
-                       request_resource(res, &crashk_res);
+                       if (crashk_res.start != crashk_res.end)
+                            request_resource(res, &crashk_res);
+#ifdef CONFIG_XEN
+                       xen_machine_kexec_register_resources(res);
+#endif
 #endif
                }
        }
@@ -1850,9 +1867,11 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
        } else {
-               extern int console_use_vt;
-               console_use_vt = 0;
-       }
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+               conswitchp = &dummy_con;
+#endif
+       }
+       xencons_early_setup();
 }
 
 static int
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Sat Dec 02 15:19:50 
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Mon Dec 04 08:24:41 
2006 -0700
@@ -550,13 +550,15 @@ setup_arch (char **cmdline_p)
                       xen_start_info->nr_pages, xen_start_info->flags);
 
                if (!is_initial_xendomain()) {
-                       extern int console_use_vt;
+#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
                        conswitchp = NULL;
-                       console_use_vt = 0;
+#endif
                }
        }
-#endif
-#endif
+       xencons_early_setup();
+#endif
+#endif
+
 
        /* enable IA-64 Machine Check Abort Handling unless disabled */
        if (!strstr(saved_command_line, "nomca"))
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/arch/x86_64/Kconfig
--- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig  Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig  Mon Dec 04 08:24:41 2006 -0700
@@ -435,7 +435,7 @@ config X86_MCE_AMD
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && !X86_64_XEN
+       depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c        Sat Dec 02 
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c        Mon Dec 04 
08:24:41 2006 -0700
@@ -260,7 +260,11 @@ void __init e820_reserve_resources(struc
                        request_resource(res, &data_resource);
 #endif
 #ifdef CONFIG_KEXEC
-                       request_resource(res, &crashk_res);
+                       if (crashk_res.start != crashk_res.end)
+                               request_resource(res, &crashk_res);
+#ifdef CONFIG_XEN
+                       xen_machine_kexec_register_resources(res);
+#endif
 #endif
                }
        }
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Sat Dec 02 
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Mon Dec 04 
08:24:41 2006 -0700
@@ -80,6 +80,10 @@
 #include <asm/mach-xen/setup_arch_post.h>
 #include <xen/interface/memory.h>
 
+#ifdef CONFIG_XEN
+#include <xen/interface/kexec.h>
+#endif
+
 extern unsigned long start_pfn;
 extern struct edid_info edid_info;
 
@@ -450,6 +454,7 @@ static __init void parse_cmdline_early (
                 * after a kernel panic.
                 */
                else if (!memcmp(from, "crashkernel=", 12)) {
+#ifndef CONFIG_XEN
                        unsigned long size, base;
                        size = memparse(from+12, &from);
                        if (*from == '@') {
@@ -460,6 +465,10 @@ static __init void parse_cmdline_early (
                                crashk_res.start = base;
                                crashk_res.end   = base + size - 1;
                        }
+#else
+                       printk("Ignoring crashkernel command line, "
+                              "parameter will be supplied by xen\n");
+#endif
                }
 #endif
 
@@ -812,10 +821,14 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif /* !CONFIG_XEN */
 #ifdef CONFIG_KEXEC
+#ifdef CONFIG_XEN
+       xen_machine_kexec_setup_resources();
+#else
        if (crashk_res.start != crashk_res.end) {
                reserve_bootmem(crashk_res.start,
                        crashk_res.end - crashk_res.start + 1);
        }
+#endif
 #endif
 
        paging_init();
@@ -970,10 +983,12 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
                } else {
-                       extern int console_use_vt;
-                       console_use_vt = 0;
-               }
-       }
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+                       conswitchp = &dummy_con;
+#endif
+                }
+       }
+       xencons_early_setup();
 #else  /* CONFIG_XEN */
 
 #ifdef CONFIG_VT
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig  Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig  Mon Dec 04 08:24:41 2006 -0700
@@ -172,6 +172,29 @@ config XEN_NETDEV_FRONTEND
          dedicated device-driver domain, or your master control domain
          (domain 0), then you almost certainly want to say Y here.
 
+config XEN_FRAMEBUFFER
+       tristate "Framebuffer-device frontend driver"
+       depends on XEN && FB
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       default y
+       help
+         The framebuffer-device frontend drivers allows the kernel to create a
+         virtual framebuffer.  This framebuffer can be viewed in another
+         domain.  Unless this domain has access to a real video card, you
+         probably want to say Y here.
+
+config XEN_KEYBOARD
+       tristate "Keyboard-device frontend driver"
+       depends on XEN && XEN_FRAMEBUFFER && INPUT
+       default y
+       help
+         The keyboard-device frontend driver allows the kernel to create a
+         virtual keyboard.  This keyboard can then be driven by another
+         domain.  If you've said Y to CONFIG_XEN_FRAMEBUFFER, you probably
+         want to say Y here.
+
 config XEN_SCRUB_PAGES
        bool "Scrub memory before freeing it to Xen"
        default y
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -15,3 +15,5 @@ obj-$(CONFIG_XEN_NETDEV_FRONTEND)     += net
 obj-$(CONFIG_XEN_NETDEV_FRONTEND)      += netfront/
 obj-$(CONFIG_XEN_PCIDEV_BACKEND)       += pciback/
 obj-$(CONFIG_XEN_PCIDEV_FRONTEND)      += pcifront/
+obj-$(CONFIG_XEN_FRAMEBUFFER)          += fbfront/
+obj-$(CONFIG_XEN_KEYBOARD)             += fbfront/
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Sat Dec 02 
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Mon Dec 04 
08:24:41 2006 -0700
@@ -359,7 +359,7 @@ static void blkfront_closing(struct xenb
        DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
 
        if (info->rq == NULL)
-               return;
+               goto out;
 
        spin_lock_irqsave(&blkif_io_lock, flags);
        /* No more blkif_request(). */
@@ -373,6 +373,7 @@ static void blkfront_closing(struct xenb
 
        xlvbd_del(info);
 
+ out:
        xenbus_frontend_closed(dev);
 }
 
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/drivers/xen/char/mem.c
--- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c       Sat Dec 02 15:19:50 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c       Mon Dec 04 08:24:41 
2006 -0700
@@ -147,7 +147,7 @@ static inline int uncached_access(struct
        return 0;
 }
 
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+static int xen_mmap_mem(struct file * file, struct vm_area_struct * vma)
 {
        size_t size = vma->vm_end - vma->vm_start;
 
@@ -200,6 +200,6 @@ struct file_operations mem_fops = {
        .llseek         = memory_lseek,
        .read           = read_mem,
        .write          = write_mem,
-       .mmap           = mmap_mem,
+       .mmap           = xen_mmap_mem,
        .open           = open_mem,
 };
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c        Sat Dec 02 
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c        Mon Dec 04 
08:24:41 2006 -0700
@@ -57,6 +57,7 @@
 #include <xen/interface/event_channel.h>
 #include <asm/hypervisor.h>
 #include <xen/evtchn.h>
+#include <xen/xenbus.h>
 #include <xen/xencons.h>
 
 /*
@@ -65,14 +66,14 @@
  *  'xencons=tty'  [XC_TTY]:     Console attached to '/dev/tty[0-9]+'.
  *  'xencons=ttyS' [XC_SERIAL]:  Console attached to '/dev/ttyS[0-9]+'.
  *  'xencons=xvc'  [XC_XVC]:     Console attached to '/dev/xvc0'.
- *                 [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY.
+ *  default:                     DOM0 -> XC_SERIAL ; all others -> XC_TTY.
  * 
  * NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses
  * warnings from standard distro startup scripts.
  */
 static enum {
-       XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL, XC_XVC
-} xc_mode = XC_DEFAULT;
+       XC_OFF, XC_TTY, XC_SERIAL, XC_XVC
+} xc_mode;
 static int xc_num = -1;
 
 /* /dev/xvc0 device number allocated by lanana.org. */
@@ -84,17 +85,32 @@ extern int sysrq_enabled;
 extern int sysrq_enabled;
 #endif
 
+void xencons_early_setup(void)
+{
+       extern int console_use_vt;
+
+       if (is_initial_xendomain()) {
+               xc_mode = XC_SERIAL;
+       } else {
+               xc_mode = XC_TTY;
+               console_use_vt = 0;
+       }
+}
+
 static int __init xencons_setup(char *str)
 {
        char *q;
        int n;
-
+       extern int console_use_vt;
+
+       console_use_vt = 1;
        if (!strncmp(str, "ttyS", 4)) {
                xc_mode = XC_SERIAL;
                str += 4;
        } else if (!strncmp(str, "tty", 3)) {
                xc_mode = XC_TTY;
                str += 3;
+               console_use_vt = 0;
        } else if (!strncmp(str, "xvc", 3)) {
                xc_mode = XC_XVC;
                str += 3;
@@ -192,14 +208,10 @@ static int __init xen_console_init(void)
                goto out;
 
        if (is_initial_xendomain()) {
-               if (xc_mode == XC_DEFAULT)
-                       xc_mode = XC_SERIAL;
                kcons_info.write = kcons_write_dom0;
        } else {
                if (!xen_start_info->console.domU.evtchn)
                        goto out;
-               if (xc_mode == XC_DEFAULT)
-                       xc_mode = XC_TTY;
                kcons_info.write = kcons_write;
        }
 
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/drivers/xen/core/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Sat Dec 02 15:19:50 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Mon Dec 04 08:24:41 
2006 -0700
@@ -11,3 +11,4 @@ obj-$(CONFIG_XEN_SKBUFF)      += skbuff.o
 obj-$(CONFIG_XEN_SKBUFF)       += skbuff.o
 obj-$(CONFIG_XEN_REBOOT)       += reboot.o machine_reboot.o
 obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
+obj-$(CONFIG_KEXEC)            += machine_kexec.o
diff -r 6fdbf173142d -r d603aed5ad6d 
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    Sat Dec 
02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h    Mon Dec 
04 08:24:41 2006 -0700
@@ -395,5 +395,13 @@ HYPERVISOR_xenoprof_op(
        return _hypercall2(int, xenoprof_op, op, arg);
 }
 
+static inline int
+HYPERVISOR_kexec_op(
+       unsigned long op, void *args)
+{
+       return _hypercall2(int, kexec_op, op, args);
+}
+
+
 
 #endif /* __HYPERCALL_H__ */
diff -r 6fdbf173142d -r d603aed5ad6d 
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  Sat Dec 
02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h  Mon Dec 
04 08:24:41 2006 -0700
@@ -396,4 +396,11 @@ HYPERVISOR_xenoprof_op(
        return _hypercall2(int, xenoprof_op, op, arg);
 }
 
+static inline int
+HYPERVISOR_kexec_op(
+       unsigned long op, void *args)
+{
+       return _hypercall2(int, kexec_op, op, args);
+}
+
 #endif /* __HYPERCALL_H__ */
diff -r 6fdbf173142d -r d603aed5ad6d 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h     Sat Dec 
02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h     Mon Dec 
04 08:24:41 2006 -0700
@@ -90,6 +90,8 @@ extern unsigned long profile_pc(struct p
 #define profile_pc(regs) instruction_pointer(regs)
 #endif
 
+#include <linux/compiler.h>
+
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
 struct task_struct;
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/include/xen/xencons.h
--- a/linux-2.6-xen-sparse/include/xen/xencons.h        Sat Dec 02 15:19:50 
2006 -0700
+++ b/linux-2.6-xen-sparse/include/xen/xencons.h        Mon Dec 04 08:24:41 
2006 -0700
@@ -14,4 +14,6 @@ int xencons_ring_init(void);
 int xencons_ring_init(void);
 int xencons_ring_send(const char *data, unsigned len);
 
+void xencons_early_setup(void);
+
 #endif /* __ASM_XENCONS_H__ */
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c  Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/mm/memory.c  Mon Dec 04 08:24:41 2006 -0700
@@ -882,6 +882,7 @@ unsigned long zap_page_range(struct vm_a
                tlb_finish_mmu(tlb, address, end);
        return end;
 }
+EXPORT_SYMBOL(zap_page_range);
 
 /*
  * Do a quick page-table lookup for a single page.
diff -r 6fdbf173142d -r d603aed5ad6d patches/linux-2.6.16.33/series
--- a/patches/linux-2.6.16.33/series    Sat Dec 02 15:19:50 2006 -0700
+++ b/patches/linux-2.6.16.33/series    Mon Dec 04 08:24:41 2006 -0700
@@ -1,3 +1,12 @@ blktap-aio-16_03_06.patch
+kexec-generic.patch
+git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
+git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
+git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch
+linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
+linux-2.6.19-rc1-kexec-xen-i386.patch
+git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch
+linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch
+linux-2.6.19-rc1-kexec-xen-x86_64.patch
 blktap-aio-16_03_06.patch
 device_bind.patch
 fix-hz-suspend.patch
@@ -22,6 +31,7 @@ xenoprof-generic.patch
 xenoprof-generic.patch
 x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
 x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
+git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch
 x86-elfnote-as-preprocessor-macro.patch
 vsnprintf.patch
 kasprintf.patch
diff -r 6fdbf173142d -r d603aed5ad6d tools/Makefile
--- a/tools/Makefile    Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/Makefile    Mon Dec 04 08:24:41 2006 -0700
@@ -19,6 +19,7 @@ SUBDIRS-y += libaio
 SUBDIRS-y += libaio
 SUBDIRS-y += blktap
 SUBDIRS-y += libfsimage
+SUBDIRS-$(XENFB_TOOLS) += xenfb
 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
 
 # These don't cross-compile
diff -r 6fdbf173142d -r d603aed5ad6d tools/blktap/drivers/block-aio.c
--- a/tools/blktap/drivers/block-aio.c  Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/blktap/drivers/block-aio.c  Mon Dec 04 08:24:41 2006 -0700
@@ -311,12 +311,8 @@ int tdaio_do_callbacks(struct td_state *
                struct pending_aio *pio;
                
                pio = &prv->pending_aio[(long)io->data];
-               
-               if (ep->res != io->u.c.nbytes) {
-                       /* TODO: handle this case better. */
-                       DPRINTF("AIO did less than I asked it to. \n");
-               }
-               rsp += pio->cb(s, ep->res2, pio->id, pio->private);
+               rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1,
+                              pio->id, pio->private);
 
                prv->iocb_free[prv->iocb_free_count++] = io;
        }
diff -r 6fdbf173142d -r d603aed5ad6d tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/blktap/drivers/block-qcow.c Mon Dec 04 08:24:41 2006 -0700
@@ -1145,13 +1145,6 @@ int tdqcow_do_callbacks(struct td_state 
 
                 pio = &prv->pending_aio[(long)io->data];
 
-                if (ep->res != io->u.c.nbytes) {
-                        /* TODO: handle this case better. */
-                       ptr = (int *)&ep->res;
-                        DPRINTF("AIO did less than I asked it to "
-                               "[%lu,%lu,%d]\n", 
-                               ep->res, io->u.c.nbytes, *ptr);
-                }
                aio_unlock(prv, pio->sector);
                if (pio->id >= 0) {
                        if (prv->crypt_method)
@@ -1162,7 +1155,7 @@ int tdqcow_do_callbacks(struct td_state 
                                                &prv->aes_decrypt_key);
                        prv->nr_reqs[pio->qcow_idx]--;
                        if (prv->nr_reqs[pio->qcow_idx] == 0) 
-                               rsp += pio->cb(s, ep->res2, pio->id, 
+                               rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 
: 1, pio->id, 
                                               pio->private);
                } else if (pio->id == -2) free(pio->buf);
 
diff -r 6fdbf173142d -r d603aed5ad6d tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/blktap/drivers/tapdisk.c    Mon Dec 04 08:24:41 2006 -0700
@@ -424,8 +424,7 @@ int send_responses(struct td_state *s, i
        }
        
        if (res != 0) {
-               DPRINTF("*** request error %d! \n", res);
-               return 0;
+               blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
        }
 
        blkif->pending_list[idx].count--;
diff -r 6fdbf173142d -r d603aed5ad6d tools/check/Makefile
--- a/tools/check/Makefile      Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/check/Makefile      Mon Dec 04 08:24:41 2006 -0700
@@ -1,3 +1,5 @@
+XEN_ROOT = ../..
+include $(XEN_ROOT)/tools/Rules.mk
 
 .PHONY: all
 all: build
@@ -5,7 +7,7 @@ all: build
 # Check this machine is OK for building on.
 .PHONY: build
 build:
-       ./chk build
+       XENFB_TOOLS=$(XENFB_TOOLS) ./chk build
 
 # Check this machine is OK for installing on.
 # DO NOT use this check from 'make install' in the parent
@@ -13,7 +15,7 @@ build:
 # copy rather than actually installing.
 .PHONY: install
 install:
-       ./chk install
+       XENFB_TOOLS=$(XENFB_TOOLS) ./chk install
 
 .PHONY: clean
 clean:
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/setup.c  Mon Dec 04 08:24:41 2006 -0700
@@ -66,7 +66,7 @@ unsigned long memory_size;
 unsigned long memory_size;
 int initialize_real_mode;
 
-extern char stack[], stack_top[];
+extern char stack_top[];
 extern unsigned trap_handlers[];
 
 void
@@ -201,7 +201,7 @@ enter_real_mode(struct regs *regs)
 enter_real_mode(struct regs *regs)
 {
        /* mask off TSS busy bit */
-        gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
+       gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
 
        /* start 8086 emulation of BIOS */
        if (initialize_real_mode) {
@@ -219,8 +219,10 @@ enter_real_mode(struct regs *regs)
                        regs->cs = booting_vector << 8; /* AP entry point */
                        regs->eip = 0;
                }
-               regs->uesp = 0;
-               regs->uss = 0;
+
+               regs->uesp = regs->uss = 0;
+               regs->eax = regs->ecx = regs->edx = regs->ebx = 0;
+               regs->esp = regs->ebp = regs->esi = regs->edi = 0;
 
                /* intercept accesses to the PIC */
                setiomap(PIC_MASTER+PIC_CMD);
@@ -236,14 +238,12 @@ enter_real_mode(struct regs *regs)
 
                /* this should get us into 16-bit mode */
                return;
-       } else {
-               /* go from protected to real mode */
-               regs->eflags |= EFLAGS_VM;
-
-               set_mode(regs, VM86_PROTECTED_TO_REAL);
-
-               emulate(regs);
        }
+
+       /* go from protected to real mode */
+       regs->eflags |= EFLAGS_VM;
+       set_mode(regs, VM86_PROTECTED_TO_REAL);
+       emulate(regs);
 }
 
 /*
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/trap.S
--- a/tools/firmware/vmxassist/trap.S   Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/trap.S   Mon Dec 04 08:24:41 2006 -0700
@@ -100,10 +100,6 @@ trap_handlers:
        .code32
        .align  16
 common_trap:                           /* common trap handler */
-       pushl   %gs
-       pushl   %fs
-       pushl   %ds
-       pushl   %es
        pushal
 
        movl    $(DATA_SELECTOR), %eax  /* make sure these are sane */
@@ -114,17 +110,13 @@ common_trap:                              /* common trap 
handler *
        movl    %esp, %ebp
 
        pushl   %ebp
-       pushl   52(%ebp)
-       pushl   48(%ebp)
+       pushl   36(%ebp)
+       pushl   32(%ebp)
        call    trap                    /* trap(trapno, errno, regs) */
        addl    $12, %esp
 
 trap_return:
        popal
-       popl    %es
-       popl    %ds
-       popl    %fs
-       popl    %gs
        addl    $8, %esp                /* skip trapno, errno */
        iret
        /* NOT REACHED */
@@ -152,10 +144,6 @@ switch_to_real_mode:
        pushl   oldctx+VMX_ASSIST_CTX_EIP
        pushl   $-1                     /* trapno, errno */
        pushl   $-1
-       pushl   %gs
-       pushl   %fs
-       pushl   %ds
-       pushl   %es
        pushal
 
        movl    %esp, %ebp
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/util.c
--- a/tools/firmware/vmxassist/util.c   Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/util.c   Mon Dec 04 08:24:41 2006 -0700
@@ -62,17 +62,15 @@ dump_regs(struct regs *regs)
                regs->eax, regs->ecx, regs->edx, regs->ebx);
        printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",
                regs->esp, regs->ebp, regs->esi, regs->edi);
-       printf("es     %8x ds     %8x fs     %8x gs     %8x\n",
-               regs->es, regs->ds, regs->fs, regs->gs);
        printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);
        printf("eip    %8x cs     %8x eflags %8x\n",
                regs->eip, regs->cs, regs->eflags);
-       printf("uesp   %8x uss    %8x \n",
+       printf("uesp   %8x uss    %8x\n",
                regs->uesp, regs->uss);
        printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",
                regs->ves, regs->vds, regs->vfs, regs->vgs);
 
-       printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n",
+       printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n\n",
                (long)oldctx.cr0, get_cr2(),
                (long)oldctx.cr3, (long)oldctx.cr4);
 }
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/vm86.c   Mon Dec 04 08:24:41 2006 -0700
@@ -376,9 +376,9 @@ segment(unsigned prefix, struct regs *re
        if (prefix & SEG_SS)
                seg = regs->uss;
        if (prefix & SEG_FS)
-               seg = regs->fs;
+               seg = regs->vfs;
        if (prefix & SEG_GS)
-               seg = regs->gs;
+               seg = regs->vgs;
        return seg;
 }
 
@@ -934,6 +934,8 @@ static void
 static void
 protected_mode(struct regs *regs)
 {
+       extern char stack_top[];
+
        regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
 
        oldctx.eip = regs->eip;
@@ -958,12 +960,10 @@ protected_mode(struct regs *regs)
                          &oldctx.gs_limit, &oldctx.gs_arbytes);
 
        /* initialize jump environment to warp back to protected mode */
+       regs->uss = DATA_SELECTOR;
+       regs->uesp = stack_top;
        regs->cs = CODE_SELECTOR;
-       regs->ds = DATA_SELECTOR;
-       regs->es = DATA_SELECTOR;
-       regs->fs = DATA_SELECTOR;
-       regs->gs = DATA_SELECTOR;
-       regs->eip = (unsigned) &switch_to_protected_mode;
+       regs->eip = (unsigned) switch_to_protected_mode;
 
        /* this should get us into 32-bit mode */
 }
@@ -975,10 +975,6 @@ real_mode(struct regs *regs)
 real_mode(struct regs *regs)
 {
        regs->eflags |= EFLAGS_VM | 0x02;
-       regs->ds = DATA_SELECTOR;
-       regs->es = DATA_SELECTOR;
-       regs->fs = DATA_SELECTOR;
-       regs->gs = DATA_SELECTOR;
 
        /*
         * When we transition from protected to real-mode and we
@@ -1070,9 +1066,6 @@ set_mode(struct regs *regs, enum vm86_mo
        case VM86_PROTECTED:
                if (mode == VM86_REAL_TO_PROTECTED) {
                        protected_mode(regs);
-//                     printf("<VM86_PROTECTED>\n");
-                       mode = newmode;
-                       return;
                } else
                        panic("unexpected protected mode transition");
                break;
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/vm86.h
--- a/tools/firmware/vmxassist/vm86.h   Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/vm86.h   Mon Dec 04 08:24:41 2006 -0700
@@ -34,7 +34,6 @@
 
 struct regs {
        unsigned        edi, esi, ebp, esp, ebx, edx, ecx, eax;
-       unsigned        es, ds, fs, gs;
        unsigned        trapno, errno;
        unsigned        eip, cs, eflags, uesp, uss;
        unsigned        ves, vds, vfs, vgs;
@@ -55,7 +54,6 @@ enum vm86_mode {
 
 extern enum vm86_mode prevmode, mode;
 extern struct vmx_assist_context oldctx;
-extern struct vmx_assist_context newctx;
 
 extern void emulate(struct regs *);
 extern void dump_regs(struct regs *);
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/hw/pci.c
--- a/tools/ioemu/hw/pci.c      Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/hw/pci.c      Mon Dec 04 08:24:41 2006 -0700
@@ -221,23 +221,16 @@ uint32_t pci_default_read_config(PCIDevi
                                  uint32_t address, int len)
 {
     uint32_t val;
-
     switch(len) {
+    case 1:
+        val = d->config[address];
+        break;
+    case 2:
+        val = le16_to_cpu(*(uint16_t *)(d->config + address));
+        break;
     default:
     case 4:
-       if (address <= 0xfc) {
-           val = le32_to_cpu(*(uint32_t *)(d->config + address));
-           break;
-       }
-       /* fall through */
-    case 2:
-        if (address <= 0xfe) {
-           val = le16_to_cpu(*(uint16_t *)(d->config + address));
-           break;
-       }
-       /* fall through */
-    case 1:
-        val = d->config[address];
+        val = le32_to_cpu(*(uint32_t *)(d->config + address));
         break;
     }
     return val;
@@ -340,8 +333,7 @@ void pci_default_write_config(PCIDevice 
 
             d->config[addr] = val;
         }
-        if (++addr > 0xff)
-               break;
+        addr++;
         val >>= 8;
     }
 
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/hw/usb-uhci.c
--- a/tools/ioemu/hw/usb-uhci.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/hw/usb-uhci.c Mon Dec 04 08:24:41 2006 -0700
@@ -421,7 +421,7 @@ static int uhci_handle_td(UHCIState *s, 
 static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
 {
     uint8_t pid;
-    uint8_t buf[1280];
+    uint8_t buf[2048];
     int len, max_len, err, ret;
 
     if (td->ctrl & TD_CTRL_IOC) {
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/vl.h  Mon Dec 04 08:24:41 2006 -0700
@@ -650,8 +650,11 @@ typedef struct PCIIORegion {
 #define PCI_MAX_LAT            0x3f    /* 8 bits */
 
 struct PCIDevice {
-    /* PCI config space */
-    uint8_t config[256];
+    /*
+     * PCI config space. The 4 extra bytes are a safety buffer for guest
+     * word/dword writes that can extend past byte 0xff.
+     */
+    uint8_t config[256+4];
 
     /* the following fields are read only */
     PCIBus *bus;
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/vnc.c Mon Dec 04 08:24:41 2006 -0700
@@ -114,6 +114,7 @@ struct VncState
     int visible_h;
 
     int ctl_keys;               /* Ctrl+Alt starts calibration */
+    int shift_keys;             /* Shift / CapsLock keys */
 };
 
 #define DIRTY_PIXEL_BITS 64
@@ -870,9 +871,12 @@ static void do_key_event(VncState *vs, i
     } else if (down) {
        int qemu_keysym = 0;
 
-       if (sym <= 128) /* normal ascii */
+       if (sym <= 128) { /* normal ascii */
+           int shifted = vs->shift_keys == 1 || vs->shift_keys == 2;
            qemu_keysym = sym;
-       else {
+           if (sym >= 'a' && sym <= 'z' && shifted)
+               qemu_keysym -= 'a' - 'A';
+       } else {
            switch (sym) {
            case XK_Up: qemu_keysym = QEMU_KEY_UP; break;
            case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break;
@@ -903,6 +907,10 @@ static void do_key_event(VncState *vs, i
            vs->ctl_keys |= 2;
            break;
 
+       case XK_Shift_L:
+           vs->shift_keys |= 1;
+           break;
+
        default:
            break;
        }
@@ -914,6 +922,14 @@ static void do_key_event(VncState *vs, i
 
        case XK_Alt_L:
            vs->ctl_keys &= ~2;
+           break;
+
+       case XK_Shift_L:
+           vs->shift_keys &= ~1;
+           break;
+
+       case XK_Caps_Lock:
+           vs->shift_keys ^= 2;
            break;
 
        case XK_1 ... XK_9:
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c    Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxc/xc_linux.c    Mon Dec 04 08:24:41 2006 -0700
@@ -250,6 +250,15 @@ int xc_evtchn_notify(int xce_handle, evt
     return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 
+evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
+{
+    struct ioctl_evtchn_bind_unbound_port bind;
+
+    bind.remote_domain = domid;
+
+    return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+}
+
 evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
     evtchn_port_t remote_port)
 {
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxc/xc_solaris.c
--- a/tools/libxc/xc_solaris.c  Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxc/xc_solaris.c  Mon Dec 04 08:24:41 2006 -0700
@@ -165,6 +165,15 @@ int xc_evtchn_notify(int xce_handle, evt
     return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 
+evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
+{
+    struct ioctl_evtchn_bind_unbound_port bind;
+
+    bind.remote_domain = domid;
+
+    return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+}
+
 evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
     evtchn_port_t remote_port)
 {
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxc/xenctrl.h     Mon Dec 04 08:24:41 2006 -0700
@@ -382,6 +382,10 @@ int xc_sched_credit_domain_get(int xc_ha
  * This function allocates an unbound port.  Ports are named endpoints used for
  * interdomain communication.  This function is most useful in opening a
  * well-known port within a domain to receive events on.
+ * 
+ * NOTE: If you are allocating a *local* unbound port, you probably want to
+ * use xc_evtchn_bind_unbound_port(). This function is intended for allocating
+ * ports *only* during domain creation.
  *
  * @parm xc_handle a handle to an open hypervisor interface
  * @parm dom the ID of the local domain (the 'allocatee')
@@ -630,6 +634,12 @@ int xc_evtchn_notify(int xce_handle, evt
 int xc_evtchn_notify(int xce_handle, evtchn_port_t port);
 
 /*
+ * Returns a new event port awaiting interdomain connection from the given
+ * domain ID, or -1 on failure, in which case errno will be set appropriately.
+ */
+evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid);
+
+/*
  * Returns a new event port bound to the remote port for the given domain ID,
  * or -1 on failure, in which case errno will be set appropriately.
  */
@@ -661,15 +671,15 @@ int xc_evtchn_unmask(int xce_handle, evt
 int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
 
 int xc_hvm_set_pci_intx_level(
-    int xce_handle, domid_t dom,
+    int xc_handle, domid_t dom,
     uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
     unsigned int level);
 int xc_hvm_set_isa_irq_level(
-    int xce_handle, domid_t dom,
+    int xc_handle, domid_t dom,
     uint8_t isa_irq,
     unsigned int level);
 
 int xc_hvm_set_pci_link_route(
-    int xce_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
+    int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
 
 #endif
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/Makefile
--- a/tools/libxen/Makefile     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/Makefile     Mon Dec 04 08:24:41 2006 -0700
@@ -48,8 +48,8 @@ libxenapi.a: $(LIBXENAPI_OBJS)
 libxenapi.a: $(LIBXENAPI_OBJS)
        $(AR) rcs libxenapi.a $^
 
-test/test_bindings: test/test_bindings.o src/libxen.so
-       $(CC) $(LDFLAGS) -o $@ $< -L src -lxen
+test/test_bindings: test/test_bindings.o libxenapi.so
+       $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
 
 
 .PHONY: install
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/README
--- a/tools/libxen/README       Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/README       Mon Dec 04 08:24:41 2006 -0700
@@ -44,11 +44,12 @@ test program depends upon libcurl3 also.
 test program depends upon libcurl3 also.  On Debian, you need the packages
 libxml2-dev and libcurl3-dev.
 
-To compile, type make.
+To compile, type make.  To compile the test also, type make
+test/test_bindings, remembering the additional dependency.
 
 To run the test, do
 
-LD_LIBRARY_PATH=src ./test/test_bindings <url> <username> <password>
+LD_LIBRARY_PATH=. ./test/test_bindings <url> <username> <password>
 
 where <url> is the fragment of the server URL that follows the http://, for
 example "localhost:8005/RPC2".
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/include/xen_vm.h
--- a/tools/libxen/include/xen_vm.h     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/include/xen_vm.h     Mon Dec 04 08:24:41 2006 -0700
@@ -21,6 +21,7 @@
 
 #include "xen_boot_type.h"
 #include "xen_common.h"
+#include "xen_console_decl.h"
 #include "xen_cpu_feature.h"
 #include "xen_host_decl.h"
 #include "xen_int_float_map.h"
@@ -96,6 +97,7 @@ typedef struct xen_vm_record
     enum xen_on_normal_exit actions_after_reboot;
     enum xen_on_normal_exit actions_after_suspend;
     enum xen_on_crash_behaviour actions_after_crash;
+    struct xen_console_record_opt_set *consoles;
     struct xen_vif_record_opt_set *vifs;
     struct xen_vbd_record_opt_set *vbds;
     struct xen_vtpm_record_opt_set *vtpms;
@@ -401,6 +403,13 @@ xen_vm_get_actions_after_crash(xen_sessi
 
 
 /**
+ * Get the consoles field of the given VM.
+ */
+extern bool
+xen_vm_get_consoles(xen_session *session, struct xen_console_set **result, 
xen_vm vm);
+
+
+/**
  * Get the VIFs field of the given VM.
  */
 extern bool
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/src/xen_vm.c Mon Dec 04 08:24:41 2006 -0700
@@ -22,6 +22,7 @@
 
 #include "xen_boot_type_internal.h"
 #include "xen_common.h"
+#include "xen_console.h"
 #include "xen_cpu_feature.h"
 #include "xen_cpu_feature_internal.h"
 #include "xen_host.h"
@@ -120,6 +121,9 @@ static const struct_member xen_vm_record
         { .key = "actions_after_crash",
           .type = &xen_on_crash_behaviour_abstract_type_,
           .offset = offsetof(xen_vm_record, actions_after_crash) },
+        { .key = "consoles",
+          .type = &abstract_type_ref_set,
+          .offset = offsetof(xen_vm_record, consoles) },
         { .key = "VIFs",
           .type = &abstract_type_ref_set,
           .offset = offsetof(xen_vm_record, vifs) },
@@ -205,6 +209,7 @@ xen_vm_record_free(xen_vm_record *record
     xen_cpu_feature_set_free(record->vcpus_features_can_use);
     xen_cpu_feature_set_free(record->vcpus_features_force_on);
     xen_cpu_feature_set_free(record->vcpus_features_force_off);
+    xen_console_record_opt_set_free(record->consoles);
     xen_vif_record_opt_set_free(record->vifs);
     xen_vbd_record_opt_set_free(record->vbds);
     xen_vtpm_record_opt_set_free(record->vtpms);
@@ -694,6 +699,23 @@ xen_vm_get_actions_after_crash(xen_sessi
 
 
 bool
+xen_vm_get_consoles(xen_session *session, struct xen_console_set **result, 
xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string_set;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_consoles");
+    return session->ok;
+}
+
+
+bool
 xen_vm_get_vifs(xen_session *session, struct xen_vif_set **result, xen_vm vm)
 {
     abstract_value param_values[] =
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/scripts/xapi.domcfg.py
--- a/tools/python/scripts/xapi.domcfg.py       Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/scripts/xapi.domcfg.py       Mon Dec 04 08:24:41 2006 -0700
@@ -26,7 +26,7 @@ platform_localtime =  False
 platform_localtime =  False
 platform_clock_offset =  False
 platform_enable_audio =  False
-builder =  ''
+builder =  'linux'
 boot_method =  '' # this will remove the kernel/initrd ??
 kernel_kernel =  '/boot/vmlinuz-2.6.16.29-xen'
 kernel_initrd =  '/root/initrd-2.6.16.29-xen.img'
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/scripts/xapi.py
--- a/tools/python/scripts/xapi.py      Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/scripts/xapi.py      Mon Dec 04 08:24:41 2006 -0700
@@ -29,17 +29,20 @@ MB = 1024 * 1024
 MB = 1024 * 1024
 
 HOST_INFO_FORMAT = '%-20s: %-50s'
-VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(vcpus_number)-5s'\
+VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(VCPUs_number)-5s'\
                  ' %(power_state)-10s %(uuid)-36s'
 SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \
                  '%(type)-10s'
 VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\
                   '%(sector_size)-8s'
+VBD_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(VDI)-8s '\
+                  '%(image)-8s'
 
 COMMANDS = {
     'host-info': ('', 'Get Xen Host Info'),
     'host-set-name': ('', 'Set host name'),
     'sr-list':   ('', 'List all SRs'),
+    'vbd-list':  ('', 'List all VBDs'),
     'vbd-create': ('<domname> <pycfg> [opts]',
                    'Create VBD attached to domname'),
     'vdi-create': ('<pycfg> [opts]', 'Create a VDI'),
@@ -165,6 +168,13 @@ def resolve_vm(server, session, vm_name)
     else:
         return vm_uuid[0]
 
+def resolve_vdi(server, session, vdi_name):
+    vdi_uuid = execute(server.VDI.get_by_name_label, session, vdi_name)
+    if not vdi_uuid:
+        return None
+    else:
+        return vdi_uuid[0]
+
 #
 # Actual commands
 #
@@ -216,16 +226,16 @@ def xapi_vm_list(*args):
     if not is_long:
         print VM_LIST_FORMAT % {'name_label':'Name',
                                 'memory_actual':'Mem',
-                                'vcpus_number': 'VCPUs',
+                                'VCPUs_number': 'VCPUs',
                                 'power_state': 'State',
                                 'uuid': 'UUID'}
 
     for uuid in vm_uuids:
         vm_info = execute(server.VM.get_record, session, uuid)
         if is_long:
-            vbds = vm_info['vbds']
-            vifs = vm_info['vifs']
-            vtpms = vm_info['vtpms']
+            vbds = vm_info['VBDs']
+            vifs = vm_info['VIFs']
+            vtpms = vm_info['VTPMs']
             vif_infos = []
             vbd_infos = []
             vtpm_infos = []
@@ -238,9 +248,9 @@ def xapi_vm_list(*args):
             for vtpm in vtpms:
                 vtpm_info = execute(server.VTPM.get_record, session, vtpm)
                 vtpm_infos.append(vtpm_info)
-            vm_info['vbds'] = vbd_infos
-            vm_info['vifs'] = vif_infos
-            vm_info['vtpms'] = vtpm_infos
+            vm_info['VBDs'] = vbd_infos
+            vm_info['VIFs'] = vif_infos
+            vm_info['VTPMs'] = vtpm_infos
             pprint(vm_info)
         else:
             print VM_LIST_FORMAT % _stringify(vm_info)
@@ -276,7 +286,7 @@ def xapi_vm_start(*args):
     server, session = _connect()
     vm_uuid = resolve_vm(server, session, args[0])
     print 'Starting VM %s (%s)' % (args[0], vm_uuid)
-    success = execute(server.VM.start, session, vm_uuid)
+    success = execute(server.VM.start, session, vm_uuid, False)
     print 'Done.'
 
 def xapi_vm_shutdown(*args):
@@ -333,6 +343,22 @@ def xapi_vif_create(*args):
     cfg['VM'] = vm_uuid
     vif_uuid = execute(server.VIF.create, session, cfg)
     print 'Done. (%s)' % vif_uuid
+
+def xapi_vbd_list(*args):
+    server, session = _connect()
+    domname = args[0]
+    
+    dom_uuid = resolve_vm(server, session, domname)
+    vbds = execute(server.VM.get_VBDs, session, dom_uuid)
+    
+    print VBD_LIST_FORMAT % {'name_label': 'VDI Label',
+                             'uuid' : 'UUID',
+                             'VDI': 'VDI',
+                             'image': 'Image'}
+    
+    for vbd in vbds:
+        vbd_struct = execute(server.VBD.get_record, session, vbd)
+        print VBD_LIST_FORMAT % vbd_struct
 
 def xapi_vdi_list(*args):
     server, session = _connect()
@@ -420,8 +446,6 @@ def xapi_vtpm_create(*args):
     print "Has driver type '%s'" % driver
     vtpm_rec = execute(server.VTPM.get_record, session, vtpm_uuid)
     print "Has vtpm record '%s'" % vtpm_rec
-    vm = execute(server.VTPM.get_VM, session, vtpm_uuid)
-    print "Has VM '%s'" % vm
 
 
 #
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Dec 04 08:24:41 2006 -0700
@@ -392,7 +392,7 @@ static PyObject *pyxc_hvm_build(XcObject
         return PyErr_SetFromErrno(xc_error);
 
     /* Set up the HVM info table. */
-    va_map = xc_map_foreign_range(self->xc_handle, dom, PAGE_SIZE,
+    va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
                                   PROT_READ | PROT_WRITE,
                                   HVM_INFO_PFN);
     if ( va_map == NULL )
@@ -407,7 +407,7 @@ static PyObject *pyxc_hvm_build(XcObject
     for ( i = 0, sum = 0; i < va_hvm->length; i++ )
         sum += ((uint8_t *)va_hvm)[i];
     va_hvm->checksum = -sum;
-    munmap(va_map, PAGE_SIZE);
+    munmap(va_map, XC_PAGE_SIZE);
 
     xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
     xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/util/bugtool.py
--- a/tools/python/xen/util/bugtool.py  Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/util/bugtool.py  Mon Dec 04 08:24:41 2006 -0700
@@ -43,8 +43,9 @@ TITLE_RE = re.compile(r'<title>(.*)</tit
 
 FILES_TO_SEND = [ '/var/log/' + x for x in 
                   [ 'syslog', 'messages', 'debug',
-                    'xen/xend.log', 'xen/xend-debug.log', 
'xen/xenstored-trace.log',
-                    'xen/xen-hotplug.log' ] ]
+                    'xen/xend-debug.log', 'xen/xenstored-trace.log',
+                    'xen/xen-hotplug.log', 'xen/xend.log' ] +
+                  [ 'xen/xend.log.%d' % z for z in range(1,6) ] ]
 #FILES_TO_SEND = [  ]
 
 
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py       Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/util/xmlrpclib2.py       Mon Dec 04 08:24:41 2006 -0700
@@ -29,6 +29,8 @@ from SimpleXMLRPCServer import SimpleXML
 from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
 import SocketServer
 import xmlrpclib, socket, os, stat
+
+import mkdir
 
 from xen.web import connection
 from xen.xend.XendLogging import log
@@ -234,14 +236,9 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
     address_family = socket.AF_UNIX
 
     def __init__(self, addr, allowed, logRequests = 1):
-        parent = os.path.dirname(addr)
-        if os.path.exists(parent):
-            os.chown(parent, os.geteuid(), os.getegid())
-            os.chmod(parent, stat.S_IRWXU)
-            if self.allow_reuse_address and os.path.exists(addr):
-                os.unlink(addr)
-        else:
-            os.makedirs(parent, stat.S_IRWXU)
+        mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True)
+        if self.allow_reuse_address and os.path.exists(addr):
+            os.unlink(addr)
 
         TCPXMLRPCServer.__init__(self, addr, allowed,
                                  UnixXMLRPCRequestHandler, logRequests)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/web/unix.py
--- a/tools/python/xen/web/unix.py      Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/web/unix.py      Mon Dec 04 08:24:41 2006 -0700
@@ -22,6 +22,8 @@ import socket
 import socket
 import stat
 
+from xen.util import mkdir
+
 import connection
 
 
@@ -30,13 +32,9 @@ created such that only the current user 
 created such that only the current user may access it."""
 
     parent = os.path.dirname(path)
-    if os.path.exists(parent):
-        os.chown(parent, os.geteuid(), os.getegid())
-        os.chmod(parent, stat.S_IRWXU)
-        if os.path.exists(path):
-            os.unlink(path)
-    else:
-        os.makedirs(parent, stat.S_IRWXU)
+    mkdir.parents(parent, stat.S_IRWXU, True)
+    if os.path.exists(path):
+        os.unlink(path)
 
     sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
     sock.bind(path)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendAPI.py  Mon Dec 04 08:24:41 2006 -0700
@@ -303,8 +303,8 @@ class XendAPI:
         #    all get_by_uuid() methods.
         
         for cls in classes.keys():
-            get_by_uuid = '%s_get_by_uuid' % cls.lower()
-            get_uuid = '%s_get_uuid' % cls.lower()            
+            get_by_uuid = '%s_get_by_uuid' % cls
+            get_uuid = '%s_get_uuid' % cls
             setattr(XendAPI, get_by_uuid,
                     lambda s, sess, obj_ref: xen_api_success(obj_ref))
             setattr(XendAPI, get_uuid,
@@ -327,7 +327,7 @@ class XendAPI:
 
             # wrap validators around readable class attributes
             for attr_name in ro_attrs + rw_attrs + self.Base_attr_ro:
-                getter_name = '%s_get_%s' % (cls.lower(), attr_name)
+                getter_name = '%s_get_%s' % (cls, attr_name)
                 try:
                     getter = getattr(XendAPI, getter_name)
                     for validator in validators:
@@ -340,7 +340,7 @@ class XendAPI:
 
             # wrap validators around writable class attrributes
             for attr_name in rw_attrs + self.Base_attr_rw:
-                setter_name = '%s_set_%s' % (cls.lower(), attr_name)
+                setter_name = '%s_set_%s' % (cls, attr_name)
                 try:
                     setter = getattr(XendAPI, setter_name)
                     for validator in validators:
@@ -353,7 +353,8 @@ class XendAPI:
 
             # wrap validators around methods
             for method_name in methods + self.Base_methods:
-                method_full_name = '%s_%s' % (cls.lower(), method_name)
+                method_full_name = '%s_%s' % (cls, method_name)
+
                 try:
                     method = getattr(XendAPI, method_full_name)
                     for validator in validators:
@@ -366,7 +367,7 @@ class XendAPI:
 
             # wrap validators around class functions
             for func_name in funcs + self.Base_funcs:
-                func_full_name = '%s_%s' % (cls.lower(), func_name)
+                func_full_name = '%s_%s' % (cls, func_name)
                 try:
                     method = getattr(XendAPI, func_full_name)
                     method = session_required(method)
@@ -379,7 +380,7 @@ class XendAPI:
 
     Base_attr_ro = ['uuid']
     Base_attr_rw = []
-    Base_methods = ['destroy', 'to_XML', 'get_record']
+    Base_methods = ['destroy', 'get_record']
     Base_funcs   = ['create', 'get_by_uuid', 'get_all']
 
     # Xen API: Class Session
@@ -411,8 +412,6 @@ class XendAPI:
         record = {'this_host': XendNode.instance().uuid,
                   'this_user': auth_manager().get_user(session)}
         return xen_api_success(record)
-    def session_to_XML(self, session):
-        return xen_api_todo()
 
     # attributes (ro)
     def session_get_this_host(self, session):
@@ -536,8 +535,6 @@ class XendAPI:
                   'features': node.get_host_cpu_features(host_cpu_ref),
                   'utilisation': node.get_host_cpu_load(host_cpu_ref)}
         return xen_api_success(record)
-    def host_cpu_to_XML(self, session, host_cpu_ref):
-        return xen_api_todo()
 
     # class methods
     def host_cpu_get_all(self, session):
@@ -656,304 +653,301 @@ class XendAPI:
         'otherConfig']
         
     # attributes (ro)
-    def vm_get_power_state(self, session, vm_ref):
+    def VM_get_power_state(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.state)
     
-    def vm_get_resident_on(self, session, vm_ref):
+    def VM_get_resident_on(self, session, vm_ref):
         return xen_api_success(XendNode.instance().uuid)
     
-    def vm_get_memory_actual(self, session, vm_ref):
+    def VM_get_memory_actual(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo() # unsupported by xc
     
-    def vm_get_memory_static_max(self, session, vm_ref):
+    def VM_get_memory_static_max(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_memory_static_max())
     
-    def vm_get_memory_static_min(self, session, vm_ref):
+    def VM_get_memory_static_min(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_memory_static_min())
     
-    def vm_get_VCPUs_number(self, session, vm_ref):
+    def VM_get_VCPUs_number(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.getVCpuCount())
     
-    def vm_get_VCPUs_utilisation(self, session, vm_ref):
+    def VM_get_VCPUs_utilisation(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_vcpus_util())
     
-    def vm_get_VCPUs_features_required(self, session, vm_ref):
+    def VM_get_VCPUs_features_required(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo() # unsupported by xc
     
-    def vm_get_VCPUs_can_use(self, session, vm_ref):
+    def VM_get_VCPUs_can_use(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo() # unsupported by xc
     
-    def vm_get_VIFs(self, session, vm_ref):
+    def VM_get_VIFs(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_vifs())
     
-    def vm_get_VBDs(self, session, vm_ref):
+    def VM_get_VBDs(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_vbds())
     
-    def vm_get_VTPMs(self, session, vm_ref):
+    def VM_get_VTPMs(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_vtpms())
     
-    def vm_get_PCI_bus(self, session, vm_ref):
+    def VM_get_PCI_bus(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo() # unsupported by xc
     
-    def vm_get_tools_version(self, session, vm_ref):
+    def VM_get_tools_version(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo()
 
     # attributes (rw)
-    def vm_get_name_label(self, session, vm_ref):
+    def VM_get_name_label(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.getName())
     
-    def vm_get_name_description(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_user_version(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_is_a_template(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_memory_dynamic_max(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-
-    def vm_get_memory_dynamic_min(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()    
-    
-    def vm_get_VCPUs_policy(self, session, vm_ref):
+    def VM_get_name_description(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_user_version(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_is_a_template(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_memory_dynamic_max(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success(dom.get_memory_dynamic_max())
+
+    def VM_get_memory_dynamic_min(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success(dom.get_memory_dynamic_min())        
+    
+    def VM_get_VCPUs_policy(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo() # need to access scheduler
     
-    def vm_get_VCPUs_params(self, session, vm_ref):
+    def VM_get_VCPUs_params(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo() # need access to scheduler
     
-    def vm_get_VCPUs_features_force_on(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_VCPUs_features_force_off(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_actions_after_shutdown(self, session, vm_ref):
+    def VM_get_VCPUs_features_force_on(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_VCPUs_features_force_off(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_actions_after_shutdown(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_on_shutdown())
     
-    def vm_get_actions_after_reboot(self, session, vm_ref):
+    def VM_get_actions_after_reboot(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_on_reboot())
     
-    def vm_get_actions_after_suspend(self, session, vm_ref):
+    def VM_get_actions_after_suspend(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_on_suspend())
     
-    def vm_get_actions_after_crash(self, session, vm_ref):
+    def VM_get_actions_after_crash(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_on_crash())
     
-    def vm_get_bios_boot(self, session, vm_ref):
+    def VM_get_bios_boot(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_bios_boot())
     
-    def vm_get_platform_std_VGA(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_platform_serial(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_platform_localtime(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_platform_clock_offset(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_platform_enable_audio(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_platform_keymap(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_builder(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_get_boot_method(self, session, vm_ref):
+    def VM_get_platform_std_VGA(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_platform_serial(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_platform_localtime(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_platform_clock_offset(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_platform_enable_audio(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_platform_keymap(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_get_builder(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success(dom.get_builder())
+    
+    def VM_get_boot_method(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success(dom.get_boot_method())
+    
+    def VM_get_kernel_kernel(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success('')
     
-    def vm_get_kernel_kernel(self, session, vm_ref):
+    def VM_get_kernel_initrd(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success('')
     
-    def vm_get_kernel_initrd(self, session, vm_ref):
+    def VM_get_kernel_args(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success('')
     
-    def vm_get_kernel_args(self, session, vm_ref):
+    def VM_get_grub_cmdline(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success('')
     
-    def vm_get_grub_cmdline(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
-    def vm_get_otherConfig(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
-    def vm_set_name_label(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_name_description(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_user_version(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_is_a_template(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_memory_dynamic_max(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_memory_dynamic_min(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_VCPUs_policy(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_VCPUs_params(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_VCPUs_features_force_on(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_VCPUs_features_force_off(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_actions_after_shutdown(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_actions_after_reboot(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_actions_after_suspend(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_actions_after_crash(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_bios_boot(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_platform_std_VGA(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_platform_serial(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_platform_localtime(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_platform_clock_offset(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_platform_enable_audio(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_builder(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_boot_method(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_kernel_kernel(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_kernel_initrd(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_kernel_args(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_grub_cmdline(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def vm_set_otherConfig(self, session, vm_ref):
+    def VM_get_otherConfig(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+    
+    def VM_set_name_label(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_name_description(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_user_version(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_is_a_template(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_memory_dynamic_max(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_memory_dynamic_min(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_VCPUs_policy(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_VCPUs_params(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_VCPUs_features_force_on(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_VCPUs_features_force_off(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_actions_after_shutdown(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_actions_after_reboot(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_actions_after_suspend(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_actions_after_crash(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_bios_boot(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_platform_std_VGA(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_platform_serial(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_platform_localtime(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_platform_clock_offset(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_platform_enable_audio(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_builder(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_boot_method(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_kernel_kernel(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_kernel_initrd(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_kernel_args(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_grub_cmdline(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success_void()
+    
+    def VM_set_otherConfig(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success_void()
     
     # class methods
-    def vm_get_all(self, session):
-        refs = [d.get_uuid() for d in XendDomain.instance().list()]
+    def VM_get_all(self, session):
+        refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
         return xen_api_success(refs)
     
-    def vm_get_by_name_label(self, session, label):
+    def VM_get_by_name_label(self, session, label):
         xendom = XendDomain.instance()
         dom = xendom.domain_lookup_nr(label)
         if dom:
             return xen_api_success([dom.get_uuid()])
         return xen_api_error(XEND_ERROR_VM_INVALID)
     
-    def vm_create(self, session, vm_struct):
+    def VM_create(self, session, vm_struct):
         xendom = XendDomain.instance()
         domuuid = xendom.create_domain(vm_struct)
         return xen_api_success(domuuid)
     
     # object methods
-    def vm_to_XML(self, session, vm_ref):
-        return xen_api_todo()
-    
-    def vm_get_record(self, session, vm_ref):
+    def VM_get_record(self, session, vm_ref):
         xendom = XendDomain.instance()
         xeninfo = xendom.get_vm_by_uuid(vm_ref)
         if not xeninfo:
@@ -969,17 +963,17 @@ class XendAPI:
             'resident_on': XendNode.instance().uuid,
             'memory_static_min': xeninfo.get_memory_static_min(),
             'memory_static_max': xeninfo.get_memory_static_max(),
-            'memory_dynamic_min': xeninfo.get_memory_static_min(),
-            'memory_dynamic_max': xeninfo.get_memory_static_max(),
+            'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
+            'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
             'memory_actual': xeninfo.get_memory_static_min(),
-            'vcpus_policy': xeninfo.get_vcpus_policy(),
-            'vcpus_params': xeninfo.get_vcpus_params(),
-            'vcpus_number': xeninfo.getVCpuCount(),
-            'vcpus_utilisation': xeninfo.get_vcpus_util(),
-            'vcpus_features_required': [],
-            'vcpus_features_can_use': [],
-            'vcpus_features_force_on': [],
-            'vcpus_features_force_off': [],
+            'VCPUs_policy': xeninfo.get_vcpus_policy(),
+            'VCPUs_params': xeninfo.get_vcpus_params(),
+            'VCPUs_number': xeninfo.getVCpuCount(),
+            'VCPUs_utilisation': xeninfo.get_vcpus_util(),
+            'VCPUs_features_required': [],
+            'VCPUs_features_can_use': [],
+            'VCPUs_features_force_on': [],
+            'VCPUs_features_force_off': [],
             'actions_after_shutdown': xeninfo.get_on_shutdown(),
             'actions_after_reboot': xeninfo.get_on_reboot(),
             'actions_after_suspend': xeninfo.get_on_suspend(),
@@ -1006,41 +1000,39 @@ class XendAPI:
         }
         return xen_api_success(record)
 
-    def vm_clean_reboot(self, session, vm_ref):
+    def VM_clean_reboot(self, session, vm_ref):
         xendom = XendDomain.instance()
         xeninfo = xendom.get_vm_by_uuid(vm_ref)
         xeninfo.shutdown("reboot")
         return xen_api_success_void()
-    def vm_clean_shutdown(self, session, vm_ref):
+    def VM_clean_shutdown(self, session, vm_ref):
         xendom = XendDomain.instance()
         xeninfo = xendom.get_vm_by_uuid(vm_ref)
         xeninfo.shutdown("poweroff")
         return xen_api_success_void()
-    def vm_clone(self, session, vm_ref):
+    def VM_clone(self, session, vm_ref):
         return xen_api_error(XEND_ERROR_UNSUPPORTED)
-    def vm_destroy(self, session, vm_ref):
+    def VM_destroy(self, session, vm_ref):
         return do_vm_func("domain_delete", vm_ref)
-    def vm_hard_reboot(self, session, vm_ref):
+    def VM_hard_reboot(self, session, vm_ref):
         return xen_api_error(XEND_ERROR_UNSUPPORTED)    
-    def vm_hard_shutdown(self, session, vm_ref):
+    def VM_hard_shutdown(self, session, vm_ref):
         return do_vm_func("domain_destroy", vm_ref)    
-    def vm_pause(self, session, vm_ref):
+    def VM_pause(self, session, vm_ref):
         return do_vm_func("domain_pause", vm_ref)
-    def vm_resume(self, session, vm_ref, start_paused):
+    def VM_resume(self, session, vm_ref, start_paused):
         return do_vm_func("domain_resume", vm_ref, start_paused = 
start_paused)    
-    def vm_start(self, session, vm_ref, start_paused):
+    def VM_start(self, session, vm_ref, start_paused):
         return do_vm_func("domain_start", vm_ref, start_paused = start_paused)
-    def vm_suspend(self, session, vm_ref):
+    def VM_suspend(self, session, vm_ref):
         return do_vm_func("domain_suspend", vm_ref)    
-    def vm_unpause(self, session, vm_ref):
+    def VM_unpause(self, session, vm_ref):
         return do_vm_func("domain_unpause", vm_ref)
-
-    # Xen API: Class VDI
-    # ----------------------------------------------------------------
-    # TODO: NOT IMPLEMENTED.
 
     # Xen API: Class VBD
     # ----------------------------------------------------------------
+    # Note: accepts a non-API standard 'image' attribute to emulate
+    #       regular xm created VBDs
 
     VBD_attr_ro = ['image',
                    'IO_bandwidth_incoming_kbs',
@@ -1053,8 +1045,10 @@ class XendAPI:
 
     VBD_attr_inst = VBD_attr_rw + ['image']
 
+    VBD_methods = ['media_change']
+
     # object methods
-    def vbd_get_record(self, session, vbd_ref):
+    def VBD_get_record(self, session, vbd_ref):
         xendom = XendDomain.instance()
         vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
         if not vm:
@@ -1063,9 +1057,12 @@ class XendAPI:
         if not cfg:
             return xen_api_error(XEND_ERROR_VBD_INVALID)
         return xen_api_success(cfg)
-    
+
+    def VBD_media_change(self, session, vbd_ref, vdi_ref):
+        return xen_api_error(XEND_ERROR_UNSUPPORTED)
+
     # class methods
-    def vbd_create(self, session, vbd_struct):
+    def VBD_create(self, session, vbd_struct):
         xendom = XendDomain.instance()
         if not xendom.is_valid_vm(vbd_struct['VM']):
             return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
@@ -1092,22 +1089,22 @@ class XendAPI:
         return xen_api_success(vbd_ref)
 
     # attributes (rw)
-    def vbd_get_VM(self, session, vbd_ref):
+    def VBD_get_VM(self, session, vbd_ref):
         xendom = XendDomain.instance()
         return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
     
-    def vbd_get_VDI(self, session, vbd_ref):
-        return xen_api_todo()
-    
-    def vbd_get_device(self, session, vbd_ref):
+    def VBD_get_VDI(self, session, vbd_ref):
+        return xen_api_todo()
+    
+    def VBD_get_device(self, session, vbd_ref):
         xendom = XendDomain.instance()
         return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
                                                       'device'))
-    def vbd_get_mode(self, session, vbd_ref):
+    def VBD_get_mode(self, session, vbd_ref):
         xendom = XendDomain.instance()
         return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
                                                       'mode'))
-    def vbd_get_driver(self, session, vbd_ref):
+    def VBD_get_driver(self, session, vbd_ref):
         xendom = XendDomain.instance()
         return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
                                                       'driver'))
@@ -1130,7 +1127,7 @@ class XendAPI:
     VIF_attr_inst = VIF_attr_rw
 
     # object methods
-    def vif_get_record(self, session, vif_ref):
+    def VIF_get_record(self, session, vif_ref):
         xendom = XendDomain.instance()
         vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
         if not vm:
@@ -1147,7 +1144,7 @@ class XendAPI:
         return xen_api_success(cfg)
 
     # class methods
-    def vif_create(self, session, vif_struct):
+    def VIF_create(self, session, vif_struct):
         xendom = XendDomain.instance()
         if xendom.is_valid_vm(vif_struct['VM']):
             dom = xendom.get_vm_by_uuid(vif_struct['VM'])
@@ -1180,99 +1177,96 @@ class XendAPI:
     VDI_methods = ['snapshot']
     VDI_funcs = ['get_by_name_label']
     
-    def vdi_get_VBDs(self, session, vdi_ref):
-        return xen_api_todo()
-    
-    def vdi_get_physical_utilisation(self, session, vdi_ref):
+    def VDI_get_VBDs(self, session, vdi_ref):
+        return xen_api_todo()
+    
+    def VDI_get_physical_utilisation(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.get_physical_utilisation())        
     
-    def vdi_get_sector_size(self, session, vdi_ref):
+    def VDI_get_sector_size(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.sector_size)        
     
-    def vdi_get_type(self, session, vdi_ref):
+    def VDI_get_type(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.type)
     
-    def vdi_get_parent(self, session, vdi_ref):
+    def VDI_get_parent(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.parent)        
     
-    def vdi_get_children(self, session, vdi_ref):
+    def VDI_get_children(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.children)        
     
-    def vdi_get_name_label(self, session, vdi_ref):
+    def VDI_get_name_label(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.name_label)
 
-    def vdi_get_name_description(self, session, vdi_ref):
+    def VDI_get_name_description(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.name_description)
 
-    def vdi_get_SR(self, session, vdi_ref):
+    def VDI_get_SR(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         return xen_api_success(sr.uuid)
 
-    def vdi_get_virtual_size(self, session, vdi_ref):
+    def VDI_get_virtual_size(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.virtual_size)
 
-    def vdi_get_sharable(self, session, vdi_ref):
+    def VDI_get_sharable(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.sharable)
 
-    def vdi_get_read_only(self, session, vdi_ref):
+    def VDI_get_read_only(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         return xen_api_success(image.sharable)        
 
-    def vdi_set_name_label(self, session, vdi_ref, value):
+    def VDI_set_name_label(self, session, vdi_ref, value):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         image.name_label = value
         return xen_api_success_void()
 
-    def vdi_set_name_description(self, session, vdi_ref, value):
+    def VDI_set_name_description(self, session, vdi_ref, value):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         image.name_description = value
         return xen_api_success_void()
 
-    def vdi_set_SR(self, session, vdi_ref, value):
+    def VDI_set_SR(self, session, vdi_ref, value):
         return xen_api_error(XEND_ERROR_UNSUPPORTED)
 
-    def vdi_set_virtual_size(self, session, vdi_ref, value):
+    def VDI_set_virtual_size(self, session, vdi_ref, value):
         return xen_api_error(XEND_ERROR_UNSUPPORTED)
 
-    def vdi_set_sharable(self, session, vdi_ref, value):
-        return xen_api_todo()
-    def vdi_set_read_only(self, session, vdi_ref, value):
+    def VDI_set_sharable(self, session, vdi_ref, value):
+        return xen_api_todo()
+    def VDI_set_read_only(self, session, vdi_ref, value):
         return xen_api_todo()
 
     # Object Methods
-    def vdi_snapshot(self, session, vdi_ref):
-        return xen_api_todo()
-    
-    def vdi_destroy(self, session, vdi_ref):
+    def VDI_snapshot(self, session, vdi_ref):
+        return xen_api_todo()
+    
+    def VDI_destroy(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         sr.destroy_image(vdi_ref)
         return xen_api_success_void()
 
-    def vdi_to_XML(self, session, vdi_ref):
-        return xen_api_todo()
-    
-    def vdi_get_record(self, session, vdi_ref):
+    def VDI_get_record(self, session, vdi_ref):
         sr = XendNode.instance().get_sr()
         image = sr.xen_api_get_by_uuid(vdi_ref)
         if image:
@@ -1295,7 +1289,7 @@ class XendAPI:
         return xen_api_error(XEND_ERROR_VDI_INVALID)
 
     # Class Functions    
-    def vdi_create(self, session, vdi_struct):
+    def VDI_create(self, session, vdi_struct):
         sr = XendNode.instance().get_sr()
         sr_ref = vdi_struct['SR']
         if sr.uuid != sr_ref:
@@ -1304,11 +1298,11 @@ class XendAPI:
         vdi_uuid = sr.create_image(vdi_struct)
         return xen_api_success(vdi_uuid)
 
-    def vdi_get_all(self, session):
+    def VDI_get_all(self, session):
         sr = XendNode.instance().get_sr()
         return xen_api_success(sr.list_images())
     
-    def vdi_get_by_name_label(self, session, name):
+    def VDI_get_by_name_label(self, session, name):
         sr = XendNode.instance().get_sr()
         image_uuid = sr.xen_api_get_by_name_label(name)
         if image_uuid:
@@ -1329,7 +1323,7 @@ class XendAPI:
     VTPM_attr_inst = VTPM_attr_rw
 
     # object methods
-    def vtpm_get_record(self, session, vtpm_ref):
+    def VTPM_get_record(self, session, vtpm_ref):
         xendom = XendDomain.instance()
         vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
         if not vm:
@@ -1346,7 +1340,7 @@ class XendAPI:
         return xen_api_success(cfg)
 
     # Class Functions
-    def vtpm_get_instance(self, session, vtpm_ref):
+    def VTPM_get_instance(self, session, vtpm_ref):
         xendom = XendDomain.instance()
         vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
         if not vm:
@@ -1360,7 +1354,7 @@ class XendAPI:
             instance = -1
         return xen_api_success(instance)
 
-    def vtpm_get_driver(self, session, vtpm_ref):
+    def VTPM_get_driver(self, session, vtpm_ref):
         xendom = XendDomain.instance()
         vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
         if not vm:
@@ -1374,7 +1368,7 @@ class XendAPI:
             driver = "Unknown"
         return xen_api_success(driver)
 
-    def vtpm_get_backend(self, session, vtpm_ref):
+    def VTPM_get_backend(self, session, vtpm_ref):
         xendom = XendDomain.instance()
         vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
         if not vm:
@@ -1388,12 +1382,12 @@ class XendAPI:
             backend = "Domain-0"
         return xen_api_success(backend)
 
-    def vtpm_get_VM(self, session, vtpm_ref):
+    def VTPM_get_VM(self, session, vtpm_ref):
         xendom = XendDomain.instance()
         return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM'))
 
     # class methods
-    def vtpm_create(self, session, vtpm_struct):
+    def VTPM_create(self, session, vtpm_struct):
         xendom = XendDomain.instance()
         if xendom.is_valid_vm(vtpm_struct['VM']):
             dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
@@ -1429,32 +1423,30 @@ class XendAPI:
     SR_funcs = ['get_by_name_label']
 
     # Class Functions
-    def sr_get_all(self, session):
+    def SR_get_all(self, session):
         sr = XendNode.instance().get_sr()
         return xen_api_success([sr.uuid])
 
-    def sr_get_by_name_label(self, session, label):
+    def SR_get_by_name_label(self, session, label):
         sr = XendNode.instance().get_sr()
         if sr.name_label != label:
             return xen_api_error(XEND_ERROR_SR_INVALID)
         return xen_api_success([sr.uuid])
 
-    def sr_create(self, session):
+    def SR_create(self, session):
         return xen_api_error(XEND_ERROR_UNSUPPORTED)
 
-    def sr_get_by_uuid(self, session):
+    def SR_get_by_uuid(self, session):
         return xen_api_success(XendNode.instance().get_sr().uuid)
 
     # Class Methods
-    def sr_clone(self, session, sr_ref):
+    def SR_clone(self, session, sr_ref):
         return xen_api_error(XEND_ERROR_UNSUPPORTED)
-    def sr_destroy(self, session, sr_ref):
+    
+    def SR_destroy(self, session, sr_ref):
         return xen_api_error(XEND_ERROR_UNSUPPORTED)
     
-    def sr_to_XML(self, session, sr_ref):
-        return xen_api_todo()
-    
-    def sr_get_record(self, session, sr_ref):
+    def SR_get_record(self, session, sr_ref):
         sr = XendNode.instance().get_sr()
         return xen_api_success({
             'uuid': sr.uuid,
@@ -1469,44 +1461,44 @@ class XendAPI:
             })
 
     # Attribute acceess
-    def sr_get_VDIs(self, session, sr_ref):
+    def SR_get_VDIs(self, session, sr_ref):
         sr = XendNode.instance().get_sr()
         return xen_api_success(sr.list_images())
 
-    def sr_get_virtual_allocation(self, session, sr_ref):
+    def SR_get_virtual_allocation(self, session, sr_ref):
         sr = XendNode.instance().get_sr()        
         return sr.used_space_bytes()
 
-    def sr_get_physical_utilisation(self, session, sr_ref):
+    def SR_get_physical_utilisation(self, session, sr_ref):
         sr = XendNode.instance().get_sr()        
         return sr.used_space_bytes()
 
-    def sr_get_physical_size(self, session, sr_ref):
+    def SR_get_physical_size(self, session, sr_ref):
         sr = XendNode.instance().get_sr()        
         return sr.total_space_bytes()
     
-    def sr_get_type(self, session, sr_ref):
+    def SR_get_type(self, session, sr_ref):
         sr = XendNode.instance().get_sr()
         return xen_api_success(sr.type)
 
-    def sr_get_location(self, session, sr_ref):
+    def SR_get_location(self, session, sr_ref):
         sr = XendNode.instance().get_sr()
         return xen_api_success(sr.location)
 
-    def sr_get_name_label(self, session, sr_ref):
+    def SR_get_name_label(self, session, sr_ref):
         sr = XendNode.instance().get_sr()
         return xen_api_success(sr.name_label)      
     
-    def sr_get_name_description(self, session, sr_ref):
+    def SR_get_name_description(self, session, sr_ref):
         sr = XendNode.instance().get_sr()
         return xen_api_success(sr.name_description)        
 
-    def sr_set_name_label(self, session, sr_ref, value):
+    def SR_set_name_label(self, session, sr_ref, value):
         sr = XendNode.instance().get_sr()
         sr.name_label = value
         return xen_api_success_void()
     
-    def sr_set_name_description(self, session, sr_ref, value):
+    def SR_set_name_description(self, session, sr_ref, value):
         sr = XendNode.instance().get_sr()
         sr.name_description = value
         return xen_api_success_void()
@@ -1525,24 +1517,24 @@ if __name__ == "__main__":
         methods  = getattr(XendAPI, '%s_methods' % cls, [])
         funcs    = getattr(XendAPI, '%s_funcs' % cls, [])
 
-        ref = '%s_ref' % cls.lower()
+        ref = '%s_ref' % cls
 
         for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
-            getter_name = '%s_get_%s' % (cls.lower(), attr_name.lower())
+            getter_name = '%s_get_%s' % (cls, attr_name)
             output('def %s(self, session, %s):' % (getter_name, ref))
             output('    return xen_api_todo()')
 
         for attr_name in rw_attrs + XendAPI.Base_attr_rw:
-            setter_name = '%s_set_%s' % (cls.lower(), attr_name.lower())
+            setter_name = '%s_set_%s' % (cls, attr_name)
             output('def %s(self, session, %s, value):' % (setter_name, ref))
             output('    return xen_api_todo()')
 
         for method_name in methods + XendAPI.Base_methods:
-            method_full_name = '%s_%s' % (cls.lower(),method_name.lower())
+            method_full_name = '%s_%s' % (cls,method_name)
             output('def %s(self, session, %s):' % (method_full_name, ref))
             output('    return xen_api_todo()')
 
         for func_name in funcs + XendAPI.Base_funcs:
-            func_full_name = '%s_%s' % (cls.lower(), func_name.lower())
+            func_full_name = '%s_%s' % (cls, func_name)
             output('def %s(self, session):' % func_full_name)
             output('    return xen_api_todo()')
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendCheckpoint.py   Mon Dec 04 08:24:41 2006 -0700
@@ -18,8 +18,8 @@ from xen.xend import balloon, sxp
 from xen.xend import balloon, sxp
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendLogging import log
+from xen.xend.XendConfig import XendConfig
 from xen.xend.XendConstants import *
-from xen.xend.XendConfig import XendConfig
 
 SIGNATURE = "LinuxGuestRecord"
 XC_SAVE = "xc_save"
@@ -137,7 +137,7 @@ def restore(xd, fd, dominfo = None, paus
     vmconfig = p.get_val()
 
     if dominfo:
-        dominfo.update(XendConfig(sxp = vmconfig), refresh = False)
+        dominfo.update(XendConfig(sxp_obj = vmconfig), refresh = False)
         dominfo.resume()
     else:
         dominfo = xd.restore_(vmconfig)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendConfig.py       Mon Dec 04 08:24:41 2006 -0700
@@ -31,143 +31,197 @@ XendConfig API
 XendConfig API
 
   XendConfig will try to mirror as closely the Xen API VM Struct
-  providing a backwards compatibility mode for SXP dumping, loading.
+  with extra parameters for those options that are not supported.
 
 """
 
-
-LEGACY_CFG_TO_XENAPI_CFG = {
+def reverse_dict(adict):
+    """Return the reverse mapping of a dictionary."""
+    return dict([(v, k) for k, v in adict.items()])
+
+def bool0(v):
+    return v != '0' and bool(v)
+
+# Mapping from XendConfig configuration keys to the old
+# legacy configuration keys that map directly.
+
+XENAPI_CFG_TO_LEGACY_CFG = {
     'uuid': 'uuid',
-    'vcpus': 'vcpus_number',
-    'maxmem': 'memory_static_max',
-    'memory': 'memory_static_min',
-    'name': 'name_label',
-    'on_poweroff': 'actions_after_shutdown',            
-    'on_reboot': 'actions_after_reboot',
-    'on_crash': 'actions_after_crash',
-    'bootloader': 'boot_method',
-    'kernel_kernel': 'kernel_kernel',
-    'kernel_initrd': 'kernel_initrd',
-    'kernel_args': 'kernel_args',
-    }
-
-XENAPI_CFG_CUSTOM_TRANSLATE = [
-    'vifs',
-    'vbds',
-    ]
-
+    'vcpus_number': 'vcpus',
+    'memory_static_min': 'memory',
+    'memory_static_max': 'maxmem',
+    'name_label': 'name',
+    'actions_after_shutdown': 'on_poweroff',
+    'actions_after_reboot': 'on_reboot',
+    'actions_after_crash': 'on_crash', 
+    'platform_localtime': 'localtime',
+}
+
+LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG)
+
+# Mapping from XendConfig configuration keys to the old
+# legacy configuration keys that are found in the 'image'
+# SXP object.
 XENAPI_HVM_CFG = {
-    'platform_std_vga': 'std-vga',
+    'platform_std_vga': 'stdvga',
     'platform_serial' : 'serial',
     'platform_localtime': 'localtime',
     'platform_enable_audio': 'soundhw',
     'platform_keymap' : 'keymap',
 }    
 
-XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
-    'name_description',
-    'user_version',
-    'is_a_template',
-    'memory_dynamic_min',
-    'memory_dynamic_max',
-    'memory_actual',
-    'vcpus_policy',
-    'vcpus_params',
-    'vcpus_features_required',
-    'vcpus_features_can_use',
-    'vcpus_features_force_on',
-    'vcpus_features_force_off',
-    'actions_after_suspend',
-    'bios_boot',
-    'platform_std_vga',
-    'platform_serial',
-    'platform_localtime',
-    'platform_clock_offset',
-    'platform_enable_audio',
-    'platform_keymap',
-    'builder',
-    'grub_cmdline',
-    'pci_bus',
-    'otherconfig'
-    ]
-
-
-# configuration params that need to be converted to ints
-# since the XMLRPC transport for Xen API does not use
-# 32 bit ints but string representation of 64 bit ints.
-XENAPI_INT_CFG = [
-    'user_version',
-    'vcpus_number',
-    'memory_static_min',
-    'memory_static_max',
-    'memory_dynamic_min',
-    'memory_dynamic_max',
-    'tpm_instance',
-    'tpm_backend',
-]    
-
-##
-## Xend Configuration Parameters
-##
-
-
-# All parameters of VMs that may be configured on-the-fly, or at start-up.
-VM_CONFIG_ENTRIES = [
-    ('name',        str),
-    ('on_crash',    str),
-    ('on_poweroff', str),
-    ('on_reboot',   str),
-    ('on_xend_start', str),
-    ('on_xend_stop', str),        
+# List of XendConfig configuration keys that have no equivalent
+# in the old world.
+
+XENAPI_CFG_TYPES = {
+    'uuid': str,
+    'power_state': str,
+    'name_label': str,
+    'name_description': str,
+    'user_version': str,
+    'is_a_template': bool0,
+    'resident_on': str,
+    'memory_static_min': int,
+    'memory_static_max': int,
+    'memory_dynamic_min': int,
+    'memory_dynamic_max': int,
+    'memory_actual': int,
+    'vcpus_policy': str,
+    'vcpus_params': str,
+    'vcpus_number': int,
+    'vcpus_features_required': list,
+    'vcpus_features_can_use': list,
+    'vcpus_features_force_on': list, 
+    'vcpus_features_force_off': list,
+    'actions_after_shutdown': str,
+    'actions_after_reboot': str,
+    'actions_after_suspend': str,
+    'actions_after_crash': str,
+    'tpm_instance': int,
+    'tpm_backend': int,    
+    'bios_boot': str,
+    'platform_std_vga': bool0,
+    'platform_serial': str,
+    'platform_localtime': bool0,
+    'platform_clock_offset': bool0,
+    'platform_enable_audio': bool0,
+    'platform_keymap': str,
+    'boot_method': str,
+    'builder': str,
+    'kernel_kernel': str,
+    'kernel_initrd': str,
+    'kernel_args': str,
+    'grub_cmdline': str,
+    'pci_bus': str,
+    'tools_version': dict,
+    'otherconfig': dict,
+}
+
+# List of legacy configuration keys that have no equivalent in the
+# Xen API, but are still stored in XendConfig.
+
+LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
+    # roundtripped (dynamic, unmodified)
+    'shadow_memory',
+    'security',
+    'vcpu_avail',
+    'cpu_weight',
+    'cpu_cap',
+    'bootloader',
+    'bootloader_args',
+    'features',
+    # read/write
+    'on_xend_start',
+    'on_xend_stop',
+    # read-only
+    'domid',
+    'start_time',
+    'cpu_time',
+    'online_vcpus',
+    # write-once
+    'cpu',
+    'cpus',
 ]
 
-# All entries written to the store.  This is VM_CONFIG_ENTRIES, plus those
-# entries written to the store that cannot be reconfigured on-the-fly.
-VM_STORE_ENTRIES = [
-    ('uuid',       str),
-    ('vcpus',      int),
-    ('vcpu_avail', int),
-    ('memory',     int),
-    ('maxmem',     int),
-    ('start_time', float),
+LEGACY_CFG_TYPES = {
+    'uuid':          str,
+    'name':          str,
+    'vcpus':         int,
+    'vcpu_avail':    int,
+    'memory':        int,
+    'shadow_memory': int,
+    'maxmem':        int,
+    'start_time':    float,
+    'cpu_cap':         int,
+    'cpu_weight':      int,
+    'cpu_time':      float,
+    'bootloader':      str,
+    'bootloader_args': str,
+    'features':        str,
+    'localtime':       int,
+    'name':        str,
+    'on_poweroff': str,
+    'on_reboot':   str,
+    'on_crash':    str,
+    'on_xend_stop': str,
+    'on_xend_start': str,
+    'online_vcpus': int,
+}
+
+# Values that should be stored in xenstore's /vm/<uuid> that is used
+# by Xend. Used in XendDomainInfo to restore running VM state from
+# xenstore.
+LEGACY_XENSTORE_VM_PARAMS = [
+    'uuid',
+    'name',
+    'vcpus',
+    'vcpu_avail',
+    'memory',
+    'shadow_memory',
+    'maxmem',
+    'start_time',
+    'name',
+    'on_poweroff',
+    'on_crash',
+    'on_reboot',
+    'on_xend_start',
+    'on_xend_stop',
 ]
 
-VM_STORED_ENTRIES = VM_CONFIG_ENTRIES + VM_STORE_ENTRIES
-
-# Configuration entries that we expect to round-trip -- be read from the
-# config file or xc, written to save-files (i.e. through sxpr), and reused as
-# config on restart or restore, all without munging.  Some configuration
-# entries are munged for backwards compatibility reasons, or because they
-# don't come out of xc in the same form as they are specified in the config
-# file, so those are handled separately.
-
-ROUNDTRIPPING_CONFIG_ENTRIES = [
-    ('uuid',       str),
-    ('vcpus',      int),
-    ('vcpu_avail', int),
-    ('cpu_cap',    int),
-    ('cpu_weight', int),
-    ('memory',     int),
-    ('shadow_memory', int),
-    ('maxmem',     int),
-    ('bootloader', str),
-    ('bootloader_args', str),
-    ('features', str),
-    ('localtime', int),
+LEGACY_IMAGE_CFG = [
+    ('root', str),
+    ('ip', str),
+    ('nographic', int),
+    ('vnc', int),
+    ('sdl', int),
+    ('vncdisplay', int),
+    ('vncunused', int),
+    ('vncpasswd', str),    
 ]
-ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_ENTRIES
-
-## Static Configuration
-
-STATIC_CONFIG_ENTRIES = [
-    ('cpu',      int),
-    ('cpus',     str),
-    ('image',    list),
-    ('security', list), # TODO: what if null?
+
+LEGACY_IMAGE_HVM_CFG = [
+    ('device_model', str),
+    ('display', str),
+    ('xauthority', str),
+    ('vncconsole', int),
+    ('pae', int),
+    ('apic', int),
 ]
 
-DEPRECATED_ENTRIES = [
-    ('restart', str),
+LEGACY_IMAGE_HVM_DEVICES_CFG = [
+    ('acpi', int),    
+    ('boot', str),
+    ('fda', str),
+    ('fdb', str),
+    ('isa', str),
+    ('keymap', str),    
+    ('localtime', str),    
+    ('serial', str),
+    ('stdvga', int),
+    ('soundhw', str),
+    ('usb', str),
+    ('usbdevice', str),    
+    ('vcpus', int),
 ]
 
 ##
@@ -178,245 +232,172 @@ CONFIG_OLD_DOM_STATES = ('running', 'blo
 CONFIG_OLD_DOM_STATES = ('running', 'blocked', 'paused', 'shutdown',
                          'crashed', 'dying')
 
-##
-## Defaults
-##
-
-def DEFAULT_VCPUS(info):
-    if 'max_vcpu_id' in info: return int(info['max_vcpu_id']) + 1
-    else: return 1
-
-DEFAULT_CONFIGURATION = (
-    ('uuid',         lambda info: uuid.createString()),
-    ('name',         lambda info: 'Domain-' + info['uuid']),
-
-    ('on_poweroff',  lambda info: 'destroy'),
-    ('on_reboot',    lambda info: 'restart'),
-    ('on_crash',     lambda info: 'restart'),
-    ('features',     lambda info: ''),
-
-    
-    ('memory',       lambda info: 0),
-    ('shadow_memory',lambda info: 0),
-    ('maxmem',       lambda info: 0),
-    ('bootloader',   lambda info: None),
-    ('bootloader_args', lambda info: None),            
-    ('backend',      lambda info: []),
-    ('device',       lambda info: {}),
-    ('image',        lambda info: None),
-    ('security',     lambda info: []),
-    ('on_xend_start', lambda info: 'ignore'),    
-    ('on_xend_stop', lambda info: 'ignore'),
-
-    ('cpus',         lambda info: []),
-    ('cpu_cap',      lambda info: 0),
-    ('cpu_weight',   lambda info: 256),
-    ('vcpus',        lambda info: DEFAULT_VCPUS(info)),
-    ('online_vcpus', lambda info: info['vcpus']),
-    ('max_vcpu_id',  lambda info: info['vcpus']-1),
-    ('vcpu_avail',   lambda info: (1<<info['vcpus'])-1),
-
-    # New for Xen API
-    ('kernel_kernel', lambda info: ''),
-    ('kernel_initrd', lambda info: ''),
-    ('kernel_args',   lambda info: ''),
-    
-)
-    
 class XendConfigError(VmError):
     def __str__(self):
         return 'Invalid Configuration: %s' % str(self.value)
 
 ##
-## XendConfig SXP Config Compat
-##
-
-class XendSXPConfig:
-    def get_domid(self):
-        pass
-    def get_handle(self):
-        return self['uuid']
-        
-
-##
 ## XendConfig Class (an extended dictionary)
 ##
 
 class XendConfig(dict):
-    """ Generic Configuration Parser accepting SXP, Python or XML.
-    This is a dictionary-like object that is populated.
-
-    @ivar legacy: dictionary holding legacy xen domain info
-    @ivar xenapi: dictionary holding xen api config info
+    """ The new Xend VM Configuration.
+
+    Stores the configuration in xenapi compatible format but retains
+    import and export functions for SXP.
     """
-
-    def __init__(self, filename = None, fd = None,
-                 sxp = None, xml = None, pycfg = None, xenapi_vm = None,
-                 cfg = {}):
-        """Constructor. Provide either the filename, fd or sxp.
-
-        @keyword filename: filename of an SXP file
-        @keyword fd: file descriptor of an SXP file
-        @keyword sxp: a list of list of a parsed SXP
-        @keyword xml: an XML tree object
-        @keyword xenapi_vm: a struct passed from an XMLRPC call (Xen API)
-        @keyword cfg: a dictionary of configuration (eg. from xc)
-        """
-        format = 'unknown'
-
-        self.xenapi = {}
-
-        if filename and not fd:
-            fd = open(filename, 'r')
-
-        if fd:
-            format = self._detect_format(fd)
-        
-        if fd:
-            if format == 'sxp':
-                sxp = self._read_sxp(fd)
-            elif format == 'python' and filename != None:
-                pycfg = self._read_python(filename)
-            elif format == 'python' and filename == None:
-                raise XendConfigError("Python files must be passed as a "
-                                      "filename rather than file descriptor.")
-            elif format == 'xml':
-                xml = self._read_xml(fd)
-            else:
-                raise XendConfigError("Unable to determine format of file")
-                
-        if sxp:
-            cfg = self._populate_from_sxp(sxp)
-        if xml:
-            cfg = self._populate_from_xml(xml)
-        if pycfg:
-            cfg = self._populate_from_python_config(pycfg)
-        if xenapi_vm:
-            cfg = self._populate_from_xenapi_vm(xenapi_vm)
+    def __init__(self, filename = None, sxp_obj = None,
+                 xapi = None, dominfo = None):
+        
+        dict.__init__(self)
+        self.update(self._defaults())
+
+        if filename:
+            try:
+                sxp_obj = sxp.parse(open(filename,'r'))
+                sxp_obj = sxp_obj[0]
+            except IOError, e:
+                raise XendConfigError("Unable to read file: %s" % filename)
+        
+        if sxp_obj:
+            self._sxp_to_xapi(sxp_obj)
+            self._sxp_to_xapi_unsupported(sxp_obj)
+        elif xapi:
+            self.update_with_xenapi_config(xapi)
+            self._add_xapi_unsupported()
+        elif dominfo:
+            # output from xc.domain_getinfo
+            self._dominfo_to_xapi(dominfo)
+
+        log.debug('XendConfig.init: %s' % self)
+
+        # validators go here
+        self.validate()
+
+    """ In time, we should enable this type checking addition. It is great
+        also for tracking bugs and unintended writes to XendDomainInfo.info
+    def __setitem__(self, key, value):
+        type_conv = XENAPI_CFG_TYPES.get(key)
+        if callable(type_conv):
+            try:
+                dict.__setitem__(self, key, type_conv(value))
+            except (ValueError, TypeError):
+                raise XendConfigError("Wrong type for configuration value " +
+                                      "%s. Expected %s" %
+                                      (key, type_conv.__name__))
+        else:
+            dict.__setitem__(self, key, value)
+    """
+
+    def _defaults(self):
+        defaults = {
+            'uuid': uuid.createString(),
+            'name_label': 'Domain-Unnamed',
+            'actions_after_shutdown': 'destroy',
+            'actions_after_reboot': 'restart',
+            'actions_after_crash': 'restart',
+            'actions_after_suspend': '',
+            'features': '',
+            'builder': 'linux',
+            'memory_static_min': 0,
+            'memory_dynamic_min': 0,
+            'shadow_memory': 0,
+            'memory_static_max': 0,
+            'memory_dynamic_max': 0,
+            'memory_actual': 0,
+            'boot_method': None,
+            'bootloader': None,
+            'bootloader_args': None,
+            'devices': {},
+            'image': {},
+            'security': None,
+            'on_xend_start': 'ignore',
+            'on_xend_stop': 'ignore',
+            'cpus': [],
+            'cpu_weight': 256,
+            'cpu_cap': 0,
+            'vcpus_number': 1,
+            'online_vcpus': 1,
+            'max_vcpu_id': 0,
+            'vcpu_avail': 1,
+            'vif_refs': [],
+            'vbd_refs': [],
+            'vtpm_refs': [],
+        }
+        
+        defaults['name_label'] = 'Domain-' + defaults['uuid']
+        return defaults
+
+    def _memory_sanity_check(self):
+        if self['memory_static_min'] == 0:
+            self['memory_static_min'] = self['memory_dynamic_min']
+
+        # If the static max is not set, let's set it to dynamic max.
+        # If the static max is smaller than static min, then fix it!
+        self['memory_static_max'] = max(self['memory_static_max'],
+                                        self['memory_dynamic_max'],
+                                        self['memory_static_min'])
+
+        for mem_type in ('memory_static_min', 'memory_static_max'):
+            if self[mem_type] <= 0:
+                raise XendConfigError('Memory value too low for %s: %d' %
+                                      (mem_type, self[mem_type]))
+
+    def _actions_sanity_check(self):
+        for event in ['shutdown', 'reboot', 'crash']:
+            if self['actions_after_' + event] not in CONFIG_RESTART_MODES:
+                raise XendConfigError('Invalid event handling mode: ' +
+                                      event)
+
+    def _builder_sanity_check(self):
+        if self['builder'] not in ('hvm', 'linux'):
+            raise XendConfigError('Invalid builder configuration')
+
+    def validate(self):
+        self._memory_sanity_check()
+        self._actions_sanity_check()
+        self._builder_sanity_check()
+
+    def _dominfo_to_xapi(self, dominfo):
+        self['domid'] = dominfo['domid']
+        self['online_vcpus'] = dominfo['online_vcpus']
+        self['max_vcpu_id'] = dominfo['max_vcpu_id']
+        self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
+        self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
+        self['cpu_time'] = dominfo['cpu_time']/1e9
+        # TODO: i don't know what the security stuff expects here
+        if dominfo.get('ssidref'):
+            self['security'] = [['ssidref', dominfo['ssidref']]]
+        self['shutdown_reason'] = dominfo['shutdown_reason']
+
+        # parse state into Xen API states
+        self['running'] = dominfo['running']
+        self['crashed'] = dominfo['crashed']
+        self['dying'] = dominfo['dying']
+        self['shutdown'] = dominfo['shutdown']
+        self['paused'] = dominfo['paused']
+        self['blocked'] = dominfo['blocked']
+
+        if 'name' in dominfo:
+            self['name_label'] = dominfo['name']
+
+        if 'handle' in dominfo:
+            self['uuid'] = uuid.toString(dominfo['handle'])
             
-        if cfg:
-            self.update(cfg)
-            
-        if xenapi_vm:
-            self.xenapi.update(xenapi_vm)
-
-        log.debug('XendConfig: %s' % str(self))
-        self.validate()
-
-    #
-    # Xen API Attribute Access
-    #
-
-    def __getattr__(self, name):
-        try:
-            return dict.__getattr__(self, name)
-        except AttributeError:
-            try:
-                return  self.__dict__['xenapi'][name]
-            except KeyError:
-                raise AttributeError("XendConfig Xen API has no attribute "
-                                     "'%s'" % name)
-            
-
-    def __setattr__(self, name, value):
-        try:
-            return dict.__setattr__(self, name, value)
-        except AttributeError:
-            self.xenapi[name] = value
-            #self.set_legacy_api_with_xen_api_value(name, value)
-
-    def __delattr__(self, name):
-        try:
-            dict.__delattr__(self, name)
-        except AttributeError:
-            del self.xenapi[name]
-        #self.del_legacy_api_with_xen_api_key(name)
-
-
-    """
-    #
-    # Legacy API Attribute Access
-    #
-
-    def __getitem__(self, key):
-        try:
-            return self.legacy[key]
-        except KeyError:
-            raise AttributeError, "XendConfig Legacy has no attribute '%s'"\
-                  % key
-
-    def __setitem__(self, key, value):
-        self.legacy[key] = value
-        self.set_xen_api_with_legacy_api_value(key, value)
-
-    def __delitem__(self, key):
-        del self.legacy[key]
-        self.del_xen_api_with_legacy_api_key(key)
-    """
-    
-
-    def _detect_format(self, fd):
-        """Detect the format of the configuration passed.
-
-        @param fd: file descriptor of contents to detect
-        @rtype: string, 'sxp', 'xml', 'python' or 'unknown'
-        """
-        format = 'unknown'
-        
-        fd.seek(0)
-        for line in fd:
-            stripped = line.strip()
-            if stripped:
-                if re.search(r'^\(', stripped): 
-                    format = 'sxp'
-                elif re.search(r'^\<?xml', stripped):
-                    format = 'xml'
-                else:
-                    format = 'python'
-                break
-
-        fd.seek(0)
-        return format
-
-    def _read_sxp(self, fd):
-        """ Read and parse SXP (from SXP to list of lists)
-
-        @rtype: list of lists.
-        """
-        try:
-            parsed = sxp.parse(fd)[0]
-            return parsed
-        except:
-            raise
-            return None
-
-    def _read_xml(self, fd):
-        """TODO: Read and parse XML (from XML to dict)
-
-        @rtype: dict
-        """
-        raise NotImplementedError
-
-    def _read_python(self, filename):
-        """Read and parse python module that represents the config.
-
-        @rtype: dict
-        """
-        cfg_globals = {}
-        execfile(filename, cfg_globals, {})
-        return cfg_globals
-
-    def _populate_from_sxp(self, parsed):
+    def _parse_sxp(self, sxp_cfg):
         """ Populate this XendConfig using the parsed SXP.
 
+        @param sxp_cfg: Parsed SXP Configuration
+        @type sxp_cfg: list of lists
         @rtype: dictionary
+        @return: A dictionary containing the parsed options of the SXP.
         """
         cfg = {}
 
         # First step is to convert deprecated options to
         # current equivalents.
         
-        restart = sxp.child_value(parsed, 'restart')
+        restart = sxp.child_value(sxp_cfg, 'restart')
         if restart:
             if restart == 'onreboot':
                 cfg['on_poweroff'] = 'destroy'
@@ -433,23 +414,19 @@ class XendConfig(dict):
                          'restart = \'%s\'', restart)
 
         # Only extract options we know about.
-        all_params = VM_CONFIG_ENTRIES + ROUNDTRIPPING_CONFIG_ENTRIES + \
-                     STATIC_CONFIG_ENTRIES
-                     
-        for key, typeconv in all_params:
-            val = sxp.child_value(parsed, key)
-            if val:
+        extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG
+        extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values()
+        
+        for key in extract_keys:
+            val = sxp.child_value(sxp_cfg, key)
+            if val != None:
                 try:
-                    cfg[key] = typeconv(val)
-                except ValueError:
-                    pass
-
-        # Manually extract other complex configuration
-        # options.
-
-        cfg['backend'] = []
-        for c in sxp.children(parsed, 'backend'):
-            cfg['backend'].append(sxp.name(sxp.child0(c)))
+                    cfg[key] = LEGACY_CFG_TYPES[key](val)
+                except KeyError:
+                    cfg[key] = val
+                except (TypeError, ValueError), e:
+                    log.warn("Unable to parse key %s: %s: %s" %
+                             (key, str(val), e))
 
         # Parsing the device SXP's. In most cases, the SXP looks
         # like this:
@@ -472,65 +449,52 @@ class XendConfig(dict):
         # Hence we deal with pci device configurations outside of
         # the regular device parsing.
         
-        cfg['device'] = {}
-        for dev in sxp.children(parsed, 'device'):
+        cfg['devices'] = {}
+        for dev in sxp.children(sxp_cfg, 'device'):
             config = sxp.child0(dev)
             dev_type = sxp.name(config)
             dev_info = {}
             
             if dev_type == 'pci':
-                continue 
-            
-            for opt, val in config[1:]:
-                dev_info[opt] = val
-            log.debug("XendConfig: reading device: %s" % dev_info)
-            # create uuid if it doesn't
-            dev_uuid = dev_info.get('uuid', uuid.createString())
-            dev_info['uuid'] = dev_uuid
-            cfg['device'][dev_uuid] = (dev_type, dev_info)
-
-        # deal with PCI device configurations if they exist
-        for dev in sxp.children(parsed, 'device'):
-            config = sxp.child0(dev)
-            dev_type = sxp.name(config)
-
-            if dev_type != 'pci':
-                continue
-            
-            dev_attr = sxp.child_value(config, 'dev')
-            if isinstance(dev_attr, (types.ListType, types.TupleType)):
+                pci_devs_uuid = sxp.child_value(config, 'uuid',
+                                                uuid.createString())
+                pci_devs = []
                 for pci_dev in sxp.children(config, 'dev'):
-                    dev_info = {}
+                    pci_dev_info = {}
                     for opt, val in pci_dev[1:]:
-                        dev_info[opt] = val
-                    log.debug("XendConfig: reading device: %s" % dev_info)
-                    dev_uuid = dev_info.get('uuid', uuid.createString())
-                    dev_info['uuid'] = dev_uuid
-                    cfg['device'][dev_uuid] = (dev_type, dev_info)
-                    
-            else: # Xen 2.0 PCI device configuration
+                        pci_dev_info[opt] = val
+                    pci_devs.append(pci_dev_info)
+                
+                cfg['devices'][pci_devs_uuid] = (dev_type,
+                                                 {'devs': pci_devs,
+                                                  'uuid': pci_devs_uuid})
+                
+                log.debug("XendConfig: reading device: %s" % pci_devs)
+            else:
                 for opt, val in config[1:]:
                     dev_info[opt] = val
                 log.debug("XendConfig: reading device: %s" % dev_info)
                 # create uuid if it doesn't
                 dev_uuid = dev_info.get('uuid', uuid.createString())
                 dev_info['uuid'] = dev_uuid
-                cfg['device'][dev_uuid] = (dev_type, dev_info)
+                cfg['devices'][dev_uuid] = (dev_type, dev_info)
+
 
         # Extract missing data from configuration entries
-        if 'image' in cfg:
-            image_vcpus = sxp.child_value(cfg['image'], 'vcpus')
-            if image_vcpus is not None:
+        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
+        if image_sxp:
+            image_vcpus = sxp.child_value(image_sxp, 'vcpus')
+            if image_vcpus != None:
                 try:
-                    if 'vcpus' not in cfg:
-                        cfg['vcpus'] = int(image_vcpus)
-                    elif cfg['vcpus'] != int(image_vcpus):
-                        cfg['vcpus'] = int(image_vcpus)
+                    if 'vcpus_number' not in cfg:
+                        cfg['vcpus_number'] = int(image_vcpus)
+                    elif cfg['vcpus_number'] != int(image_vcpus):
+                        cfg['vcpus_number'] = int(image_vcpus)
                         log.warn('Overriding vcpus from %d to %d using image'
-                                 'vcpus value.', cfg['vcpus'])
+                                 'vcpus value.', cfg['vcpus_number'])
                 except ValueError, e:
                     raise XendConfigError('integer expeceted: %s: %s' %
-                                        str(cfg['image']), e)
+                                          image_sxp, e)
 
         # Deprecated cpu configuration
         if 'cpu' in cfg:
@@ -564,101 +528,188 @@ class XendConfig(dict):
         except ValueError, e:
             raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
 
-        # Parse image SXP outside of image.py
-        # - used to be only done in image.py
-        if 'image' in cfg:
-            cfg['kernel_kernel'] = sxp.child_value(cfg['image'], 'kernel','')
-            cfg['kernel_initrd'] = sxp.child_value(cfg['image'], 'ramdisk','')
-            kernel_args = sxp.child_value(cfg['image'], 'args', '')
-
-            # attempt to extract extra arguments from SXP config
-            arg_ip = sxp.child_value(cfg['image'], 'ip')
-            if arg_ip: kernel_args += ' ip=%s' % arg_ip
-            arg_root = sxp.child_value(cfg['image'], 'root')
-            if arg_root: kernel_args += ' root=%s' % arg_root
-            
-            cfg['kernel_args'] = kernel_args
+        if 'security' in cfg and isinstance(cfg['security'], str):
+            cfg['security'] = sxp.from_string(cfg['security'])
 
         # TODO: get states
-        old_state = sxp.child_value(parsed, 'state')
+        old_state = sxp.child_value(sxp_cfg, 'state')
         if old_state:
             for i in range(len(CONFIG_OLD_DOM_STATES)):
                 cfg[CONFIG_OLD_DOM_STATES[i]] = int(old_state[i] != '-')
 
-        # Xen API extra cfgs
-        # ------------------
-        cfg['vif_refs'] = []
-        cfg['vbd_refs'] = []
-        cfg['vtpm_refs'] = []
-        for dev_uuid, (dev_type, dev_info) in cfg['device'].items():
-            if dev_type == 'vif':
-                cfg['vif_refs'].append(dev_uuid)
-            elif dev_type in ('vbd','tap'):
-                cfg['vbd_refs'].append(dev_uuid)
-            elif dev_type == 'vtpm':
-                cfg['vtpm_refs'].append(dev_uuid)
-                
         return cfg
-
-
-    def _populate_from_xenapi_vm(self, xenapi_vm):
-        cfg = {}
-
-        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
+    
+
+    def _sxp_to_xapi(self, sxp_cfg):
+        """Read in an SXP Configuration object and
+        populate at much of the Xen API with valid values.
+        """
+        cfg = self._parse_sxp(sxp_cfg)
+
+        # Convert parameters that can be directly mapped from
+        # the Legacy Config to Xen API Config
+        
+        for apikey, cfgkey in XENAPI_CFG_TO_LEGACY_CFG.items():
             try:
-                if apikey in XENAPI_INT_CFG:
-                    cfg[cfgkey] = int(xenapi_vm[apikey])
+                type_conv = XENAPI_CFG_TYPES.get(apikey)
+                if callable(type_conv):
+                    self[apikey] = type_conv(cfg[cfgkey])
                 else:
-                    cfg[cfgkey] = xenapi_vm[apikey]                    
+                    log.warn("Unconverted key: " + apikey)
+                    self[apikey] = cfg[cfgkey]
             except KeyError:
                 pass
 
-        # Reconstruct image SXP 
-        # TODO: get rid of SXP altogether from here
-        sxp_image = ['linux']
-        if xenapi_vm['kernel_kernel']:
-            sxp_image.append(['kernel', xenapi_vm['kernel_kernel']])
-        if xenapi_vm['kernel_initrd']:
-            sxp_image.append(['ramdisk', xenapi_vm['kernel_initrd']])
-        if xenapi_vm['kernel_args']:
-            sxp_image.append(['args', xenapi_vm['kernel_args']])
-
-        cfg['image'] = prettyprintstring(sxp_image)
-
-        # make sure device structures are there.
-        if 'device' not in cfg:
-            cfg['device'] = {}
-        if 'vif_refs' not in cfg:
-            cfg['vif_refs'] = []
-        if 'vbd_refs' not in cfg:
-            cfg['vbd_refs'] = []
-        if 'vtpm_refs' not in cfg:
-            cfg['vtpm_refs'] = []
-
-        return cfg
-
-
-    def _sync_xen_api_from_legacy_api(self):
-        """ Sync all the attributes that is supported by the Xen API
-        from the legacy API configuration.
+        # Convert Legacy "image" config to Xen API kernel_*
+        # configuration
+        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
+        if image_sxp:
+            self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
+            self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
+            kernel_args = sxp.child_value(image_sxp, 'args', '')
+
+            # attempt to extract extra arguments from SXP config
+            arg_ip = sxp.child_value(image_sxp, 'ip')
+            if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
+                kernel_args += ' ip=%s' % arg_ip
+            arg_root = sxp.child_value(image_sxp, 'root')
+            if arg_root and not re.search(r'root=[^ ]+', kernel_args):
+                kernel_args += ' root=%s' % arg_root
+            
+            self['kernel_args'] = kernel_args
+
+        # Convert Legacy HVM parameters to Xen API configuration
+        self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
+        self['platform_serial'] = str(cfg.get('serial', ''))
+        self['platform_localtime'] = bool0(cfg.get('localtime', 0))
+        self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
+
+        # Convert path to bootloader to boot_method
+        if not cfg.get('bootloader'):
+            if self.get('kernel_kernel','').endswith('hvmloader'):
+                self['boot_method'] = 'bios'
+            else:
+                self['boot_method'] = 'kernel_external'
+        else:
+            self['boot_method'] = 'grub'
+
+        # make sure a sane maximum is set
+        if self['memory_static_max'] <= 0:
+            self['memory_static_max'] = self['memory_static_min']
+            
+        self['memory_dynamic_max'] = self['memory_static_max']
+        self['memory_dynamic_min'] = self['memory_static_min']
+
+        # set device references in the configuration
+        self['devices'] = cfg.get('devices', {})
+        
+        self['vif_refs'] = []
+        self['vbd_refs'] = []
+        self['vtpm_refs'] = []
+        for dev_uuid, (dev_type, dev_info) in self['devices'].items():
+            if dev_type == 'vif':
+                self['vif_refs'].append(dev_uuid)
+            elif dev_type in ('vbd','tap'):
+                self['vbd_refs'].append(dev_uuid)
+            elif dev_type in ('vtpm',):
+                self['vtpm_refs'].append(dev_uuid)
+        
+
+    def _sxp_to_xapi_unsupported(self, sxp_cfg):
+        """Read in an SXP configuration object and populate
+        values are that not related directly supported in
+        the Xen API.
         """
-        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():        
-            if cfgkey in self:
-                self.xenapi[apikey] = self[cfgkey]
-
-    def _sync_legacy_api_from_xen_api(self):
-        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
-            if apikey in self.xenapi:
-                self[cfgkey] = self.xenapi[apikey]
-
-
-    def _populate_from_xml(self, parsed_xml):
-        raise NotImplementedError
-
-    def _populate_from_python_config(self, parsed_py):
-        raise NotImplementedError
+
+        # Parse and convert parameters used to configure
+        # the image (as well as HVM images)
+        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
+        if image_sxp:
+            image = {}
+            image['type'] = sxp.name(image_sxp)
+            for arg, conv in LEGACY_IMAGE_CFG:
+                val = sxp.child_value(image_sxp, arg, None)
+                if val != None:
+                    image[arg] = conv(val)
+
+            image_hvm = {}
+            for arg, conv in LEGACY_IMAGE_HVM_CFG:
+                val = sxp.child_value(image_sxp, arg, None)
+                if val != None:
+                    image_hvm[arg] = conv(val)
+                    
+            image_hvm_devices = {}
+            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
+                val = sxp.child_value(image_sxp, arg, None)
+                if val != None:
+                    image_hvm_devices[arg] = conv(val)
+
+            if image_hvm or image_hvm_devices:
+                image['hvm'] = image_hvm
+                image['hvm']['devices'] = image_hvm_devices
+
+            self['image'] = image
+
+            for apikey, imgkey in XENAPI_HVM_CFG.items():
+                val = sxp.child_value(image_sxp, imgkey, None)
+                if val != None:
+                    self[apikey] = val
+
+        # extract backend value
+                    
+        backend = []
+        for c in sxp.children(sxp_cfg, 'backend'):
+            backend.append(sxp.name(sxp.child0(c)))
+        if backend:
+            self['backend'] = backend
+
+        if self['image'].has_key('hvm'):
+            self['builder'] = 'hvm'
+            
+        # Parse and convert other Non Xen API parameters.
+        def _set_cfg_if_exists(sxp_arg):
+            val = sxp.child_value(sxp_cfg, sxp_arg)
+            if val != None:
+                if LEGACY_CFG_TYPES.get(sxp_arg):
+                    self[sxp_arg] = LEGACY_CFG_TYPES[sxp_arg](val)
+                else:
+                    self[sxp_arg] = val
+
+        _set_cfg_if_exists('shadow_memory')
+        _set_cfg_if_exists('security')
+        _set_cfg_if_exists('features')
+        _set_cfg_if_exists('on_xend_stop')
+        _set_cfg_if_exists('on_xend_start')
+        _set_cfg_if_exists('vcpu_avail')
+        _set_cfg_if_exists('max_vcpu_id') # TODO, deprecated?
+        
+        # Parse and store runtime configuration 
+        _set_cfg_if_exists('start_time')
+        _set_cfg_if_exists('online_vcpus')
+        _set_cfg_if_exists('cpu_time')
+        _set_cfg_if_exists('shutdown_reason')
+        _set_cfg_if_exists('up_time')
+        _set_cfg_if_exists('status') # TODO, deprecated  
+
+    def _add_xapi_unsupported(self):
+        """Updates the configuration object with entries that are not
+        officially supported by the Xen API but is required for
+        the rest of Xend to function.
+        """
+
+        # populate image
+        self['image']['type'] = self['builder']
+        if self['builder'] == 'hvm':
+            self['image']['hvm'] = {}
+            for xapi, cfgapi in XENAPI_HVM_CFG.items():
+                self['image']['hvm'][cfgapi] = self[xapi]
+            
 
     def _get_old_state_string(self):
+        """Returns the old xm state string.
+        @rtype: string
+        @return: old state string
+        """
         state_string = ''
         for state_name in CONFIG_OLD_DOM_STATES:
             on_off = self.get(state_name, 0)
@@ -669,8 +720,40 @@ class XendConfig(dict):
 
         return state_string
 
-    def get_sxp(self, domain = None, ignore_devices = False, ignore = []):
+
+    def update_config(self, dominfo):
+        """Update configuration with the output from xc.domain_getinfo().
+
+        @param dominfo: Domain information via xc.domain_getinfo()
+        @type dominfo: dict
+        """
+        self._dominfo_to_xapi(dominfo)
+        self.validate()
+
+    def update_with_xenapi_config(self, xapi):
+        """Update configuration with a Xen API VM struct
+
+        @param xapi: Xen API VM Struct
+        @type xapi: dict
+        """
+        for key, val in xapi.items():
+            key = key.lower()
+            type_conv = XENAPI_CFG_TYPES.get(key)
+            if callable(type_conv):
+                self[key] = type_conv(val)
+            else:
+                self[key] = val
+
+        self.validate()
+
+    def to_xml(self):
+        """Return an XML string representing the configuration."""
+        pass
+
+    def to_sxp(self, domain = None, ignore_devices = False, ignore = []):
         """ Get SXP representation of this config object.
+
+        Incompat: removed store_mfn, console_mfn
 
         @keyword domain: (optional) XendDomainInfo to get extra information
                          from such as domid and running devices.
@@ -688,44 +771,36 @@ class XendConfig(dict):
         if domain.getDomid() is not None:
             sxpr.append(['domid', domain.getDomid()])
 
-        for cfg, typefunc in ROUNDTRIPPING_CONFIG_ENTRIES:
-            if cfg in self:
-                if self[cfg] is not None:
-                    sxpr.append([cfg, self[cfg]])
-
-        if 'image' in self and self['image'] is not None:
-            sxpr.append(['image', self['image']])
-        if 'security' in self and self['security']:
-            sxpr.append(['security', self['security']])
-        if 'shutdown_reason' in self:
-            sxpr.append(['shutdown_reason', self['shutdown_reason']])
-        if 'cpu_time' in self:
-            sxpr.append(['cpu_time', self['cpu_time']/1e9])
-
-        sxpr.append(['online_vcpus', self['online_vcpus']])
-
-        if 'start_time' in self:
-            uptime = time.time() - self['start_time']
-            sxpr.append(['up_time', str(uptime)])
-            sxpr.append(['start_time', str(self['start_time'])])
-
-        if domain:
-            sxpr.append(['status', str(domain.state)])
-        else:
-            sxpr.append(['status', str(DOM_STATE_HALTED)])
+        for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
+            if self.has_key(xenapi) and self[xenapi] not in (None, []):
+                if type(self[xenapi]) == bool:
+                    # convert booleans to ints before making an sxp item
+                    sxpr.append([legacy, int(self[xenapi])])
+                else:
+                    sxpr.append([legacy, self[xenapi]])
+
+        for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
+            if legacy in ('domid', 'uuid'): # skip these
+                continue
+            if self.has_key(legacy) and self[legacy] not in (None, []):
+                sxpr.append([legacy, self[legacy]])
+
+        if 'image' in self and self['image']:
+            sxpr.append(['image', self.image_sxpr()])
+
+        sxpr.append(['status', domain.state])
+        sxpr.append(['memory_dynamic_min',  self.get('memory_dynamic_min')])
+        sxpr.append(['memory_dynamic_max',  self.get('memory_dynamic_max')])
 
         if domain.getDomid() is not None:
             sxpr.append(['state', self._get_old_state_string()])
 
-        sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max',
-                                                    self['memory'])])
-
-        # For save/restore migration
         if domain:
             if domain.store_mfn:
                 sxpr.append(['store_mfn', domain.store_mfn])
             if domain.console_mfn:
                 sxpr.append(['console_mfn', domain.console_mfn])
+
 
         # Marshall devices (running or from configuration)
         if not ignore_devices:
@@ -743,7 +818,7 @@ class XendConfig(dict):
                     except:
                         log.exception("dumping sxp from device controllers")
                         pass
-                        
+                    
                 # if we didn't find that device, check the existing config
                 # for a device in the same class
                 if not found:
@@ -751,58 +826,28 @@ class XendConfig(dict):
                         if dev_type == cls:
                             sxpr.append(['device', dev_info])
 
-        return sxpr
-
-    def validate(self):
-        """ Validate the configuration and fill in missing configuration
-        with defaults.
+        return sxpr    
+    
+    def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
+        """Add a device configuration in SXP format or XenAPI struct format.
+
+        For SXP, it could be either:
+
+        [device, [vbd, [uname ...]]
+
+        or:
+
+        [vbd, [uname ..]]
+
+        @type cfg_sxp: list of lists (parsed sxp object)
+        @param cfg_sxp: SXP configuration object
+        @type cfg_xenapi: dict
+        @param cfg_xenapi: A device configuration from Xen API (eg. vbd,vif)
+        @rtype: string
+        @return: Assigned UUID of the device.
         """
-
-        # Fill in default values
-        for key, default_func in DEFAULT_CONFIGURATION:
-            if key not in self or self[key] == None:
-                self[key] = default_func(self)
-
-        # Basic sanity checks
-        if 'image' in self and isinstance(self['image'], str):
-            self['image'] = sxp.from_string(self['image'])
-        if 'security' in self and isinstance(self['security'], str):
-            self['security'] = sxp.from_string(self['security'])
-        if self['memory'] == 0 and 'mem_kb' in self:
-            self['memory'] = (self['mem_kb'] + 1023)/1024
-        if self['memory'] <= 0:
-            raise XendConfigError('Invalid memory size: %s' %
-                                  str(self['memory']))
-
-        self['maxmem'] = max(self['memory'], self['maxmem'])
-
-        # convert mem_kb from domain_getinfo to something more descriptive
-        if 'mem_kb' in self:
-            self['memory_dynamic_max'] = (self['mem_kb'] + 1023)/1024
-
-        # Verify devices
-        for d_uuid, (d_type, d_info) in self['device'].items():
-            if d_type not in XendDevices.valid_devices() and \
-               d_type not in XendDevices.pseudo_devices():
-                raise XendConfigError('Invalid device (%s)' % d_type)
-
-        # Verify restart modes
-        for event in ('on_poweroff', 'on_reboot', 'on_crash'):
-            if self[event] not in CONFIG_RESTART_MODES:
-                raise XendConfigError('Invalid restart event: %s = %s' % \
-                                      (event, str(self[event])))
-
-        # Verify that {vif,vbd}_refs are here too
-        if 'vif_refs' not in self:
-            self['vif_refs'] = []
-        if 'vbd_refs' not in self:
-            self['vbd_refs'] = []
-        if 'vtpm_refs' not in self:
-            self['vtpm_refs'] = []
-
-    def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
         if dev_type not in XendDevices.valid_devices() and \
-           dev_type not in XendDevices.pseudo_devices():
+           dev_type not in XendDevices.pseudo_devices():        
             raise XendConfigError("XendConfig: %s not a valid device type" %
                             dev_type)
 
@@ -816,22 +861,48 @@ class XendConfig(dict):
             log.debug("XendConfig.device_add: %s" % str(cfg_xenapi))
 
         if cfg_sxp:
+            if sxp.child0(cfg_sxp) == 'device':
+                config = sxp.child0(cfg_sxp)
+            else:
+                config = cfg_sxp
+
+            dev_type = sxp.name(config)
             dev_info = {}
 
             try:
-                for opt, val in cfg_sxp[1:]:
+                for opt, val in config[1:]:
                     dev_info[opt] = val
             except ValueError:
                 pass # SXP has no options for this device
 
+            
+            def _get_config_ipaddr(config):
+                val = []
+                for ipaddr in sxp.children(config, elt='ip'):
+                    val.append(sxp.child0(ipaddr))
+                return val
+
+            if dev_type == 'vif' and 'ip' in dev_info:
+                dev_info['ip'] = _get_config_ipaddr(config)
+
+            if dev_type == 'vbd':
+                if dev_info.get('dev', '').startswith('ioemu:'):
+                    dev_info['driver'] = 'ioemu'
+                else:
+                    dev_info['driver'] = 'paravirtualised'
+                    
+
             # create uuid if it doesn't exist
             dev_uuid = dev_info.get('uuid', uuid.createString())
             dev_info['uuid'] = dev_uuid
-            self['device'][dev_uuid] = (dev_type, dev_info)
-            if dev_type in ('vif', 'vbd'):
+
+            # store dev references by uuid for certain device types
+            self['devices'][dev_uuid] = (dev_type, dev_info)
+            if dev_type in ('vif', 'vbd', 'vtpm'):
                 self['%s_refs' % dev_type].append(dev_uuid)
             elif dev_type in ('tap',):
                 self['vbd_refs'].append(dev_uuid)
+
             return dev_uuid
 
         if cfg_xenapi:
@@ -849,13 +920,21 @@ class XendConfig(dict):
                 
                 dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
                 dev_info['uuid'] = dev_uuid
-                self['device'][dev_uuid] = (dev_type, dev_info)
+                self['devices'][dev_uuid] = (dev_type, dev_info)
                 self['vif_refs'].append(dev_uuid)
                 return dev_uuid
             
-            elif dev_type == 'vbd':
-                dev_info['uname'] = cfg_xenapi.get('image', None)
-                dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+            elif dev_type in ('vbd', 'tap'):
+                if dev_type == 'vbd':
+                    dev_info['uname'] = cfg_xenapi.get('image', '')
+                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+                elif dev_type == 'tap':
+                    dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
+                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+                    
+                dev_info['driver'] = cfg_xenapi.get('driver')
+                dev_info['VDI'] = cfg_xenapi.get('VDI', '')
+                    
                 if cfg_xenapi.get('mode') == 'RW':
                     dev_info['mode'] = 'w'
                 else:
@@ -863,35 +942,43 @@ class XendConfig(dict):
 
                 dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
                 dev_info['uuid'] = dev_uuid
-                self['device'][dev_uuid] = (dev_type, dev_info)
+                self['devices'][dev_uuid] = (dev_type, dev_info)
                 self['vbd_refs'].append(dev_uuid)                
                 return dev_uuid
 
-            elif dev_type == 'vtpm':
+            elif dev_type in ('vtpm'):
                 if cfg_xenapi.get('type'):
                     dev_info['type'] = cfg_xenapi.get('type')
+
                 dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
                 dev_info['uuid'] = dev_uuid
-                self['device'][dev_uuid] = (dev_type, dev_info)
+                self['devices'][dev_uuid] = (dev_type, dev_info)
                 self['vtpm_refs'].append(dev_uuid)
                 return dev_uuid
 
-            elif dev_type == 'tap':
-                dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
-                dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
-                
-                if cfg_xenapi.get('mode') == 'RW':
-                    dev_info['mode'] = 'w'
-                else:
-                    dev_info['mode'] = 'r'
-
-                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
-                dev_info['uuid'] = dev_uuid
-                self['device'][dev_uuid] = (dev_type, dev_info)
-                self['vbd_refs'].append(dev_uuid)                
-                return dev_uuid                
-                
         return ''
+
+    def device_update(self, dev_uuid, cfg_sxp):
+        """Update an existing device with the new configuration.
+
+        @rtype: boolean
+        @return: Returns True if succesfully found and updated a device conf
+        """
+        if dev_uuid in self['devices']:
+            config = sxp.child0(cfg_sxp)
+            dev_type = sxp.name(config)
+            dev_info = {}
+
+            try:
+                for opt, val in config[1:]:
+                    self['devices'][opt] = val
+            except ValueError:
+                pass # SXP has no options for this device
+            
+            return True
+
+        return False
+
 
     def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None):
         """Get Device SXPR by either giving the device UUID or (type, config).
@@ -900,8 +987,8 @@ class XendConfig(dict):
         @return: device config sxpr
         """
         sxpr = []
-        if dev_uuid != None and dev_uuid in self['device']:
-            dev_type, dev_info = self['device'][dev_uuid]
+        if dev_uuid != None and dev_uuid in self['devices']:
+            dev_type, dev_info = self['devices'][dev_uuid]
 
         if dev_type == None or dev_info == None:
             raise XendConfigError("Required either UUID or device type and "
@@ -917,27 +1004,106 @@ class XendConfig(dict):
         """Returns the SXPR for all devices in the current configuration."""
         sxprs = []
         pci_devs = []
-        for dev_type, dev_info in self['device'].values():
+
+        if 'devices' not in self:
+            return sxprs
+        
+        for dev_type, dev_info in self['devices'].values():
             if dev_type == 'pci': # special case for pci devices
-                pci_devs.append(dev_info)
+                sxpr = [['uuid', dev_info['uuid']]]
+                for pci_dev_info in dev_info['devs']:
+                    pci_dev_sxpr = ['dev']
+                    for opt, val in pci_dev_info.items():
+                        pci_dev_sxpr.append([opt, val])
+                    sxpr.append(pci_dev_sxpr)
+                sxprs.append((dev_type, sxpr))
             else:
                 sxpr = self.device_sxpr(dev_type = dev_type,
                                         dev_info = dev_info)
                 sxprs.append((dev_type, sxpr))
 
-        # if we have any pci_devs, we parse them differently into
-        # one single pci SXP entry.
-        if pci_devs:
-            sxpr = ['pci',]
-            for dev_info in pci_devs:
-                dev_sxpr = self.device_sxpr(dev_type = 'dev',
-                                            dev_info = dev_info)
-                sxpr.append(dev_sxpr)
-            sxprs.append(('pci', sxpr))
-            
         return sxprs
 
-                     
+    def image_sxpr(self):
+        """Returns a backwards compatible image SXP expression that is
+        used in xenstore's /vm/<uuid>/image value and xm list."""
+        image = [self['image'].get('type', 'linux')]
+        if self.has_key('kernel_kernel'):
+            image.append(['kernel', self['kernel_kernel']])
+        if self.has_key('kernel_initrd') and self['kernel_initrd']:
+            image.append(['ramdisk', self['kernel_initrd']])
+        if self.has_key('kernel_args') and self['kernel_args']:
+            image.append(['args', self['kernel_args']])
+
+        for arg, conv in LEGACY_IMAGE_CFG:
+            if self['image'].has_key(arg):
+                image.append([arg, self['image'][arg]])
+
+        if 'hvm' in self['image']:
+            for arg, conv in LEGACY_IMAGE_HVM_CFG:
+                if self['image']['hvm'].get(arg):
+                    image.append([arg, self['image']['hvm'][arg]])
+
+        if 'hvm' in self['image'] and 'devices' in self['image']['hvm']:
+            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
+                if self['image']['hvm']['devices'].get(arg):
+                    image.append([arg,
+                                  self['image']['hvm']['devices'][arg]])
+
+        return image
+
+    def update_with_image_sxp(self, image_sxp):
+        # Convert Legacy "image" config to Xen API kernel_*
+        # configuration
+        self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
+        self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
+        kernel_args = sxp.child_value(image_sxp, 'args', '')
+        
+        # attempt to extract extra arguments from SXP config
+        arg_ip = sxp.child_value(image_sxp, 'ip')
+        if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
+            kernel_args += ' ip=%s' % arg_ip
+        arg_root = sxp.child_value(image_sxp, 'root')
+        if arg_root and not re.search(r'root=', kernel_args):
+            kernel_args += ' root=%s' % arg_root
+        self['kernel_args'] = kernel_args
+
+        # Store image SXP in python dictionary format
+        image = {}
+        image['type'] = sxp.name(image_sxp)
+        for arg, conv in LEGACY_IMAGE_CFG:
+            val = sxp.child_value(image_sxp, arg, None)
+            if val != None:
+                image[arg] = conv(val)
+
+        image_hvm = {}
+        for arg, conv in LEGACY_IMAGE_HVM_CFG:
+            val = sxp.child_value(image_sxp, arg, None)
+            if val != None:
+                image_hvm[arg] = conv(val)
+                    
+        image_hvm_devices = {}
+        for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
+            val = sxp.child_value(image_sxp, arg, None)
+            if val != None:
+                image_hvm_devices[arg] = conv(val)
+
+        if image_hvm or image_hvm_devices:
+            image['hvm'] = image_hvm
+            image['hvm']['devices'] = image_hvm_devices
+
+        self['image'] = image
+
+        for apikey, imgkey in XENAPI_HVM_CFG.items():
+            val = sxp.child_value(image_sxp, imgkey, None)
+            if val != None:
+                type_conv = XENAPI_CFG_TYPES[apikey]
+                if callable(conv):
+                    self[apikey] = type_conv(val)
+                else:
+                    self[apikey] = val
+
+        
 #
 # debugging 
 #
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendConstants.py
--- a/tools/python/xen/xend/XendConstants.py    Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendConstants.py    Mon Dec 04 08:24:41 2006 -0700
@@ -34,6 +34,8 @@ DOMAIN_SHUTDOWN_REASONS = {
     DOMAIN_CRASH   : "crash",
     DOMAIN_HALT    : "halt"
 }
+REVERSE_DOMAIN_SHUTDOWN_REASONS = \
+    dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()])
 
 restart_modes = [
     "restart",
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendDevices.py
--- a/tools/python/xen/xend/XendDevices.py      Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendDevices.py      Mon Dec 04 08:24:41 2006 -0700
@@ -19,7 +19,7 @@
 # A collection of DevControllers 
 #
 
-from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif
+from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif, 
vfbif
 from xen.xend.server.BlktapController import BlktapController
 
 class XendDevices:
@@ -41,6 +41,8 @@ class XendDevices:
         'irq': irqif.IRQController,
         'usb': usbif.UsbifController,
         'tap': BlktapController,
+        'vfb': vfbif.VfbifController,
+        'vkbd': vfbif.VkbdifController,
     }
 
     #@classmethod
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py       Mon Dec 04 08:24:41 2006 -0700
@@ -23,6 +23,7 @@
 """
 
 import os
+import stat
 import shutil
 import socket
 import threading
@@ -44,7 +45,7 @@ from xen.xend.XendDevices import XendDev
 
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xswatch import xswatch
-from xen.util import security
+from xen.util import mkdir, security
 from xen.xend import uuid
 
 xc = xen.lowlevel.xc.xc()
@@ -99,11 +100,7 @@ class XendDomain:
         """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)
+        mkdir.parents(dom_path, stat.S_IRWXU)
 
         xstransact.Mkdir(XS_VMROOT)
         xstransact.SetPermissions(XS_VMROOT, {'dom': DOM0_ID})
@@ -184,7 +181,7 @@ class XendDomain:
                 if not dom_uuid:
                     continue
                 
-                dom_name = dom.get('name', 'Domain-%s' % dom_uuid)
+                dom_name = dom.get('name_label', 'Domain-%s' % dom_uuid)
                 try:
                     running_dom = self.domain_lookup_nr(dom_name)
                     if not running_dom:
@@ -271,25 +268,17 @@ class XendDomain:
             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)
-            
-            if not os.path.exists(domain_config_dir):
+
+            def make_or_raise(path):
                 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)
-                
+                    mkdir.parents(path, stat.S_IRWXU)
+                except:
+                    log.exception("%s could not be created." % path)
+                    raise XendError("%s could not be created." % path)
+
+            make_or_raise(domains_dir)
+            make_or_raise(domain_config_dir)
+
             try:
                 sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
                 prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
@@ -423,7 +412,6 @@ class XendDomain:
                 self._remove_domain(dom, domid)
 
 
-
     def _add_domain(self, info):
         """Add a domain to the list of running domains
         
@@ -433,6 +421,11 @@ class XendDomain:
         """
         log.debug("Adding Domain: %s" % info.getDomid())
         self.domains[info.getDomid()] = info
+        
+        # update the managed domains with a new XendDomainInfo object
+        # if we are keeping track of it.
+        if info.get_uuid() in self.managed_domains:
+            self._managed_domain_register(info)
 
     def _remove_domain(self, info, domid = None):
         """Remove the domain from the list of running domains
@@ -669,7 +662,7 @@ class XendDomain:
         self.domains_lock.acquire()
         try:
             try:
-                xeninfo = XendConfig(xenapi_vm = xenapi_vm)
+                xeninfo = XendConfig(xapi = xenapi_vm)
                 dominfo = XendDomainInfo.createDormant(xeninfo)
                 log.debug("Creating new managed domain: %s: %s" %
                           (dominfo.getName(), dominfo.get_uuid()))
@@ -873,8 +866,8 @@ class XendDomain:
         self.domains_lock.acquire()
         try:
             try:
-                xeninfo = XendConfig(sxp = config)
-                dominfo = XendDomainInfo.createDormant(xeninfo)
+                domconfig = XendConfig(sxp_obj = config)
+                dominfo = XendDomainInfo.createDormant(domconfig)
                 log.debug("Creating new managed domain: %s" %
                           dominfo.getName())
                 self._managed_domain_register(dominfo)
@@ -935,6 +928,9 @@ class XendDomain:
 
                 if dominfo.state != DOM_STATE_HALTED:
                     raise XendError("Domain is still running")
+
+                log.info("Domain %s (%s) deleted." %
+                         (dominfo.getName(), dominfo.info.get('uuid')))
 
                 self._managed_domain_unregister(dominfo)
                 self._remove_domain(dominfo)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Dec 04 08:24:41 2006 -0700
@@ -38,10 +38,9 @@ from xen.util import security
 from xen.util import security
 
 from xen.xend import balloon, sxp, uuid, image, arch
-from xen.xend import XendRoot, XendNode
+from xen.xend import XendRoot, XendNode, XendConfig
 
 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
@@ -57,6 +56,11 @@ xroot = XendRoot.instance()
 
 log = logging.getLogger("xend.XendDomainInfo")
 #log.setLevel(logging.TRACE)
+
+
+def bool0(v):
+    return v != "0" and bool(v)
+
 
 ##
 # All parameters of VMs that may be configured on-the-fly, or at start-up.
@@ -88,7 +92,7 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [
     ('bootloader',      str),
     ('bootloader_args', str),
     ('features',        str),
-    ('localtime',       int),
+    ('localtime',       bool0),
     ]
 
 ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
@@ -145,7 +149,7 @@ def create(config):
     """
 
     log.debug("XendDomainInfo.create(%s)", config)
-    vm = XendDomainInfo(XendConfig(sxp = config))
+    vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
     try:
         vm.start()
     except:
@@ -175,10 +179,9 @@ def recreate(info, priv):
 
     assert not info['dying']
 
-    xeninfo = XendConfig(cfg = info)
+    xeninfo = XendConfig.XendConfig(dominfo = info)
     domid = xeninfo['domid']
-    uuid1 = xeninfo['handle']
-    xeninfo['uuid'] = uuid.toString(uuid1)
+    uuid1 = uuid.fromString(xeninfo['uuid'])
     needs_reinitialising = False
     
     dompath = GetDomainPath(domid)
@@ -228,6 +231,15 @@ def recreate(info, priv):
         vm._storeVmDetails()
         vm._storeDomDetails()
         
+    if vm.info['image']: # Only dom0 should be without an image entry when
+                         # recreating, but we cope with missing ones
+                         # elsewhere just in case.
+        vm.image = image.create(vm,
+                                vm.info,
+                                vm.info['image'],
+                                vm.info['devices'])
+        vm.image.recreate()
+
     vm._registerWatches()
     vm.refreshShutdown(xeninfo)
     return vm
@@ -236,7 +248,7 @@ def restore(config):
 def restore(config):
     """Create a domain and a VM object to do a restore.
 
-    @param config: Domain configuration object
+    @param config: Domain SXP configuration
     @type  config: list of lists. (see C{create})
 
     @rtype:  XendDomainInfo
@@ -246,7 +258,8 @@ def restore(config):
     """
 
     log.debug("XendDomainInfo.restore(%s)", config)
-    vm = XendDomainInfo(XendConfig(sxp = config), resume = True)
+    vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
+                        resume = True)
     try:
         vm.resume()
         return vm
@@ -254,24 +267,24 @@ def restore(config):
         vm.destroy()
         raise
 
-def createDormant(xeninfo):
+def createDormant(domconfig):
     """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
+    @param domconfig: Parsed configuration
+    @type  domconfig: XendConfig object
     
     @rtype:  XendDomainInfo
     @return: A up and running XendDomainInfo instance
     @raise XendError: Errors with configuration.    
     """
     
-    log.debug("XendDomainInfo.createDormant(%s)", xeninfo)
+    log.debug("XendDomainInfo.createDormant(%s)", domconfig)
     
     # domid does not make sense for non-running domains.
-    xeninfo.pop('domid', None)
-    vm = XendDomainInfo(XendConfig(cfg = xeninfo))
+    domconfig.pop('domid', None)
+    vm = XendDomainInfo(domconfig)
     return vm    
 
 def domain_by_name(name):
@@ -383,14 +396,6 @@ class XendDomainInfo:
         #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
 
@@ -403,6 +408,7 @@ class XendDomainInfo:
         self.vmWatch = None
         self.shutdownWatch = None
         self.shutdownStartTime = None
+        self._resume = resume
 
         self.state = DOM_STATE_HALTED
         self.state_updated = threading.Condition()
@@ -416,8 +422,7 @@ class XendDomainInfo:
         if augment:
             self._augmentInfo(priv)
 
-        self._checkName(self.info['name'])
-        self.setResume(resume)
+        self._checkName(self.info['name_label'])
             
 
     #
@@ -477,10 +482,11 @@ class XendDomainInfo:
         if self.domid == 0:
             raise XendError('Domain 0 cannot be shutdown')
         
-        if not reason in DOMAIN_SHUTDOWN_REASONS.values():
+        if reason not in DOMAIN_SHUTDOWN_REASONS.values():
             raise XendError('Invalid reason: %s' % reason)
-        self._storeDom("control/shutdown", reason)
-                
+        self._removeVm('xend/previous_restart_time')
+        self.storeDom("control/shutdown", reason)
+
     def pause(self):
         """Pause domain
         
@@ -506,18 +512,20 @@ class XendDomainInfo:
     def send_sysrq(self, key):
         """ Send a Sysrq equivalent key via xenstored."""
         asserts.isCharConvertible(key)
-        self._storeDom("control/sysrq", '%c' % 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)
+        @type  dev_config: SXP object (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)        
+        dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
+        dev_config_dict = self.info['devices'][dev_uuid][1]
+        log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
+        devid = self._createDevice(dev_type, dev_config_dict)
         self._waitForDevice(dev_type, devid)
         return self.getDeviceController(dev_type).sxpr(devid)
 
@@ -525,12 +533,26 @@ class XendDomainInfo:
         """Configure an existing device.
         
         @param dev_config: device configuration
-        @type  dev_config: dictionary (parsed config)
+        @type  dev_config: SXP object (parsed config)
         @param devid:      device id
         @type  devid:      int
+        @return: Returns True if successfully updated device
+        @rtype: boolean
         """
         deviceClass = sxp.name(dev_config)
-        self._reconfigureDevice(deviceClass, devid, dev_config)
+        
+        # look up uuid of the device
+        dev_control =  self.getDeviceController(deviceClass)
+        dev_sxpr = dev_control.sxpr(devid)
+        dev_uuid = sxp.child_value(sxpr, 'uuid')
+        if not dev_uuid:
+            return False
+
+        self.info.device_update(dev_uuid, dev_config)
+        dev_config_dict = self.info['devices'].get(dev_uuid)
+        if dev_config_dict:
+            dev_control.reconfigureDevice(devid, dev_config_dict[1])
+        return True
 
     def waitForDevices(self):
         """Wait for this domain's configured devices to connect.
@@ -558,8 +580,18 @@ class XendDomainInfo:
         return self.getDeviceController(deviceClass).destroyDevice(devid)
 
 
+
     def getDeviceSxprs(self, deviceClass):
-        return self.getDeviceController(deviceClass).sxprs()
+        if self.state == DOM_STATE_RUNNING:
+            return self.getDeviceController(deviceClass).sxprs()
+        else:
+            sxprs = []
+            dev_num = 0
+            for dev_type, dev_info in self.info.all_devices_sxpr():
+                if dev_type == deviceClass:
+                    sxprs.append([dev_num, dev_info])
+                    dev_num += 1
+            return sxprs
 
 
     def setMemoryTarget(self, target):
@@ -567,22 +599,22 @@ class XendDomainInfo:
         @param target: In MiB.
         """
         log.debug("Setting memory target of domain %s (%d) to %d MiB.",
-                  self.info['name'], self.domid, target)
+                  self.info['name_label'], self.domid, target)
         
         if target <= 0:
             raise XendError('Invalid memory size')
         
-        self.info['memory'] = target
+        self.info['memory_static_min'] = target
         self.storeVm("memory", target)
-        self._storeDom("memory/target", target << 10)
+        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']]]
+                    ['name',       self.info['name_label']],
+                    ['vcpu_count', self.info['vcpus_number']]]
 
             for i in range(0, self.info['max_vcpu_id']+1):
                 info = xc.vcpu_getinfo(self.domid, i)
@@ -610,30 +642,40 @@ class XendDomainInfo:
         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:
-                self.info[name] = val
-
+        augment_entries = XendConfig.LEGACY_XENSTORE_VM_PARAMS[:]
         if priv:
-            entries = VM_STORE_ENTRIES[:]
-            entries.remove(('memory', int))
-            entries.remove(('maxmem', int))
-        else:
-            entries = VM_STORE_ENTRIES
-        entries.append(('image', str))
-        entries.append(('security', str))
-
-        map(lambda x, y: useIfNeeded(x[0], y), entries,
-            self._readVMDetails(entries))
-
+            augment_entries.remove('memory')
+            augment_entries.remove('maxmem')
+
+        vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
+                                         for k in augment_entries])
+        
+        # make returned lists into a dictionary
+        vm_config = dict(zip(augment_entries, vm_config))
+        
+        for arg in augment_entries:
+            xapicfg = arg
+            val = vm_config[arg]
+            if val != None:
+                if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
+                    xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
+                    self.info[xapiarg] = val
+                else:
+                    self.info[arg] = val
+
+        # read image value
+        image_sxp = self._readVm('image')
+        if image_sxp:
+            self.info.update_with_image_sxp(sxp.from_string(image_sxp))
+
+        # read devices
         devices = []
-
         for devclass in XendDevices.valid_devices():
             devconfig = self.getDeviceController(devclass).configurations()
             if devconfig:
-                devices.extend(map(lambda conf: (devclass, conf), devconfig))
-
-        if not self.info['device'] and devices is not None:
+                devices.extend(devconfig)
+
+        if not self.info['devices'] and devices is not None:
             for device in devices:
                 self.info.device_add(device[0], cfg_sxp = device)
 
@@ -660,8 +702,11 @@ class XendDomainInfo:
     # Function to update xenstore /dom/*
     #
 
-    def _readDom(self, *args):
+    def readDom(self, *args):
         return xstransact.Read(self.dompath, *args)
+
+    def gatherDom(self, *args):
+        return xstransact.Gather(self.dompath, *args)
 
     def _writeDom(self, *args):
         return xstransact.Write(self.dompath, *args)
@@ -669,7 +714,7 @@ class XendDomainInfo:
     def _removeDom(self, *args):
         return xstransact.Remove(self.dompath, *args)
 
-    def _storeDom(self, *args):
+    def storeDom(self, *args):
         return xstransact.Store(self.dompath, *args)
 
     def _recreateDom(self):
@@ -678,16 +723,16 @@ class XendDomainInfo:
     def _recreateDomFunc(self, t):
         t.remove()
         t.mkdir()
-        t.set_permissions({ 'dom' : self.domid })
+        t.set_permissions({'dom' : self.domid})
         t.write('vm', self.vmpath)
 
     def _storeDomDetails(self):
         to_store = {
             'domid':              str(self.domid),
             'vm':                 self.vmpath,
-            'name':               self.info['name'],
+            'name':               self.info['name_label'],
             'console/limit':      str(xroot.get_console_limit() * 1024),
-            'memory/target':      str(self.info['memory'] * 1024)
+            'memory/target':      str(self.info['memory_static_min'] * 1024)
             }
 
         def f(n, v):
@@ -713,7 +758,7 @@ class XendDomainInfo:
                 return 'offline'
 
         result = {}
-        for v in range(0, self.info['vcpus']):
+        for v in range(0, self.info['vcpus_number']):
             result["cpu/%d/availability" % v] = availability(v)
         return result
 
@@ -735,19 +780,29 @@ class XendDomainInfo:
         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)
+
+        # Check whether values in the configuration have
+        # changed in Xenstore.
+        
+        cfg_vm = ['name', 'on_poweroff', 'on_reboot', 'on_crash']
+        
+        vm_details = self._readVMDetails([(k,XendConfig.LEGACY_CFG_TYPES[k])
+                                           for k in cfg_vm])
+
+        # convert two lists into a python dictionary
+        vm_details = dict(zip(cfg_vm, vm_details))
+        
+        for arg, val in vm_details.items():
+            if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
+                xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
+                if val != None and val != self.info[xapiarg]:
+                    self.info[xapiarg] = val
+                    changed= True
+
+        # Check whether image definition has been updated
+        image_sxp = self._readVm('image')
+        if image_sxp and image_sxp != self.info.image_sxpr():
+            self.info.update_with_image_sxp(sxp.from_string(image_sxp))
             changed = True
 
         if changed:
@@ -760,17 +815,17 @@ class XendDomainInfo:
     def _handleShutdownWatch(self, _):
         log.debug('XendDomainInfo.handleShutdownWatch')
         
-        reason = self._readDom('control/shutdown')
+        reason = self.readDom('control/shutdown')
 
         if reason and reason != 'suspend':
-            sst = self._readDom('xend/shutdown_start_time')
+            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)
+                self.storeDom('xend/shutdown_start_time', now)
                 timeout = SHUTDOWN_TIMEOUT
 
             log.trace(
@@ -791,17 +846,17 @@ class XendDomainInfo:
 
     def setName(self, name):
         self._checkName(name)
-        self.info['name'] = name
+        self.info['name_label'] = name
         self.storeVm("name", name)
 
     def getName(self):
-        return self.info['name']
+        return self.info['name_label']
 
     def getDomainPath(self):
         return self.dompath
 
     def getShutdownReason(self):
-        return self._readDom('control/shutdown')
+        return self.readDom('control/shutdown')
 
     def getStorePort(self):
         """For use only by image.py and XendCheckpoint.py."""
@@ -816,11 +871,13 @@ class XendDomainInfo:
         return self.info['features']
 
     def getVCpuCount(self):
-        return self.info['vcpus']
+        return self.info['vcpus_number']
 
     def setVCpuCount(self, vcpus):
         self.info['vcpu_avail'] = (1 << vcpus) - 1
+        self.info['vcpus_number'] = vcpus
         self.storeVm('vcpu_avail', self.info['vcpu_avail'])
+        self.storeVm('vcpus', self.info['vcpus_number'])
         self._writeDom(self._vcpuDomDetails())
 
     def getLabel(self):
@@ -828,19 +885,19 @@ class XendDomainInfo:
 
     def getMemoryTarget(self):
         """Get this domain's target memory size, in KB."""
-        return self.info['memory'] * 1024
+        return self.info['memory_static_min'] * 1024
 
     def getResume(self):
-        return "%s" % self.info['resume']
+        return str(self._resume)
 
     def getCap(self):
-        return self.info['cpu_cap']
+        return self.info.get('cpu_cap', 0)
 
     def getWeight(self):
         return self.info['cpu_weight']
 
     def setResume(self, state):
-        self.info['resume'] = state
+        self._resume = state
 
     def getRestartCount(self):
         return self._readVm('xend/restart_count')
@@ -885,13 +942,13 @@ class XendDomainInfo:
                 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
 
                 log.warn('Domain has crashed: name=%s id=%d.',
-                         self.info['name'], self.domid)
+                         self.info['name_label'], self.domid)
 
                 if xroot.get_enable_dump():
                     self.dumpCore()
@@ -901,7 +958,7 @@ class XendDomainInfo:
 
             elif xeninfo['shutdown']:
                 self._stateSet(DOM_STATE_SHUTDOWN)
-                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
@@ -910,7 +967,7 @@ class XendDomainInfo:
                     reason = shutdown_reason(xeninfo['shutdown_reason'])
 
                     log.info('Domain has shutdown: name=%s id=%d reason=%s.',
-                             self.info['name'], self.domid, reason)
+                             self.info['name_label'], self.domid, reason)
 
                     self._clearRestart()
 
@@ -945,7 +1002,7 @@ class XendDomainInfo:
                     if timeout < 0:
                         log.info(
                             "Domain shutdown timeout expired: name=%s id=%s",
-                            self.info['name'], self.domid)
+                            self.info['name_label'], self.domid)
                         self.destroy()
         finally:
             self.refresh_shutdown_lock.release()
@@ -965,11 +1022,23 @@ class XendDomainInfo:
     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]]()
-
+        actions =  {"destroy"        : self.destroy,
+                    "restart"        : self._restart,
+                    "preserve"       : self._preserve,
+                    "rename-restart" : self._renameRestart}
+
+        action_conf = {
+            'poweroff': 'actions_after_shutdown',
+            'reboot': 'actions_after_reboot',
+            'crash': 'actions_after_crash',
+        }
+
+        action_target = self.info.get(action_conf.get(reason))
+        func = actions.get(action_target, None)
+        if func and callable(func):
+            func()
+        else:
+            self.destroy() # default to destroy
 
     def _renameRestart(self):
         self._restart(True)
@@ -1008,7 +1077,7 @@ class XendDomainInfo:
                 log.error(
                     'VM %s restarting too fast (%f seconds since the last '
                     'restart).  Refusing to restart to avoid loops.',
-                    self.info['name'], timeout)
+                    self.info['name_label'], timeout)
                 self.destroy()
                 return
 
@@ -1055,11 +1124,11 @@ class XendDomainInfo:
         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'],
+                 self.info['name_label'], self.domid, self.info['uuid'],
                  new_name, new_uuid)
         self._unwatchVm()
         self._releaseDevices()
-        self.info['name'] = new_name
+        self.info['name_label'] = new_name
         self.info['uuid'] = new_uuid
         self.vmpath = XS_VMROOT + new_uuid
         self._storeVmDetails()
@@ -1067,10 +1136,10 @@ class XendDomainInfo:
 
 
     def _preserve(self):
-        log.info("Preserving dead domain %s (%d).", self.info['name'],
+        log.info("Preserving dead domain %s (%d).", self.info['name_label'],
                  self.domid)
         self._unwatchVm()
-        self._storeDom('xend/shutdown_completed', 'True')
+        self.storeDom('xend/shutdown_completed', 'True')
         self._stateSet(DOM_STATE_HALTED)
 
     #
@@ -1084,7 +1153,7 @@ class XendDomainInfo:
             if not corefile:
                 this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
                 corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
-                                  self.info['name'], self.domid)
+                                  self.info['name_label'], self.domid)
                 
             if os.path.isdir(corefile):
                 raise XendError("Cannot dump core in a directory: %s" %
@@ -1095,7 +1164,7 @@ class XendDomainInfo:
             corefile_incomp = corefile+'-incomplete'
             os.rename(corefile, corefile_incomp)
             log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
-                          self.domid, self.info['name'])
+                          self.domid, self.info['name_label'])
             raise XendError("Failed to dump core: %s" %  str(ex))
 
     #
@@ -1117,8 +1186,8 @@ class XendDomainInfo:
 
         @raise: VmError for invalid devices
         """
-        for (devclass, config) in self.info.all_devices_sxpr():
-            if devclass in XendDevices.valid_devices():
+        for (devclass, config) in self.info.get('devices', {}).values():
+            if devclass in XendDevices.valid_devices():            
                 log.info("createDevice: %s : %s" % (devclass, config))
                 self._createDevice(devclass, config)
 
@@ -1139,7 +1208,7 @@ class XendDomainInfo:
                         # there's nothing more we can do.
                         log.exception(
                            "Device release failed: %s; %s; %s",
-                           self.info['name'], devclass, dev)
+                           self.info['name_label'], devclass, dev)
             if t.commit():
                 break
 
@@ -1211,11 +1280,12 @@ class XendDomainInfo:
 
         log.debug('XendDomainInfo.constructDomain')
 
-        hvm = (self._infoIsSet('image') and
-               sxp.name(self.info['image']) == "hvm")
+        image_cfg = self.info.get('image', {})
+        hvm = image_cfg.has_key('hvm')
+
         if hvm:
             info = xc.xeninfo()
-            if not 'hvm' in info['xen_caps']:
+            if 'hvm' not in info['xen_caps']:
                 raise VmError("HVM guest support is unavailable: is VT/AMD-V "
                               "supported by your CPU and enabled in your "
                               "BIOS?")
@@ -1228,14 +1298,14 @@ class XendDomainInfo:
 
         if self.domid < 0:
             raise VmError('Creating domain failed: name=%s' %
-                          self.info['name'])
+                          self.info['name_label'])
 
         self.dompath = GetDomainPath(self.domid)
 
         self._recreateDom()
 
         # Set maximum number of vcpus in domain
-        xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
+        xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
 
 
     def _introduceDomain(self):
@@ -1256,7 +1326,7 @@ class XendDomainInfo:
 
         # if we have a boot loader but no image, then we need to set things
         # up by running the boot loader non-interactively
-        if self._infoIsSet('bootloader') and not self._infoIsSet('image'):
+        if self.info.get('bootloader') and self.info.get('image'):
             self._configureBootloader()
 
         if not self._infoIsSet('image'):
@@ -1264,11 +1334,12 @@ class XendDomainInfo:
 
         try:
             self.image = image.create(self,
+                                      self.info,
                                       self.info['image'],
-                                      self.info.all_devices_sxpr())
-
-            localtime = self.info.get('localtime', 0)
-            if localtime is not None and localtime == 1:
+                                      self.info['devices'])
+
+            localtime = self.info.get('localtime', False)
+            if localtime:
                 xc.domain_set_time_offset(self.domid)
 
             xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
@@ -1284,12 +1355,12 @@ class XendDomainInfo:
             # the various headrooms necessary, given the raw configured
             # values. maxmem, memory, and shadow are all in KiB.
             maxmem = self.image.getRequiredAvailableMemory(
-                self.info['maxmem'] * 1024)
+                self.info['memory_static_min'] * 1024)
             memory = self.image.getRequiredAvailableMemory(
-                self.info['memory'] * 1024)
+                self.info['memory_static_max'] * 1024)
             shadow = self.image.getRequiredShadowMemory(
                 self.info['shadow_memory'] * 1024,
-                self.info['maxmem'] * 1024)
+                self.info['memory_static_max'] * 1024)
 
             # Round shadow up to a multiple of a MiB, as shadow_mem_control
             # takes MiB and we must not round down and end up under-providing.
@@ -1317,7 +1388,7 @@ class XendDomainInfo:
 
             self._createDevices()
 
-            if self.info['bootloader'] not in [None, 'kernel_external']:
+            if self.info['bootloader']:
                 self.image.cleanupBootloading()
 
             self.info['start_time'] = time.time()
@@ -1325,7 +1396,7 @@ class XendDomainInfo:
             self._stateSet(DOM_STATE_RUNNING)
         except RuntimeError, exn:
             log.exception("XendDomainInfo.initDomain: exception occurred")
-            if self.info['bootloader'] not in [None, 'kernel_external'] \
+            if self.info['bootloader'] not in (None, 'kernel_external') \
                    and self.image is not None:
                 self.image.cleanupBootloading()
             raise VmError(str(exn))
@@ -1338,7 +1409,6 @@ class XendDomainInfo:
         self.refresh_shutdown_lock.acquire()
         try:
             self.unwatchShutdown()
-
             self._releaseDevices()
 
             if self.image:
@@ -1459,14 +1529,14 @@ class XendDomainInfo:
 
     def _configureBootloader(self):
         """Run the bootloader if we're configured to do so."""
-        if not self.info['bootloader']:
+        if not self.info.get('bootloader'):
             return
         blcfg = None
         # FIXME: this assumes that we want to use the first disk device
-        for (n, c) in self.info.all_devices_sxpr():
-            if not n or not c or not(n in ["vbd", "tap"]):
+        for devuuid, (devtype, devinfo) in self.info.all_devices_sxpr():
+            if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
                 continue
-            disk = sxp.child_value(c, "uname")
+            disk = devinfo.get('uname')
             if disk is None:
                 continue
             fn = blkdev_uname_to_file(disk)
@@ -1478,7 +1548,8 @@ class XendDomainInfo:
             msg = "Had a bootloader specified, but can't find disk"
             log.error(msg)
             raise VmError(msg)
-        self.info['image'] = blcfg
+        
+        self.info.update_with_image_sxp(blcfg)
 
     # 
     # VM Functions
@@ -1516,7 +1587,8 @@ class XendDomainInfo:
         if arch.type == "x86":
             # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
             # the minimum that Xen would allocate if no value were given.
-            overhead_kb = self.info['vcpus'] * 1024 + self.info['maxmem'] * 4
+            overhead_kb = self.info['vcpus_number'] * 1024 + \
+                          self.info['memory_static_max'] * 4
             overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
             # The domain might already have some shadow memory
             overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
@@ -1558,12 +1630,15 @@ class XendDomainInfo:
     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'])
+        for key in XendConfig.LEGACY_XENSTORE_VM_PARAMS:
+            info_key = XendConfig.LEGACY_CFG_TO_XENAPI_CFG.get(key, key)
+            if self._infoIsSet(info_key):
+                to_store[key] = str(self.info[info_key])
+
+        if self.info.get('image'):
+            image_sxpr = self.info.image_sxpr()
+            if image_sxpr:
+                to_store['image'] = sxp.to_string(image_sxpr)
 
         if self._infoIsSet('security'):
             secinfo = self.info['security']
@@ -1633,8 +1708,9 @@ class XendDomainInfo:
             raise VmError('Invalid VM Name')
 
         dom =  XendDomain.instance().domain_lookup_nr(name)
-        if dom and dom != self and not dom.info['dying']:
-            raise VmError("VM name '%s' already exists" % name)
+        if dom and dom.info['uuid'] != self.info['uuid']:
+            raise VmError("VM name '%s' already exists as domain %s" %
+                          (name, str(dom.domid)))
         
 
     def update(self, info = None, refresh = True):
@@ -1656,6 +1732,7 @@ class XendDomainInfo:
                     #create new security element
                     self.info.update({'security':
                                       [['ssidref', str(info['ssidref'])]]})
+                    
         #ssidref field not used any longer
         if 'ssidref' in info:
             info.pop('ssidref')
@@ -1663,8 +1740,7 @@ class XendDomainInfo:
         # make sure state is reset for info
         # TODO: we should eventually get rid of old_dom_states
 
-        self.info.update(info)
-        self.info.validate()
+        self.info.update_config(info)
 
         if refresh:
             self.refreshShutdown(info)
@@ -1673,11 +1749,11 @@ class XendDomainInfo:
                   str(self.domid), self.info)
 
     def sxpr(self, ignore_store = False):
-        result = self.info.get_sxp(domain = self,
+        result = self.info.to_sxp(domain = self,
                                    ignore_devices = ignore_store)
 
         if not ignore_store and self.dompath:
-            vnc_port = self._readDom('console/vnc-port')
+            vnc_port = self.readDom('console/vnc-port')
             if vnc_port is not None:
                 result.append(['device',
                                ['console', ['vnc-port', str(vnc_port)]]])
@@ -1695,9 +1771,15 @@ class XendDomainInfo:
         return dom_uuid
     
     def get_memory_static_max(self):
-        return self.info['maxmem']
+        return self.info.get('memory_static_max')
     def get_memory_static_min(self):
-        return self.info['memory']
+        return self.info.get('memory_static_min')
+    def get_memory_dynamic_max(self):
+        return self.info.get('memory_dynamic_min')
+    def get_memory_dynamic_min(self):
+        return self.info.get('memory_dynamic_max')
+    
+    
     def get_vcpus_policy(self):
         sched_id = xc.sched_id_get()
         if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
@@ -1713,31 +1795,29 @@ class XendDomainInfo:
     def get_bios_boot(self):
         return '' # TODO
     def get_platform_std_vga(self):
-        return False
+        return self.info.get('platform_std_vga', False)    
     def get_platform_keymap(self):
         return ''
     def get_platform_serial(self):
-        return '' # TODO
+        return self.info.get('platform_serial', '')
     def get_platform_localtime(self):
-        return False # TODO
+        return self.info.get('platform_localtime', False)
     def get_platform_clock_offset(self):
-        return False # TODO
+        return self.info.get('platform_clock_offset', False)
     def get_platform_enable_audio(self):
-        return False # TODO
+        return self.info.get('platform_enable_audio', False)
+    def get_platform_keymap(self):
+        return self.info.get('platform_keymap', '')
     def get_builder(self):
-        return 'Linux' # TODO
+        return self.info.get('builder', 0)
     def get_boot_method(self):
-        bootloader = self.info['bootloader']
-        if not bootloader or bootloader not in XEN_API_BOOT_TYPE:
-            return 'kernel_external'
-        return bootloader
-    
+        return self.info.get('boot_method', '')
     def get_kernel_image(self):
-        return self.info['kernel_kernel']
+        return self.info.get('kernel_kernel', '')
     def get_kernel_initrd(self):
-        return self.info['kernel_initrd']
+        return self.info.get('kernel_initrd', '')
     def get_kernel_args(self):
-        return self.info['kernel_args']
+        return self.info.get('kernel_args', '')
     def get_grub_cmdline(self):
         return '' # TODO
     def get_pci_bus(self):
@@ -1748,25 +1828,26 @@ class XendDomainInfo:
         return {} # TODO
     
     def get_on_shutdown(self):
-        after_shutdown = self.info.get('on_poweroff')
+        after_shutdown = self.info.get('action_after_shutdown')
         if not after_shutdown or after_shutdown not in XEN_API_ON_NORMAL_EXIT:
             return XEN_API_ON_NORMAL_EXIT[-1]
         return after_shutdown
 
     def get_on_reboot(self):
-        after_reboot = self.info.get('on_reboot')
+        after_reboot = self.info.get('action_after_reboot')
         if not after_reboot or after_reboot not in XEN_API_ON_NORMAL_EXIT:
             return XEN_API_ON_NORMAL_EXIT[-1]
         return after_reboot
 
     def get_on_suspend(self):
-        after_suspend = self.info.get('on_suspend') # TODO: not supported
+        # TODO: not supported        
+        after_suspend = self.info.get('action_after_suspend') 
         if not after_suspend or after_suspend not in XEN_API_ON_NORMAL_EXIT:
             return XEN_API_ON_NORMAL_EXIT[-1]
         return after_suspend        
 
     def get_on_crash(self):
-        after_crash = self.info.get('on_crash')
+        after_crash = self.info.get('action_after_crash')
         if not after_crash or after_crash not in XEN_API_ON_CRASH_BEHAVIOUR:
             return XEN_API_ON_CRASH_BEHAVIOUR[0]
         return after_crash
@@ -1780,7 +1861,7 @@ class XendDomainInfo:
 
         @rtype: dictionary
         """
-        dev_type_config = self.info['device'].get(dev_uuid)
+        dev_type_config = self.info['devices'].get(dev_uuid)
 
         # shortcut if the domain isn't started because
         # the devcontrollers will have no better information
@@ -1840,7 +1921,7 @@ class XendDomainInfo:
             config['IO_bandwidth_incoming_kbs'] = 0.0
             config['IO_bandwidth_outgoing_kbs'] = 0.0
 
-        if dev_class =='vbd':
+        if dev_class == 'vbd':
             config['VDI'] = '' # TODO
             config['device'] = config.get('dev', '')
             config['driver'] = 'paravirtualised' # TODO
@@ -1984,8 +2065,8 @@ class XendDomainInfo:
 
     def __str__(self):
         return '<domain id=%s name=%s memory=%s state=%s>' % \
-               (str(self.domid), self.info['name'],
-                str(self.info['memory']), DOM_STATES[self.state])
+               (str(self.domid), self.info['name_label'],
+                str(self.info['memory_static_min']), DOM_STATES[self.state])
 
     __repr__ = __str__
 
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py      Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendLogging.py      Mon Dec 04 08:24:41 2006 -0700
@@ -16,13 +16,15 @@
 # Copyright (C) 2005, 2006 XenSource Ltd.
 #============================================================================
 
-
+import os
+import stat
 import tempfile
 import types
 import logging
 import logging.handlers
 import fcntl
 
+from xen.util import mkdir
 from xen.xend.server import params
 
 
@@ -80,6 +82,7 @@ def init(filename, level):
     global logfilename
 
     def openFileHandler(fname):
+        mkdir.parents(os.path.dirname(fname), stat.S_IRWXU)
         return XendRotatingFileHandler(fname, mode = 'a',
                                        maxBytes = MAX_BYTES,
                                        backupCount = BACKUP_COUNT)
diff -r 6fdbf173142d -r d603aed5ad6d 
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py    Sat Dec 02 15:19:50 
2006 -0700
+++ b/tools/python/xen/xend/XendStorageRepository.py    Mon Dec 04 08:24:41 
2006 -0700
@@ -19,10 +19,12 @@
 # The default QCOW Xen API Storage Repository
 #
 
+import commands
 import os
-import commands
+import stat
 import threading
 
+from xen.util import mkdir
 from xen.xend import uuid
 from xen.xend.XendError import XendError
 from xen.xend.XendVDI import *
@@ -98,10 +100,7 @@ class XendStorageRepository:
         """
         self.lock.acquire()
         try:
-            # create directory if /var/lib/xend/storage does not exist
-            if not os.path.exists(XEND_STORAGE_DIR):
-                os.makedirs(XEND_STORAGE_DIR)
-                os.chmod(XEND_STORAGE_DIR, 0700)
+            mkdir.parents(XEND_STORAGE_DIR, stat.S_IRWXU)
 
             # scan the directory and populate self.images
             total_used = 0
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/image.py    Mon Dec 04 08:24:41 2006 -0700
@@ -23,7 +23,7 @@ import signal
 import signal
 
 import xen.lowlevel.xc
-from xen.xend import sxp
+from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
 from xen.xend.XendError import VmError, XendError
 from xen.xend.XendLogging import log
 from xen.xend.server.netif import randomMAC
@@ -31,19 +31,18 @@ from xen.xend import arch
 from xen.xend import arch
 from xen.xend import FlatDeviceTree
 
-
 xc = xen.lowlevel.xc.xc()
 
-
 MAX_GUEST_CMDLINE = 1024
 
 
-def create(vm, imageConfig, deviceConfig):
+def create(vm, vmConfig, imageConfig, deviceConfig):
     """Create an image handler for a vm.
 
     @return ImageHandler instance
     """
-    return findImageHandlerClass(imageConfig)(vm, imageConfig, deviceConfig)
+    return findImageHandlerClass(imageConfig)(vm, vmConfig, imageConfig,
+                                              deviceConfig)
 
 
 class ImageHandler:
@@ -66,34 +65,20 @@ class ImageHandler:
     ostype = None
 
 
-    def __init__(self, vm, imageConfig, deviceConfig):
+    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
         self.vm = vm
 
         self.kernel = None
         self.ramdisk = None
         self.cmdline = None
 
-        self.configure(imageConfig, deviceConfig)
-
-    def configure(self, imageConfig, _):
+        self.configure(vmConfig, imageConfig, deviceConfig)
+
+    def configure(self, vmConfig, imageConfig, _):
         """Config actions common to all unix-like domains."""
-
-        def get_cfg(name, default = None):
-            return sxp.child_value(imageConfig, name, default)
-
-        self.kernel = get_cfg("kernel")
-        self.cmdline = ""
-        ip = get_cfg("ip")
-        if ip:
-            self.cmdline += " ip=" + ip
-        root = get_cfg("root")
-        if root:
-            self.cmdline += " root=" + root
-        args = get_cfg("args")
-        if args:
-            self.cmdline += " " + args
-        self.ramdisk = get_cfg("ramdisk", '')
-        
+        self.kernel = vmConfig['kernel_kernel']
+        self.cmdline = vmConfig['kernel_args']
+        self.ramdisk = vmConfig['kernel_initrd']
         self.vm.storeVm(("image/ostype", self.ostype),
                         ("image/kernel", self.kernel),
                         ("image/cmdline", self.cmdline),
@@ -181,6 +166,10 @@ class ImageHandler:
         pass
 
 
+    def recreate(self):
+        pass
+
+
 class LinuxImageHandler(ImageHandler):
 
     ostype = "linux"
@@ -214,8 +203,8 @@ class PPC_LinuxImageHandler(LinuxImageHa
 
     ostype = "linux"
 
-    def configure(self, imageConfig, deviceConfig):
-        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
+    def configure(self, vmConfig, imageConfig, deviceConfig):
+        LinuxImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
         self.imageConfig = imageConfig
 
     def buildDomain(self):
@@ -248,37 +237,42 @@ class PPC_LinuxImageHandler(LinuxImageHa
 
 class HVMImageHandler(ImageHandler):
 
-    def __init__(self, vm, imageConfig, deviceConfig):
-        ImageHandler.__init__(self, vm, imageConfig, deviceConfig)
+    ostype = "hvm"
+
+    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
+        ImageHandler.__init__(self, vm, vmConfig, imageConfig, deviceConfig)
         self.shutdownWatch = None
-
-    def configure(self, imageConfig, deviceConfig):
-        ImageHandler.configure(self, imageConfig, deviceConfig)
+        self.rebootFeatureWatch = None
+
+    def configure(self, vmConfig, imageConfig, deviceConfig):
+        ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
 
         info = xc.xeninfo()
-        if not 'hvm' in info['xen_caps']:
+        if 'hvm' not in info['xen_caps']:
             raise VmError("HVM guest support is unavailable: is VT/AMD-V "
                           "supported by your CPU and enabled in your BIOS?")
 
         self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
-        self.device_model = sxp.child_value(imageConfig, 'device_model')
+        self.device_model = imageConfig['hvm'].get('device_model')
         if not self.device_model:
             raise VmError("hvm: missing device model")
-        self.display = sxp.child_value(imageConfig, 'display')
-        self.xauthority = sxp.child_value(imageConfig, 'xauthority')
-        self.vncconsole = sxp.child_value(imageConfig, 'vncconsole')
+        
+        self.display = imageConfig['hvm'].get('display')
+        self.xauthority = imageConfig['hvm'].get('xauthority')
+        self.vncconsole = imageConfig['hvm'].get('vncconsole')
 
         self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
                         ("image/device-model", self.device_model),
                         ("image/display", self.display))
 
-        self.pid = 0
+        self.pid = None
 
         self.dmargs += self.configVNC(imageConfig)
 
-        self.pae  = int(sxp.child_value(imageConfig, 'pae',  1))
-        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 1))
-        self.apic = int(sxp.child_value(imageConfig, 'apic', 1))
+        self.pae  = imageConfig['hvm'].get('pae', 0)
+        self.apic  = imageConfig['hvm'].get('apic', 0)
+        self.acpi  = imageConfig['hvm']['devices'].get('acpi', 0)
+        
 
     def buildDomain(self):
         store_evtchn = self.vm.getStorePort()
@@ -295,6 +289,7 @@ class HVMImageHandler(ImageHandler):
         log.debug("apic           = %d", self.apic)
 
         self.register_shutdown_watch()
+        self.register_reboot_feature_watch()
 
         return xc.hvm_build(domid          = self.vm.getDomid(),
                             image          = self.kernel,
@@ -312,8 +307,10 @@ class HVMImageHandler(ImageHandler):
                    'localtime', 'serial', 'stdvga', 'isa', 'vcpus',
                    'acpi', 'usb', 'usbdevice', 'keymap' ]
         ret = []
+        hvmDeviceConfig = imageConfig['hvm']['devices']
+        
         for a in dmargs:
-            v = sxp.child_value(imageConfig, a)
+            v = hvmDeviceConfig.get(a)
 
             # python doesn't allow '-' in variable names
             if a == 'stdvga': a = 'std-vga'
@@ -328,7 +325,7 @@ class HVMImageHandler(ImageHandler):
                     ret.append("-%s" % a)
                     ret.append("%s" % v)
 
-            if a in ['fda', 'fdb' ]:
+            if a in ['fda', 'fdb']:
                 if v:
                     if not os.path.isabs(v):
                         raise VmError("Floppy file %s does not exist." % v)
@@ -336,26 +333,27 @@ class HVMImageHandler(ImageHandler):
 
         # Handle disk/network related options
         mac = None
-        ret = ret + ["-domain-name", "%s" % self.vm.info['name']]
+        ret = ret + ["-domain-name", str(self.vm.info['name_label'])]
         nics = 0
-        for (name, info) in deviceConfig:
-            if name == 'vbd':
-                uname = sxp.child_value(info, 'uname')
+        
+        for devuuid, (devtype, devinfo) in deviceConfig.items():
+            if devtype == 'vbd':
+                uname = devinfo['uname']
                 if uname is not None and 'file:' in uname:
                     (_, vbdparam) = string.split(uname, ':', 1)
                     if not os.path.isfile(vbdparam):
                         raise VmError('Disk image does not exist: %s' %
                                       vbdparam)
-            if name == 'vif':
-                type = sxp.child_value(info, 'type')
-                if type != 'ioemu':
+            if devtype == 'vif':
+                dtype = devinfo.get('type', 'ioemu')
+                if dtype != 'ioemu':
                     continue
                 nics += 1
-                mac = sxp.child_value(info, 'mac')
+                mac = devinfo.get('mac')
                 if mac == None:
                     mac = randomMAC()
-                bridge = sxp.child_value(info, 'bridge', 'xenbr0')
-                model = sxp.child_value(info, 'model', 'rtl8139')
+                bridge = devinfo.get('bridge', 'xenbr0')
+                model = devinfo.get('model', 'rtl8139')
                 ret.append("-net")
                 ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
                            (nics, mac, model))
@@ -363,31 +361,32 @@ class HVMImageHandler(ImageHandler):
                 ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
         return ret
 
-    def configVNC(self, config):
+    def configVNC(self, imageConfig):
         # Handle graphics library related options
-        vnc = sxp.child_value(config, 'vnc')
-        sdl = sxp.child_value(config, 'sdl')
+        vnc = imageConfig.get('vnc')
+        sdl = imageConfig.get('sdl')
         ret = []
-        nographic = sxp.child_value(config, 'nographic')
+        nographic = imageConfig.get('nographic')
 
         # get password from VM config (if password omitted, None)
-        vncpasswd_vmconfig = sxp.child_value(config, 'vncpasswd')
+        vncpasswd_vmconfig = imageConfig.get('vncpasswd')
 
         if nographic:
             ret.append('-nographic')
             return ret
 
         if vnc:
-            vncdisplay = int(sxp.child_value(config, 'vncdisplay',
-                                             self.vm.getDomid()))
-
-            vncunused = sxp.child_value(config, 'vncunused')
+            vncdisplay = imageConfig.get('vncdisplay',
+                                         int(self.vm.getDomid()))
+            vncunused = imageConfig.get('vncunused')
+
             if vncunused:
                 ret += ['-vncunused']
             else:
                 ret += ['-vnc', '%d' % vncdisplay]
 
-            vnclisten = sxp.child_value(config, 'vnclisten')
+            vnclisten = imageConfig.get('vnclisten')
+
             if not(vnclisten):
                 vnclisten = (xen.xend.XendRoot.instance().
                              get_vnclisten_address())
@@ -423,21 +422,37 @@ class HVMImageHandler(ImageHandler):
         if self.vncconsole:
             args = args + ([ "-vncviewer" ])
         log.info("spawning device models: %s %s", self.device_model, args)
+        # keep track of pid and spawned options to kill it later
         self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
+        self.vm.storeDom("image/device-model-pid", self.pid)
         log.info("device model pid: %d", self.pid)
 
+    def recreate(self):
+        self.register_shutdown_watch()
+        self.register_reboot_feature_watch()
+        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
+
     def destroy(self):
-        self.unregister_shutdown_watch();
-        if not self.pid:
-            return
-        os.kill(self.pid, signal.SIGKILL)
-        os.waitpid(self.pid, 0)
-        self.pid = 0
+        self.unregister_shutdown_watch()
+        self.unregister_reboot_feature_watch();
+        if self.pid:
+            try:
+                os.kill(self.pid, signal.SIGKILL)
+            except OSError, exn:
+                log.exception(exn)
+            try:
+                os.waitpid(self.pid, 0)
+            except OSError, exn:
+                # This is expected if Xend has been restarted within the
+                # life of this domain.  In this case, we can kill the process,
+                # but we can't wait for it because it's not our child.
+                pass
+            self.pid = None
 
     def register_shutdown_watch(self):
         """ add xen store watch on control/shutdown """
-        self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \
-                                    self.hvm_shutdown)
+        self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown",
+                                     self.hvm_shutdown)
         log.debug("hvm shutdown watch registered")
 
     def unregister_shutdown_watch(self):
@@ -456,27 +471,54 @@ class HVMImageHandler(ImageHandler):
         """ watch call back on node control/shutdown,
             if node changed, this function will be called
         """
-        from xen.xend.XendConstants import DOMAIN_SHUTDOWN_REASONS
         xd = xen.xend.XendDomain.instance()
         try:
             vm = xd.domain_lookup( self.vm.getDomid() )
         except XendError:
             # domain isn't registered, no need to clean it up.
-            return
+            return False
 
         reason = vm.getShutdownReason()
         log.debug("hvm_shutdown fired, shutdown reason=%s", reason)
-        for x in DOMAIN_SHUTDOWN_REASONS.keys():
-            if DOMAIN_SHUTDOWN_REASONS[x] == reason:
-                vm.info['shutdown'] = 1
-                vm.info['shutdown_reason'] = x
-                vm.refreshShutdown(vm.info)
-
-        return 1 # Keep watching
+        if reason in REVERSE_DOMAIN_SHUTDOWN_REASONS:
+            vm.info['shutdown'] = 1
+            vm.info['shutdown_reason'] = \
+                REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
+            vm.refreshShutdown(vm.info)
+
+        return True # Keep watching
+
+    def register_reboot_feature_watch(self):
+        """ add xen store watch on control/feature-reboot """
+        self.rebootFeatureWatch = xswatch(self.vm.dompath + 
"/control/feature-reboot", \
+                                         self.hvm_reboot_feature)
+        log.debug("hvm reboot feature watch registered")
+
+    def unregister_reboot_feature_watch(self):
+        """Remove the watch on the control/feature-reboot, if any. Nothrow
+        guarantee."""
+
+        try:
+            if self.rebootFeatureWatch:
+                self.rebootFeatureWatch.unwatch()
+        except:
+            log.exception("Unwatching hvm reboot feature watch failed.")
+        self.rebootFeatureWatch = None
+        log.debug("hvm reboot feature watch unregistered")
+
+    def hvm_reboot_feature(self, _):
+        """ watch call back on node control/feature-reboot,
+            if node changed, this function will be called
+        """
+        status = self.vm.readDom('control/feature-reboot')
+        log.debug("hvm_reboot_feature fired, module status=%s", status)
+        if status == '1':
+            self.unregister_shutdown_watch()
+
+        return True # Keep watching
+
 
 class IA64_HVM_ImageHandler(HVMImageHandler):
-
-    ostype = "hvm"
 
     def getRequiredAvailableMemory(self, mem_kb):
         page_kb = 16
@@ -489,8 +531,6 @@ class IA64_HVM_ImageHandler(HVMImageHand
         return 0
 
 class X86_HVM_ImageHandler(HVMImageHandler):
-
-    ostype = "hvm"
 
     def getRequiredAvailableMemory(self, mem_kb):
         # Add 8 MiB overhead for QEMU's video RAM.
@@ -529,10 +569,10 @@ def findImageHandlerClass(image):
     @param image config
     @return ImageHandler subclass or None
     """
-    type = sxp.name(image)
-    if type is None:
+    image_type = image['type']
+    if image_type is None:
         raise VmError('missing image type')
     try:
-        return _handlers[arch.type][type]
+        return _handlers[arch.type][image_type]
     except KeyError:
-        raise VmError('unknown image type: ' + type)
+        raise VmError('unknown image type: ' + image_type)
diff -r 6fdbf173142d -r d603aed5ad6d 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Sat Dec 02 15:19:50 
2006 -0700
+++ b/tools/python/xen/xend/server/DevController.py     Mon Dec 04 08:24:41 
2006 -0700
@@ -17,6 +17,7 @@
 #============================================================================
 
 from threading import Event
+import types
 
 from xen.xend import sxp
 from xen.xend.XendError import VmError
@@ -86,7 +87,7 @@ class DevController:
 
         import xen.xend.XendDomain
         xd = xen.xend.XendDomain.instance()
-        backdom_name = sxp.child_value(config, 'backend')
+        backdom_name = config.get('backend')
         if backdom_name is None:
             backdom = xen.xend.XendDomain.DOM0_ID
         else:
@@ -223,7 +224,7 @@ class DevController:
         configDict = self.getDeviceConfiguration(devid)
         sxpr = [self.deviceClass]
         for key, val in configDict.items():
-            if type(val) == type(list()):
+            if isinstance(val, (types.ListType, types.TupleType)):
                 for v in val:
                     sxpr.append([key, v])
             else:
@@ -405,7 +406,7 @@ class DevController:
         import xen.xend.XendDomain
         xd = xen.xend.XendDomain.instance()
 
-        backdom_name = sxp.child_value(config, 'backend')
+        backdom_name = config.get('backend')
         if backdom_name:
             backdom = xd.domain_lookup_nr(backdom_name)
         else:
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/SrvDaemon.py Mon Dec 04 08:24:41 2006 -0700
@@ -21,6 +21,7 @@ import xen.lowlevel.xc
 
 from xen.xend.XendLogging import log
 from xen.xend import osdep
+from xen.util import mkdir
 
 import relocate
 import SrvServer
@@ -108,8 +109,7 @@ class Daemon:
         # so _before_ we close stderr.
         try:
             parent = os.path.dirname(XEND_DEBUG_LOG)
-            if not os.path.exists(parent):
-                os.makedirs(parent, stat.S_IRWXU)
+            mkdir.parents(parent, stat.S_IRWXU)
             fd = os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND)
         except Exception, exn:
             print >>sys.stderr, exn
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/SrvServer.py Mon Dec 04 08:24:41 2006 -0700
@@ -154,7 +154,7 @@ def create():
     if api_cfg:
         try:
             addrs = [(str(x[0]).split(':'),
-                      len(x) > 1 and x[1] or XendAPI.AUTH_NONE,
+                      len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
                       len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
                       or None)
                      for x in api_cfg]
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/blkif.py     Mon Dec 04 08:24:41 2006 -0700
@@ -21,7 +21,6 @@ import string
 
 from xen.util import blkif
 from xen.util import security
-from xen.xend import sxp
 from xen.xend.XendError import VmError
 from xen.xend.server.DevController import DevController
 
@@ -37,9 +36,9 @@ class BlkifController(DevController):
 
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
-        uname = sxp.child_value(config, 'uname', '')
-        dev = sxp.child_value(config, 'dev', '')
-
+        uname = config.get('uname', '')
+        dev = config.get('dev', '')
+        
         if 'ioemu:' in dev:
             (_, dev) = string.split(dev, ':', 1)
         try:
@@ -59,17 +58,17 @@ class BlkifController(DevController):
             except ValueError:
                 (typ, params) = ("", "")
 
-        mode = sxp.child_value(config, 'mode', 'r')
+        mode = config.get('mode', 'r')
         if mode not in ('r', 'w', 'w!'):
             raise VmError('Invalid mode')
 
-        back = { 'dev'    : dev,
-                 'type'   : typ,
-                 'params' : params,
-                 'mode'   : mode
-               }
+        back = {'dev'    : dev,
+                'type'   : typ,
+                'params' : params,
+                'mode'   : mode,
+                }
 
-        uuid = sxp.child_value(config, 'uuid')
+        uuid = config.get('uuid')
         if uuid:
             back['uuid'] = uuid
 
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/iopif.py
--- a/tools/python/xen/xend/server/iopif.py     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/iopif.py     Mon Dec 04 08:24:41 2006 -0700
@@ -22,7 +22,6 @@ import types
 
 import xen.lowlevel.xc
 
-from xen.xend import sxp
 from xen.xend.XendError import VmError
 
 from xen.xend.server.DevController import DevController
@@ -49,13 +48,12 @@ class IOPortsController(DevController):
     def __init__(self, vm):
         DevController.__init__(self, vm)
 
-
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
 
         def get_param(field):
             try:
-                val = sxp.child_value(config, field)
+                val = config.get(field)
 
                 if not val:
                     raise VmError('ioports: Missing %s config setting' % field)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/irqif.py
--- a/tools/python/xen/xend/server/irqif.py     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/irqif.py     Mon Dec 04 08:24:41 2006 -0700
@@ -45,7 +45,7 @@ class IRQController(DevController):
 
         def get_param(field):
             try:
-                val = sxp.child_value(config, field)
+                val = config.get(field)
 
                 if not val:
                     raise VmError('irq: Missing %s config setting' % field)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/netif.py     Mon Dec 04 08:24:41 2006 -0700
@@ -24,7 +24,6 @@ import random
 import random
 import re
 
-from xen.xend import sxp
 from xen.xend import XendRoot
 from xen.xend.server.DevController import DevController
 
@@ -139,22 +138,15 @@ class NetifController(DevController):
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
 
-        def _get_config_ipaddr(config):
-            val = []
-            for ipaddr in sxp.children(config, elt='ip'):
-                val.append(sxp.child0(ipaddr))
-            return val
-
         script = os.path.join(xroot.network_script_dir,
-                              sxp.child_value(config, 'script',
-                                              xroot.get_vif_script()))
-        typ = sxp.child_value(config, 'type')
-        bridge  = sxp.child_value(config, 'bridge')
-        mac     = sxp.child_value(config, 'mac')
-        vifname = sxp.child_value(config, 'vifname')
-        rate    = sxp.child_value(config, 'rate')
-        uuid    = sxp.child_value(config, 'uuid')
-        ipaddr  = _get_config_ipaddr(config)
+                              config.get('script', xroot.get_vif_script()))
+        typ = config.get('type')
+        bridge  = config.get('bridge')
+        mac     = config.get('mac')
+        vifname = config.get('vifname')
+        rate    = config.get('rate')
+        uuid    = config.get('uuid')
+        ipaddr  = config.get('ip')
 
         devid = self.allocateDeviceID()
 
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/pciif.py     Mon Dec 04 08:24:41 2006 -0700
@@ -53,60 +53,29 @@ class PciController(DevController):
 
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
-        #log.debug('pci config='+sxp.to_string(config))
-
-        def get_param(config, field, default=None):
+        def parse_hex(val):
             try:
-                val = sxp.child_value(config, field)
-
-                if not val:
-                    if default==None:
-                        raise VmError('pci: Missing %s config setting' % field)
-                    else:
-                        return default
-
                 if isinstance(val, types.StringTypes):
                     return int(val, 16)
                 else:
                     return val
-            except:
-                if default==None:
-                    raise VmError('pci: Invalid config setting %s: %s' %
-                              (field, val))
-                else:
-                    return default
-        
+            except ValueError:
+                return None
+            
         back = {}
+        pcidevid = 0
+        for pci_config in config.get('devs', []):
+            domain = parse_hex(pci_config.get('domain', 0))
+            bus = parse_hex(pci_config.get('bus', 0))
+            slot = parse_hex(pci_config.get('slot', 0))
+            func = parse_hex(pci_config.get('func', 0))            
+            self.setupDevice(domain, bus, slot, func)
+            back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \
+                                        (domain, bus, slot, func)
+            pcidevid += 1
 
-        val = sxp.child_value(config, 'dev')
-        if isinstance(val, (types.ListType, types.TupleType)):
-            pcidevid = 0
-            for dev_config in sxp.children(config, 'dev'):
-                domain = get_param(dev_config, 'domain', 0)
-                bus = get_param(dev_config,'bus')
-                slot = get_param(dev_config,'slot')
-                func = get_param(dev_config,'func')
-
-                self.setupDevice(domain, bus, slot, func)
-
-                back['dev-%i' % pcidevid]="%04x:%02x:%02x.%02x"% \
-                        (domain, bus, slot, func)
-                pcidevid+=1
-            
-            back['num_devs']=str(pcidevid)
-
-        else:
-            # Xen 2.0 configuration compatibility
-            domain = get_param(config, 'domain', 0)
-            bus  = get_param(config, 'bus')
-            slot = get_param(config, 'dev')
-            func = get_param(config, 'func')
-
-            self.setupDevice(domain, bus, slot, func)
-
-            back['dev-0']="%04x:%02x:%02x.%02x"%(domain, bus, slot, func)
-            back['num_devs']=str(1)
-
+        back['num_devs']=str(pcidevid)
+        back['uuid'] = config.get('uuid','')
         return (0, back, {})
 
     def getDeviceConfiguration(self, devid):
@@ -129,7 +98,8 @@ class PciController(DevController):
                                  'slot': '0x%(slot)s' % pci_dev_info,
                                  'func': '0x%(func)s' % pci_dev_info})
 
-        result['dev'] = pci_devs
+        result['devs'] = pci_devs
+        result['uuid'] = self.readBackend(devid, 'uuid')
         return result
 
     def configuration(self, devid):
@@ -142,7 +112,8 @@ class PciController(DevController):
         sxpr = [self.deviceClass]
 
         # remove devs
-        devs = configDict.pop('dev', [])
+        devs = configDict.pop('devs', [])
+        
         for dev in devs:
             dev_sxpr = ['dev']
             for dev_item in dev.items():
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/pciquirk.py
--- a/tools/python/xen/xend/server/pciquirk.py  Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/pciquirk.py  Mon Dec 04 08:24:41 2006 -0700
@@ -15,25 +15,24 @@ class PCIQuirk:
         self.device = device
         self.subvendor = subvendor
         self.subdevice = subdevice
-       self.domain = domain
-       self.bus = bus
-       self.slot = slot
-       self.func = func
+        self.domain = domain
+        self.bus = bus
+        self.slot = slot
+        self.func = func
 
         self.devid = "%04x:%04x:%04x:%04x" % (vendor, device, subvendor, 
subdevice)
-       self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
+        self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
+        self.quirks = self.__getQuirksByID()
 
-        self.quirks = self.__getQuirksByID( )
-
-       self.__sendQuirks( )
-       self.__sendPermDevs( )
+        self.__sendQuirks()
+        self.__sendPermDevs()
 
     def __matchPCIdev( self, list ):
         ret = False
         if list == None:
             return False
         for id in list:
-            if id.startswith( self.devid[:9] ): # id's vendor and device ID 
match
+            if id.startswith(self.devid[:9]): # id's vendor and device ID match
                 skey = id.split(':')
                 size = len(skey)
                 if (size == 2):                # subvendor/subdevice not 
suplied
@@ -41,13 +40,13 @@ class PCIQuirk:
                     break
                 elif (size == 4):      # check subvendor/subdevice
                     # check subvendor
-                   subven = '%04x' % self.subvendor
+                    subven = '%04x' % self.subvendor
                     if ((skey[2] != 'FFFF') and 
                         (skey[2] != 'ffff') and 
                         (skey[2] != subven)):
                             continue
                     # check subdevice
-                   subdev = '%04x' % self.subdevice
+                    subdev = '%04x' % self.subdevice
                     if ((skey[3] != 'FFFF') and 
                         (skey[3] != 'ffff') and 
                         (skey[3] != subdev)):
@@ -101,8 +100,8 @@ class PCIQuirk:
                        self.slot, self.func, quirk) )
                 f.close()
             except Exception, e:
-                raise VmError("pci: failed to open/write/close quirks sysfs " 
+ \
-                       "node - " + str(e))
+                raise VmError("pci: failed to open/write/close quirks " +
+                              "sysfs node - " + str(e))
 
     def __devIsUnconstrained( self ):
         if os.path.exists(PERMISSIVE_CONFIG_FILE):
@@ -126,20 +125,22 @@ class PCIQuirk:
 
         devices = child_at(child(pci_perm_dev_config, 
'unconstrained_dev_ids'),0)
        if self.__matchPCIdev( devices ):
-            log.debug("Permissive mode enabled for PCI device [%s]" % 
self.devid)
+            log.debug("Permissive mode enabled for PCI device [%s]" %
+                      self.devid)
             return True
-        log.debug("Permissive mode NOT enabled for PCI device [%s]" % 
self.devid)
+        log.debug("Permissive mode NOT enabled for PCI device [%s]" %
+                  self.devid)
         return False
 
     def __sendPermDevs(self):
        if self.__devIsUnconstrained( ):
-            log.debug("Unconstrained device: %04x:%02x:%02x.%1x" % 
(self.domain,
-                   self.bus, self.slot, self.func))
+            log.debug("Unconstrained device: %04x:%02x:%02x.%1x" %
+                      (self.domain, self.bus, self.slot, self.func))
             try:
                 f = file(PERMISSIVE_SYSFS_NODE ,"w")
                 f.write( "%04x:%02x:%02x.%1x" % (self.domain, self.bus,
-                       self.slot, self.func) )
+                                                 self.slot, self.func))
                 f.close()
             except Exception, e:
-                raise VmError("pci: failed to open/write/close permissive " + \
-               "sysfs node: " + str(e))
+                raise VmError("pci: failed to open/write/close permissive " +
+                              "sysfs node: " + str(e))
diff -r 6fdbf173142d -r d603aed5ad6d 
tools/python/xen/xend/server/tests/test_controllers.py
--- a/tools/python/xen/xend/server/tests/test_controllers.py    Sat Dec 02 
15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/tests/test_controllers.py    Mon Dec 04 
08:24:41 2006 -0700
@@ -21,11 +21,11 @@ class test_controllers(unittest.TestCase
     def testNetif(self):
         controller = self.controllerInstance(netif.NetifController)
 
-        self.assertNetif(controller.getDeviceDetails(['vif']), None)
+        self.assertNetif(controller.getDeviceDetails({}), None)
         self.assertNetif(
-            controller.getDeviceDetails(
-            ['vif', ['mac', 'aa:bb:cc:dd:ee:ff']]),
+            controller.getDeviceDetails({'mac': 'aa:bb:cc:dd:ee:ff'}),
             'aa:bb:cc:dd:ee:ff')
+
 
 
     def assertNetif(self, results, expectedMac):
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/tpmif.py     Mon Dec 04 08:24:41 2006 -0700
@@ -18,10 +18,8 @@
 # Copyright (C) 2005 XenSource Ltd
 #============================================================================
 
-"""Support for virtual TPM interfaces.
-"""
+"""Support for virtual TPM interfaces."""
 
-from xen.xend import sxp
 from xen.xend import XendRoot
 from xen.xend.XendLogging import log
 from xen.xend.XendError import XendError
@@ -49,12 +47,12 @@ class TPMifController(DevController):
         """@see DevController.getDeviceDetails"""
 
         devid = self.allocateDeviceID()
-        inst = int(sxp.child_value(config, 'pref_instance', '-1'))
+        inst = int(config.get('pref_instance', -1))
         if inst == -1:
-            inst = int(sxp.child_value(config, 'instance' , '0'))
+            inst = int(config.get('instance', 0))
 
-        typ    = sxp.child_value(config, 'type')
-        uuid   = sxp.child_value(config, 'uuid')
+        typ    = config.get('type')
+        uuid   = config.get('uuid')
 
         log.info("The domain has a TPM with pref. instance %d and devid %d.",
                  inst, devid)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xm/create.py     Mon Dec 04 08:24:41 2006 -0700
@@ -284,6 +284,18 @@ gopts.var('usbport', val='PATH',
           use="""Add a physical USB port to a domain, as specified by the path
           to that port.  This option may be repeated to add more than one 
port.""")
 
+gopts.var('vfb', 
val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY",
+          fn=append_value, default=[],
+          use="""Make the domain a framebuffer backend.
+          The backend type should be either sdl or vnc.
+          For type=vnc, connect an external vncviewer.  The server will listen
+          on ADDR (default 127.0.0.1) on port N+5900.  N defaults to the
+          domain id.  If vncunused=1, the server will try to find an arbitrary
+          unused port above 5900.
+          For type=sdl, a viewer will be started automatically using the
+          given DISPLAY and XAUTHORITY, which default to the current user's
+          ones.""")
+
 gopts.var('vif', 
val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT,backend=DOM,vifname=NAME",
           fn=append_value, default=[],
           use="""Add a network interface with the given MAC address and bridge.
@@ -512,8 +524,8 @@ def configure_image(vals):
         config_image.append(['args', vals.extra])
 
     if vals.builder == 'hvm':
-        configure_hvm(config_image, vals)
-        
+        configure_hvm(config_image, vals) 
+       
     return config_image
     
 def configure_disks(config_devs, vals):
@@ -564,6 +576,23 @@ def configure_usb(config_devs, vals):
         config_usb = ['usbport', ['path', path]]
         config_devs.append(['device', config_usb])
 
+def configure_vfbs(config_devs, vals):
+    for f in vals.vfb:
+        d = comma_sep_kv_to_dict(f)
+        config = ['vfb']
+        if not d.has_key("type"):
+            d['type'] = 'sdl'
+        for (k,v) in d.iteritems():
+            if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
+                          'xauthority', 'type' ]:
+                err("configuration option %s unknown to vfbs" % k)
+            config.append([k,v])
+        if not d.has_key("display") and os.environ.has_key("DISPLAY"):
+            config.append(["display", os.environ['DISPLAY']])
+        if not d.has_key("xauthority"):
+            config.append(["xauthority", get_xauthority()])
+        config_devs.append(['device', ['vkbd']])
+        config_devs.append(['device', config])
 
 def configure_security(config, vals):
     """Create the config for ACM security labels.
@@ -742,6 +771,7 @@ def make_config(vals):
     configure_vifs(config_devs, vals)
     configure_usb(config_devs, vals)
     configure_vtpm(config_devs, vals)
+    configure_vfbs(config_devs, vals)
     configure_security(config, vals)
     config += config_devs
 
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xm/main.py       Mon Dec 04 08:24:41 2006 -0700
@@ -581,8 +581,8 @@ def parse_doms_info(info):
     return {
         'domid'    : get_info('domid',        str,   ''),
         'name'     : get_info('name',         str,   '??'),
-        'mem'      : get_info('memory_dynamic_max', int,   0),
-        'vcpus'    : get_info('online_vcpus', int,   0),
+        'mem'      : get_info('memory_dynamic_min', int,   0),
+        'vcpus'    : get_info('vcpus',        int,   0),
         'state'    : get_info('state',        str,    ''),
         'cpu_time' : get_info('cpu_time',     float, 0),
         'up_time'  : get_info('up_time',      float, -1),
diff -r 6fdbf173142d -r d603aed5ad6d tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c   Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/tests/test_x86_emulator.c   Mon Dec 04 08:24:41 2006 -0700
@@ -17,12 +17,14 @@ typedef int64_t            s64;
 
 #define PFEC_write_access (1U<<1)
 
-static int read_any(
-    unsigned long addr,
+static int read(
+    unsigned int seg,
+    unsigned long offset,
     unsigned long *val,
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt)
 {
+    unsigned long addr = offset;
     switch ( bytes )
     {
     case 1: *val = *(u8 *)addr; break;
@@ -33,12 +35,14 @@ static int read_any(
     return X86EMUL_CONTINUE;
 }
 
-static int write_any(
-    unsigned long addr,
+static int write(
+    unsigned int seg,
+    unsigned long offset,
     unsigned long val,
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt)
 {
+    unsigned long addr = offset;
     switch ( bytes )
     {
     case 1: *(u8 *)addr = (u8)val; break;
@@ -49,13 +53,15 @@ static int write_any(
     return X86EMUL_CONTINUE;
 }
 
-static int cmpxchg_any(
-    unsigned long addr,
+static int cmpxchg(
+    unsigned int seg,
+    unsigned long offset,
     unsigned long old,
     unsigned long new,
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt)
 {
+    unsigned long addr = offset;
     switch ( bytes )
     {
     case 1: *(u8 *)addr = (u8)new; break;
@@ -66,21 +72,27 @@ static int cmpxchg_any(
     return X86EMUL_CONTINUE;
 }
 
-static int cmpxchg8b_any(
-    unsigned long addr,
+static int cmpxchg8b(
+    unsigned int seg,
+    unsigned long offset,
     unsigned long old_lo,
     unsigned long old_hi,
     unsigned long new_lo,
     unsigned long new_hi,
     struct x86_emulate_ctxt *ctxt)
 {
+    unsigned long addr = offset;
     ((unsigned long *)addr)[0] = new_lo;
     ((unsigned long *)addr)[1] = new_hi;
     return X86EMUL_CONTINUE;
 }
 
 static struct x86_emulate_ops emulops = {
-    read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any
+    .read       = read,
+    .insn_fetch = read,
+    .write      = write,
+    .cmpxchg    = cmpxchg,
+    .cmpxchg8b  = cmpxchg8b
 };
 
 int main(int argc, char **argv)
@@ -108,7 +120,7 @@ int main(int argc, char **argv)
     regs.eip    = (unsigned long)&instr[0];
     regs.ecx    = 0x12345678;
     regs.error_code = PFEC_write_access;
-    ctxt.cr2    = (unsigned long)res;
+    regs.eax    = (unsigned long)res;
     *res        = 0x7FFFFFFF;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -127,7 +139,7 @@ int main(int argc, char **argv)
 #else
     regs.ecx    = 0x12345678UL;
 #endif
-    ctxt.cr2    = (unsigned long)res;
+    regs.eax    = (unsigned long)res;
     regs.error_code = 0;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -142,7 +154,7 @@ int main(int argc, char **argv)
     regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.ecx    = ~0UL;
-    ctxt.cr2    = (unsigned long)res;
+    regs.eax    = (unsigned long)res;
     regs.error_code = 0;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -152,13 +164,13 @@ int main(int argc, char **argv)
         goto fail;
     printf("okay\n");
 
-    printf("%-40s", "Testing lock cmpxchgb %%cl,(%%eax)...");
-    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x08;
+    printf("%-40s", "Testing lock cmpxchgb %%cl,(%%ebx)...");
+    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x0b;
     regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.eax    = 0x92345677UL;
     regs.ecx    = 0xAA;
-    ctxt.cr2    = (unsigned long)res;
+    regs.ebx    = (unsigned long)res;
     regs.error_code = PFEC_write_access;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -169,13 +181,13 @@ int main(int argc, char **argv)
         goto fail;
     printf("okay\n");
 
-    printf("%-40s", "Testing lock cmpxchgb %%cl,(%%eax)...");
-    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x08;
+    printf("%-40s", "Testing lock cmpxchgb %%cl,(%%ebx)...");
+    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x0b;
     regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.eax    = 0xAABBCC77UL;
     regs.ecx    = 0xFF;
-    ctxt.cr2    = (unsigned long)res;
+    regs.ebx    = (unsigned long)res;
     regs.error_code = PFEC_write_access;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -192,7 +204,7 @@ int main(int argc, char **argv)
     regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.ecx    = 0x12345678;
-    ctxt.cr2    = (unsigned long)res;
+    regs.eax    = (unsigned long)res;
     regs.error_code = PFEC_write_access;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -203,14 +215,14 @@ int main(int argc, char **argv)
         goto fail;
     printf("okay\n");
 
-    printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%eax)...");
-    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x08;
+    printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%ebx)...");
+    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x0b;
     regs.eflags = 0x200;
     *res        = 0x923456AA;
     regs.eip    = (unsigned long)&instr[0];
     regs.eax    = 0x923456AAUL;
     regs.ecx    = 0xDDEEFF00L;
-    ctxt.cr2    = (unsigned long)res;
+    regs.ebx    = (unsigned long)res;
     regs.error_code = PFEC_write_access;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -230,7 +242,6 @@ int main(int argc, char **argv)
     regs.esi    = (unsigned long)res + 0;
     regs.edi    = (unsigned long)res + 2;
     regs.error_code = 0; /* read fault */
-    ctxt.cr2    = regs.esi;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
          (*res != 0x44554455) ||
@@ -248,13 +259,28 @@ int main(int argc, char **argv)
     regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.edi    = (unsigned long)res;
-    ctxt.cr2    = regs.edi;
     regs.error_code = PFEC_write_access;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
          (*res != 0x2233445D) ||
          ((regs.eflags&0x201) != 0x201) ||
          (regs.eip != (unsigned long)&instr[4]) )
+        goto fail;
+    printf("okay\n");
+
+    printf("%-40s", "Testing btrl %eax,(%edi)...");
+    instr[0] = 0x0f; instr[1] = 0xb3; instr[2] = 0x07;
+    *res        = 0x2233445F;
+    regs.eflags = 0x200;
+    regs.eip    = (unsigned long)&instr[0];
+    regs.eax    = -32;
+    regs.edi    = (unsigned long)(res+1);
+    regs.error_code = PFEC_write_access;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0x2233445E) ||
+         ((regs.eflags&0x201) != 0x201) ||
+         (regs.eip != (unsigned long)&instr[3]) )
         goto fail;
     printf("okay\n");
 
@@ -270,7 +296,6 @@ int main(int argc, char **argv)
     regs.ecx    = 0xCCCCFFFF;
     regs.eip    = (unsigned long)&instr[0];
     regs.edi    = (unsigned long)res;
-    ctxt.cr2    = regs.edi;
     regs.error_code = PFEC_write_access;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -283,9 +308,9 @@ int main(int argc, char **argv)
 
     printf("%-40s", "Testing cmpxchg8b (%edi) [failing]...");
     instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
+    regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.edi    = (unsigned long)res;
-    ctxt.cr2    = regs.edi;
     regs.error_code = PFEC_write_access;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
@@ -300,9 +325,10 @@ int main(int argc, char **argv)
 
     printf("%-40s", "Testing movsxbd (%%eax),%%ecx...");
     instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08;
-    regs.eip    = (unsigned long)&instr[0];
-    regs.ecx    = 0x12345678;
-    ctxt.cr2    = (unsigned long)res;
+    regs.eflags = 0x200;
+    regs.eip    = (unsigned long)&instr[0];
+    regs.ecx    = 0x12345678;
+    regs.eax    = (unsigned long)res;
     *res        = 0x82;
     regs.error_code = 0;
     rc = x86_emulate_memop(&ctxt, &emulops);
@@ -316,9 +342,10 @@ int main(int argc, char **argv)
 
     printf("%-40s", "Testing movzxwd (%%eax),%%ecx...");
     instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08;
-    regs.eip    = (unsigned long)&instr[0];
-    regs.ecx    = 0x12345678;
-    ctxt.cr2    = (unsigned long)res;
+    regs.eflags = 0x200;
+    regs.eip    = (unsigned long)&instr[0];
+    regs.ecx    = 0x12345678;
+    regs.eax    = (unsigned long)res;
     *res        = 0x1234aa82;
     regs.error_code = 0;
     rc = x86_emulate_memop(&ctxt, &emulops);
@@ -330,6 +357,23 @@ int main(int argc, char **argv)
         goto fail;
     printf("okay\n");
 
+    printf("%-40s", "Testing xadd %%ax,(%%ecx)...");
+    instr[0] = 0x66; instr[1] = 0x0f; instr[2] = 0xc1; instr[3] = 0x01;
+    regs.eflags = 0x200;
+    regs.eip    = (unsigned long)&instr[0];
+    regs.ecx    = (unsigned long)res;
+    regs.eax    = 0x12345678;
+    *res        = 0x11111111;
+    regs.error_code = 0;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) ||
+         (*res != 0x11116789) ||
+         (regs.eax != 0x12341111) ||
+         ((regs.eflags&0x240) != 0x200) ||
+         (regs.eip != (unsigned long)&instr[4]) )
+        goto fail;
+    printf("okay\n");
+
     return 0;
 
  fail:
diff -r 6fdbf173142d -r d603aed5ad6d tools/xm-test/tests/vtpm/Makefile.am
--- a/tools/xm-test/tests/vtpm/Makefile.am      Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/xm-test/tests/vtpm/Makefile.am      Mon Dec 04 08:24:41 2006 -0700
@@ -7,7 +7,8 @@ TESTS = 01_vtpm-list_pos.test \
         05_vtpm-loc_migr.test \
         06_vtpm-susp_res_pcrs.test \
         07_vtpm-mig_pcrs.test \
-        08_vtpm-mig_pcrs.test
+        08_vtpm-mig_pcrs.test \
+        09_vtpm-xapi.test
 
 XFAIL_TESTS =
 
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/ia64/xen/Makefile
--- a/xen/arch/ia64/xen/Makefile        Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/ia64/xen/Makefile        Mon Dec 04 08:24:41 2006 -0700
@@ -1,5 +1,7 @@ subdir-y += oprofile
 subdir-y += oprofile
 
+obj-y += machine_kexec.o
+obj-y += crash.o
 obj-y += acpi.o
 obj-y += dom0_ops.o
 obj-y += domain.o
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/powerpc/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -40,6 +40,8 @@ obj-y += sysctl.o
 obj-y += sysctl.o
 obj-y += time.o
 obj-y += usercopy.o
+obj-y += machine_kexec.o
+obj-y += crash.o
 
 obj-$(debug) += 0opt.o
 obj-$(crash_debug) += gdbstub.o
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/Makefile     Mon Dec 04 08:24:41 2006 -0700
@@ -43,6 +43,8 @@ obj-y += traps.o
 obj-y += traps.o
 obj-y += usercopy.o
 obj-y += x86_emulate.o
+obj-y += machine_kexec.o
+obj-y += crash.o
 
 obj-$(crash_debug) += gdbstub.o
 
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/platform.c       Mon Dec 04 08:24:41 2006 -0700
@@ -920,7 +920,7 @@ void handle_mmio(unsigned long gpa)
     df = regs->eflags & X86_EFLAGS_DF ? 1 : 0;
 
     mode = hvm_guest_x86_mode(v);
-    inst_addr = hvm_get_segment_base(v, seg_cs) + regs->eip;
+    inst_addr = hvm_get_segment_base(v, x86_seg_cs) + regs->eip;
     inst_len = hvm_instruction_length(inst_addr, mode);
     if ( inst_len <= 0 )
     {
@@ -964,10 +964,10 @@ void handle_mmio(unsigned long gpa)
         addr = regs->edi;
         if ( ad_size == WORD )
             addr &= 0xFFFF;
-        addr += hvm_get_segment_base(v, seg_es);
+        addr += hvm_get_segment_base(v, x86_seg_es);
         if ( addr == gpa )
         {
-            enum segment seg;
+            enum x86_segment seg;
 
             dir = IOREQ_WRITE;
             addr = regs->esi;
@@ -975,13 +975,13 @@ void handle_mmio(unsigned long gpa)
                 addr &= 0xFFFF;
             switch ( seg_sel )
             {
-            case 0x26: seg = seg_es; break;
-            case 0x2e: seg = seg_cs; break;
-            case 0x36: seg = seg_ss; break;
+            case 0x26: seg = x86_seg_es; break;
+            case 0x2e: seg = x86_seg_cs; break;
+            case 0x36: seg = x86_seg_ss; break;
             case 0:
-            case 0x3e: seg = seg_ds; break;
-            case 0x64: seg = seg_fs; break;
-            case 0x65: seg = seg_gs; break;
+            case 0x3e: seg = x86_seg_ds; break;
+            case 0x64: seg = x86_seg_fs; break;
+            case 0x65: seg = x86_seg_gs; break;
             default: domain_crash_synchronous();
             }
             addr += hvm_get_segment_base(v, seg);
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c    Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/svm/emulate.c    Mon Dec 04 08:24:41 2006 -0700
@@ -128,17 +128,6 @@ static inline unsigned long DECODE_GPR_V
         return (unsigned long) -1; \
     }
 
-#if 0
-/*
- * hv_is_canonical - checks if the given address is canonical
- */
-static inline u64 hv_is_canonical(u64 addr)
-{
-    u64 bits = addr & (u64)0xffff800000000000;
-    return (u64)((bits == (u64)0xffff800000000000) || (bits == (u64)0x0));
-}
-#endif
-
 #define modrm operand [0]
 
 #define sib operand [1]
@@ -209,7 +198,7 @@ unsigned long get_effective_addr_modrm64
 
 #if __x86_64__
         /* 64-bit mode */
-        if (vmcb->cs.attributes.fields.l && (vmcb->efer & EFER_LMA))
+        if (vmcb->cs.attr.fields.l && (vmcb->efer & EFER_LMA))
             return vmcb->rip + inst_len + *size + disp;
 #endif
         return disp;
@@ -334,7 +323,7 @@ unsigned long svm_rip2pointer(struct vmc
      * no matter what kind of addressing is used.
      */
     unsigned long p = vmcb->cs.base + vmcb->rip;
-    if (!(vmcb->cs.attributes.fields.l && vmcb->efer & EFER_LMA))
+    if (!(vmcb->cs.attr.fields.l && vmcb->efer & EFER_LMA))
         return (u32)p; /* mask to 32 bits */
     /* NB. Should mask to 16 bits if in real mode or 16-bit protected mode. */
     return p;
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Dec 04 08:24:41 2006 -0700
@@ -269,13 +269,11 @@ static int svm_long_mode_enabled(struct 
     return test_bit(SVM_CPU_STATE_LMA_ENABLED, &v->arch.hvm_svm.cpu_state);
 }
 
-#define IS_CANO_ADDRESS(add) 1
-
 static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
 {
     u64 msr_content = 0;
-    struct vcpu *vc = current;
-    struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
+    struct vcpu *v = current;
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
     switch ((u32)regs->ecx)
     {
@@ -284,17 +282,25 @@ static inline int long_mode_do_msr_read(
         msr_content &= ~EFER_SVME;
         break;
 
+#ifdef __x86_64__
     case MSR_FS_BASE:
         msr_content = vmcb->fs.base;
-        break;
+        goto check_long_mode;
 
     case MSR_GS_BASE:
         msr_content = vmcb->gs.base;
-        break;
+        goto check_long_mode;
 
     case MSR_SHADOW_GS_BASE:
         msr_content = vmcb->kerngsbase;
-        break;
+    check_long_mode:
+        if ( !svm_long_mode_enabled(v) )
+        {
+            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+            return 0;
+        }
+        break;
+#endif
 
     case MSR_STAR:
         msr_content = vmcb->star;
@@ -326,25 +332,25 @@ static inline int long_mode_do_msr_write
 static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
     u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
+    u32 ecx = regs->ecx;
     struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
     HVM_DBG_LOG(DBG_LEVEL_1, "msr %x msr_content %"PRIx64"\n",
-                (u32)regs->ecx, msr_content);
-
-    switch ( (u32)regs->ecx )
+                ecx, msr_content);
+
+    switch ( ecx )
     {
     case MSR_EFER:
-#ifdef __x86_64__
         /* offending reserved bit will cause #GP */
         if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
         {
-            printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
-                   msr_content);
-            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
-            return 0;
-        }
-
+            gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
+                     "EFER: %"PRIx64"\n", msr_content);
+            goto gp_fault;
+        }
+
+#ifdef __x86_64__
         /* LME: 0 -> 1 */
         if ( msr_content & EFER_LME &&
              !test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state))
@@ -353,10 +359,9 @@ static inline int long_mode_do_msr_write
                  !test_bit(SVM_CPU_STATE_PAE_ENABLED,
                            &v->arch.hvm_svm.cpu_state) )
             {
-                printk("Trying to set LME bit when "
-                       "in paging mode or PAE bit is not set\n");
-                svm_inject_exception(v, TRAP_gp_fault, 1, 0);
-                return 0;
+                gdprintk(XENLOG_WARNING, "Trying to set LME bit when "
+                         "in paging mode or PAE bit is not set\n");
+                goto gp_fault;
             }
             set_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state);
         }
@@ -371,37 +376,38 @@ static inline int long_mode_do_msr_write
         vmcb->efer = msr_content | EFER_SVME;
         break;
 
+#ifdef __x86_64__
     case MSR_FS_BASE:
     case MSR_GS_BASE:
+    case MSR_SHADOW_GS_BASE:
         if ( !svm_long_mode_enabled(v) )
-            goto exit_and_crash;
-
-        if (!IS_CANO_ADDRESS(msr_content))
-        {
-            HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
-            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
-        }
-
-        if (regs->ecx == MSR_FS_BASE)
+            goto gp_fault;
+
+        if ( !is_canonical_address(msr_content) )
+            goto uncanonical_address;
+
+        if ( ecx == MSR_FS_BASE )
             vmcb->fs.base = msr_content;
-        else 
+        else if ( ecx == MSR_GS_BASE )
             vmcb->gs.base = msr_content;
-        break;
-
-    case MSR_SHADOW_GS_BASE:
-        vmcb->kerngsbase = msr_content;
-        break;
+        else
+            vmcb->kerngsbase = msr_content;
+        break;
+#endif
  
     case MSR_STAR:
         vmcb->star = msr_content;
         break;
  
     case MSR_LSTAR:
-        vmcb->lstar = msr_content;
-        break;
- 
     case MSR_CSTAR:
-        vmcb->cstar = msr_content;
+        if ( !is_canonical_address(msr_content) )
+            goto uncanonical_address;
+
+        if ( ecx == MSR_LSTAR )
+            vmcb->lstar = msr_content;
+        else
+            vmcb->cstar = msr_content;
         break;
  
     case MSR_SYSCALL_MASK:
@@ -414,10 +420,11 @@ static inline int long_mode_do_msr_write
 
     return 1;
 
- exit_and_crash:
-    gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
-    domain_crash(v->domain);
-    return 1; /* handled */
+ uncanonical_address:
+    HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
+ gp_fault:
+    svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+    return 0;
 }
 
 
@@ -476,13 +483,13 @@ static int svm_guest_x86_mode(struct vcp
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
     if ( vmcb->efer & EFER_LMA )
-        return (vmcb->cs.attributes.fields.l ?
+        return (vmcb->cs.attr.fields.l ?
                 X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32);
 
     if ( svm_realmode(v) )
         return X86EMUL_MODE_REAL;
 
-    return (vmcb->cs.attributes.fields.db ?
+    return (vmcb->cs.attr.fields.db ?
             X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16);
 }
 
@@ -509,29 +516,49 @@ unsigned long svm_get_ctrl_reg(struct vc
     return 0;                   /* dummy */
 }
 
-static unsigned long svm_get_segment_base(struct vcpu *v, enum segment seg)
+static unsigned long svm_get_segment_base(struct vcpu *v, enum x86_segment seg)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     int long_mode = 0;
 
 #ifdef __x86_64__
-    long_mode = vmcb->cs.attributes.fields.l && (vmcb->efer & EFER_LMA);
+    long_mode = vmcb->cs.attr.fields.l && (vmcb->efer & EFER_LMA);
 #endif
     switch ( seg )
     {
-    case seg_cs: return long_mode ? 0 : vmcb->cs.base;
-    case seg_ds: return long_mode ? 0 : vmcb->ds.base;
-    case seg_es: return long_mode ? 0 : vmcb->es.base;
-    case seg_fs: return vmcb->fs.base;
-    case seg_gs: return vmcb->gs.base;
-    case seg_ss: return long_mode ? 0 : vmcb->ss.base;
-    case seg_tr: return vmcb->tr.base;
-    case seg_gdtr: return vmcb->gdtr.base;
-    case seg_idtr: return vmcb->idtr.base;
-    case seg_ldtr: return vmcb->ldtr.base;
+    case x86_seg_cs: return long_mode ? 0 : vmcb->cs.base;
+    case x86_seg_ds: return long_mode ? 0 : vmcb->ds.base;
+    case x86_seg_es: return long_mode ? 0 : vmcb->es.base;
+    case x86_seg_fs: return vmcb->fs.base;
+    case x86_seg_gs: return vmcb->gs.base;
+    case x86_seg_ss: return long_mode ? 0 : vmcb->ss.base;
+    case x86_seg_tr: return vmcb->tr.base;
+    case x86_seg_gdtr: return vmcb->gdtr.base;
+    case x86_seg_idtr: return vmcb->idtr.base;
+    case x86_seg_ldtr: return vmcb->ldtr.base;
     }
     BUG();
     return 0;
+}
+
+static void svm_get_segment_register(struct vcpu *v, enum x86_segment seg,
+                                     struct segment_register *reg)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    switch ( seg )
+    {
+    case x86_seg_cs:   memcpy(reg, &vmcb->cs,   sizeof(*reg)); break;
+    case x86_seg_ds:   memcpy(reg, &vmcb->ds,   sizeof(*reg)); break;
+    case x86_seg_es:   memcpy(reg, &vmcb->es,   sizeof(*reg)); break;
+    case x86_seg_fs:   memcpy(reg, &vmcb->fs,   sizeof(*reg)); break;
+    case x86_seg_gs:   memcpy(reg, &vmcb->gs,   sizeof(*reg)); break;
+    case x86_seg_ss:   memcpy(reg, &vmcb->ss,   sizeof(*reg)); break;
+    case x86_seg_tr:   memcpy(reg, &vmcb->tr,   sizeof(*reg)); break;
+    case x86_seg_gdtr: memcpy(reg, &vmcb->gdtr, sizeof(*reg)); break;
+    case x86_seg_idtr: memcpy(reg, &vmcb->idtr, sizeof(*reg)); break;
+    case x86_seg_ldtr: memcpy(reg, &vmcb->ldtr, sizeof(*reg)); break;
+    default: BUG();
+    }
 }
 
 /* Make sure that xen intercepts any FP accesses from current */
@@ -785,6 +812,15 @@ static void svm_vcpu_destroy(struct vcpu
     svm_destroy_vmcb(v);
 }
 
+static void svm_hvm_inject_exception(
+    unsigned int trapnr, int errcode, unsigned long cr2)
+{
+    struct vcpu *v = current;
+    svm_inject_exception(v, trapnr, (errcode != -1), errcode);
+    if ( trapnr == TRAP_page_fault )
+        v->arch.hvm_svm.vmcb->cr2 = v->arch.hvm_svm.cpu_cr2 = cr2;
+}
+
 int start_svm(void)
 {
     u32 eax, ecx, edx;
@@ -844,11 +880,14 @@ int start_svm(void)
     hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
     hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
     hvm_funcs.get_segment_base = svm_get_segment_base;
+    hvm_funcs.get_segment_register = svm_get_segment_register;
 
     hvm_funcs.update_host_cr3 = svm_update_host_cr3;
     
     hvm_funcs.stts = svm_stts;
     hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
+
+    hvm_funcs.inject_exception = svm_hvm_inject_exception;
 
     hvm_funcs.init_ap_context = svm_init_ap_context;
     hvm_funcs.init_hypercall_page = svm_init_hypercall_page;
@@ -1154,7 +1193,7 @@ static void svm_dr_access(struct vcpu *v
 
 static void svm_get_prefix_info(
     struct vmcb_struct *vmcb, 
-    unsigned int dir, segment_selector_t **seg, unsigned int *asize)
+    unsigned int dir, svm_segment_register_t **seg, unsigned int *asize)
 {
     unsigned char inst[MAX_INST_LEN];
     int i;
@@ -1235,18 +1274,18 @@ static inline int svm_get_io_address(
     unsigned long        reg;
     unsigned int         asize, isize;
     int                  long_mode = 0;
-    segment_selector_t  *seg = NULL;
+    svm_segment_register_t *seg = NULL;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
 #ifdef __x86_64__
     /* If we're in long mode, we shouldn't check the segment presence & limit 
*/
-    long_mode = vmcb->cs.attributes.fields.l && vmcb->efer & EFER_LMA;
+    long_mode = vmcb->cs.attr.fields.l && vmcb->efer & EFER_LMA;
 #endif
 
-    /* d field of cs.attributes is 1 for 32-bit, 0 for 16 or 64 bit. 
-     * l field combined with EFER_LMA -> longmode says whether it's 16 or 64 
bit. 
+    /* d field of cs.attr is 1 for 32-bit, 0 for 16 or 64 bit. 
+     * l field combined with EFER_LMA says whether it's 16 or 64 bit. 
      */
-    asize = (long_mode)?64:((vmcb->cs.attributes.fields.db)?32:16);
+    asize = (long_mode)?64:((vmcb->cs.attr.fields.db)?32:16);
 
 
     /* The ins/outs instructions are single byte, so if we have got more 
@@ -1266,7 +1305,7 @@ static inline int svm_get_io_address(
         reg = regs->esi;
         if (!seg)               /* If no prefix, used DS. */
             seg = &vmcb->ds;
-        if (!long_mode && (seg->attributes.fields.type & 0xa) == 0x8) {
+        if (!long_mode && (seg->attr.fields.type & 0xa) == 0x8) {
             svm_inject_exception(v, TRAP_gp_fault, 1, 0);
             return 0;
         }
@@ -1275,14 +1314,14 @@ static inline int svm_get_io_address(
     {
         reg = regs->edi;
         seg = &vmcb->es;        /* Note: This is ALWAYS ES. */
-        if (!long_mode && (seg->attributes.fields.type & 0xa) != 0x2) {
+        if (!long_mode && (seg->attr.fields.type & 0xa) != 0x2) {
             svm_inject_exception(v, TRAP_gp_fault, 1, 0);
             return 0;
         }
     }
 
     /* If the segment isn't present, give GP fault! */
-    if (!long_mode && !seg->attributes.fields.p) 
+    if (!long_mode && !seg->attr.fields.p) 
     {
         svm_inject_exception(v, TRAP_gp_fault, 1, 0);
         return 0;
@@ -1305,7 +1344,7 @@ static inline int svm_get_io_address(
     {
         ASSERT(*addr == (u32)*addr);
         if ((u32)(*addr + size - 1) < (u32)*addr ||
-            (seg->attributes.fields.type & 0xc) != 0x4 ?
+            (seg->attr.fields.type & 0xc) != 0x4 ?
             *addr + size - 1 > seg->limit :
             *addr <= seg->limit)
         {
@@ -1318,9 +1357,9 @@ static inline int svm_get_io_address(
            occur. Note that the checking is not necessary for page granular
            segments as transfers crossing page boundaries will be broken up
            anyway. */
-        if (!seg->attributes.fields.g && *count > 1)
-        {
-            if ((seg->attributes.fields.type & 0xc) != 0x4)
+        if (!seg->attr.fields.g && *count > 1)
+        {
+            if ((seg->attr.fields.type & 0xc) != 0x4)
             {
                 /* expand-up */
                 if (!(regs->eflags & EF_DF))
@@ -1355,8 +1394,35 @@ static inline int svm_get_io_address(
 
         *addr += seg->base;
     }
-    else if (seg == &vmcb->fs || seg == &vmcb->gs)
-        *addr += seg->base;
+#ifdef __x86_64__
+    else
+    {
+        if (seg == &vmcb->fs || seg == &vmcb->gs)
+            *addr += seg->base;
+
+        if (!is_canonical_address(*addr) ||
+            !is_canonical_address(*addr + size - 1))
+        {
+            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+            return 0;
+        }
+        if (*count > (1UL << 48) / size)
+            *count = (1UL << 48) / size;
+        if (!(regs->eflags & EF_DF))
+        {
+            if (*addr + *count * size - 1 < *addr ||
+                !is_canonical_address(*addr + *count * size - 1))
+                *count = (*addr & ~((1UL << 48) - 1)) / size;
+        }
+        else
+        {
+            if ((*count - 1) * size > *addr ||
+                !is_canonical_address(*addr + (*count - 1) * size))
+                *count = (*addr & ~((1UL << 48) - 1)) / size + 1;
+        }
+        ASSERT(*count);
+    }
+#endif
 
     return 1;
 }
@@ -2154,52 +2220,52 @@ static int svm_do_vmmcall_reset_to_realm
 
     /* setup the segment registers and all their hidden states */
     vmcb->cs.sel = 0xF000;
-    vmcb->cs.attributes.bytes = 0x089b;
+    vmcb->cs.attr.bytes = 0x089b;
     vmcb->cs.limit = 0xffff;
     vmcb->cs.base = 0x000F0000;
 
     vmcb->ss.sel = 0x00;
-    vmcb->ss.attributes.bytes = 0x0893;
+    vmcb->ss.attr.bytes = 0x0893;
     vmcb->ss.limit = 0xffff;
     vmcb->ss.base = 0x00;
 
     vmcb->ds.sel = 0x00;
-    vmcb->ds.attributes.bytes = 0x0893;
+    vmcb->ds.attr.bytes = 0x0893;
     vmcb->ds.limit = 0xffff;
     vmcb->ds.base = 0x00;
     
     vmcb->es.sel = 0x00;
-    vmcb->es.attributes.bytes = 0x0893;
+    vmcb->es.attr.bytes = 0x0893;
     vmcb->es.limit = 0xffff;
     vmcb->es.base = 0x00;
     
     vmcb->fs.sel = 0x00;
-    vmcb->fs.attributes.bytes = 0x0893;
+    vmcb->fs.attr.bytes = 0x0893;
     vmcb->fs.limit = 0xffff;
     vmcb->fs.base = 0x00;
     
     vmcb->gs.sel = 0x00;
-    vmcb->gs.attributes.bytes = 0x0893;
+    vmcb->gs.attr.bytes = 0x0893;
     vmcb->gs.limit = 0xffff;
     vmcb->gs.base = 0x00;
 
     vmcb->ldtr.sel = 0x00;
-    vmcb->ldtr.attributes.bytes = 0x0000;
+    vmcb->ldtr.attr.bytes = 0x0000;
     vmcb->ldtr.limit = 0x0;
     vmcb->ldtr.base = 0x00;
 
     vmcb->gdtr.sel = 0x00;
-    vmcb->gdtr.attributes.bytes = 0x0000;
+    vmcb->gdtr.attr.bytes = 0x0000;
     vmcb->gdtr.limit = 0x0;
     vmcb->gdtr.base = 0x00;
     
     vmcb->tr.sel = 0;
-    vmcb->tr.attributes.bytes = 0;
+    vmcb->tr.attr.bytes = 0;
     vmcb->tr.limit = 0x0;
     vmcb->tr.base = 0;
 
     vmcb->idtr.sel = 0x00;
-    vmcb->idtr.attributes.bytes = 0x0000;
+    vmcb->idtr.attr.bytes = 0x0000;
     vmcb->idtr.limit = 0x3ff;
     vmcb->idtr.base = 0x00;
 
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Mon Dec 04 08:24:41 2006 -0700
@@ -90,7 +90,7 @@ static int construct_vmcb(struct vcpu *v
 {
     struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
     struct vmcb_struct *vmcb = arch_svm->vmcb;
-    segment_attributes_t attrib;
+    svm_segment_attributes_t attrib;
 
     /* Always flush the TLB on VMRUN. */
     vmcb->tlb_control = 1;
@@ -166,13 +166,13 @@ static int construct_vmcb(struct vcpu *v
     attrib.fields.p = 1;      /* segment present */
     attrib.fields.db = 1;     /* 32-bit */
     attrib.fields.g = 1;      /* 4K pages in limit */
-    vmcb->es.attributes = attrib;
-    vmcb->ss.attributes = attrib;
-    vmcb->ds.attributes = attrib;
-    vmcb->fs.attributes = attrib;
-    vmcb->gs.attributes = attrib;
+    vmcb->es.attr = attrib;
+    vmcb->ss.attr = attrib;
+    vmcb->ds.attr = attrib;
+    vmcb->fs.attr = attrib;
+    vmcb->gs.attr = attrib;
     attrib.fields.type = 0xb; /* type=0xb -> executable/readable, accessed */
-    vmcb->cs.attributes = attrib;
+    vmcb->cs.attr = attrib;
 
     /* Guest IDT. */
     vmcb->idtr.base = 0;
@@ -186,11 +186,11 @@ static int construct_vmcb(struct vcpu *v
     vmcb->ldtr.sel = 0;
     vmcb->ldtr.base = 0;
     vmcb->ldtr.limit = 0;
-    vmcb->ldtr.attributes.bytes = 0;
+    vmcb->ldtr.attr.bytes = 0;
 
     /* Guest TSS. */
     attrib.fields.type = 0xb; /* 32-bit TSS (busy) */
-    vmcb->tr.attributes = attrib;
+    vmcb->tr.attr = attrib;
     vmcb->tr.base = 0;
     vmcb->tr.limit = 0xff;
 
@@ -278,10 +278,10 @@ void svm_do_launch(struct vcpu *v)
     v->arch.schedule_tail = arch_svm_do_resume;
 }
 
-static void svm_dump_sel(char *name, segment_selector_t *s)
+static void svm_dump_sel(char *name, svm_segment_register_t *s)
 {
     printk("%s: sel=0x%04x, attr=0x%04x, limit=0x%08x, base=0x%016llx\n", 
-           name, s->sel, s->attributes.bytes, s->limit,
+           name, s->sel, s->attr.bytes, s->limit,
            (unsigned long long)s->base);
 }
 
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/vlapic.c Mon Dec 04 08:24:41 2006 -0700
@@ -119,19 +119,16 @@ static int vlapic_find_highest_vector(u3
 
 static int vlapic_test_and_set_irr(int vector, struct vlapic *vlapic)
 {
-    vlapic->flush_tpr_threshold = 1;
     return vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
 }
 
 static void vlapic_set_irr(int vector, struct vlapic *vlapic)
 {
-    vlapic->flush_tpr_threshold = 1;
     vlapic_set_vector(vector, vlapic->regs + APIC_IRR);
 }
 
 static void vlapic_clear_irr(int vector, struct vlapic *vlapic)
 {
-    vlapic->flush_tpr_threshold = 1;
     vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
 }
 
@@ -634,7 +631,6 @@ static void vlapic_write(struct vcpu *v,
     {
     case APIC_TASKPRI:
         vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
-        vlapic->flush_tpr_threshold = 1;
         break;
 
     case APIC_EOI:
@@ -667,10 +663,7 @@ static void vlapic_write(struct vcpu *v,
             }
         }
         else
-        {
             vlapic->disabled &= ~VLAPIC_SW_DISABLED;
-            vlapic->flush_tpr_threshold = 1;
-        }
         break;
 
     case APIC_ESR:
@@ -730,7 +723,7 @@ static void vlapic_write(struct vcpu *v,
         break;
 
     default:
-        gdprintk(XENLOG_WARNING, 
+        gdprintk(XENLOG_DEBUG,
                  "Local APIC Write to read-only register 0x%x\n", offset);
         break;
     }
@@ -925,8 +918,6 @@ static int vlapic_reset(struct vlapic *v
     vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
     vlapic->disabled |= VLAPIC_SW_DISABLED;
 
-    vlapic->flush_tpr_threshold = 1;
-
     return 1;
 }
 
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/vmx/Makefile
--- a/xen/arch/x86/hvm/vmx/Makefile     Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/Makefile     Mon Dec 04 08:24:41 2006 -0700
@@ -1,6 +1,6 @@ subdir-$(x86_32) += x86_32
 subdir-$(x86_32) += x86_32
 subdir-$(x86_64) += x86_64
 
-obj-y += io.o
+obj-y += intr.o
 obj-y += vmcs.o
 obj-y += vmx.o
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Dec 04 08:24:41 2006 -0700
@@ -95,13 +95,7 @@ static void vmx_save_host_msrs(void)
         rdmsrl(msr_index[i], host_msr_state->msrs[i]);
 }
 
-#define CASE_READ_MSR(address)                                              \
-    case MSR_ ## address:                                                   \
-        msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_ ## address];     \
-        break
-
-#define CASE_WRITE_MSR(address)                                             \
-    case MSR_ ## address:                                                   \
+#define WRITE_MSR(address)                                                  \
         guest_msr_state->msrs[VMX_INDEX_MSR_ ## address] = msr_content;     \
         if ( !test_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags) )\
             set_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags);    \
@@ -109,7 +103,6 @@ static void vmx_save_host_msrs(void)
         set_bit(VMX_INDEX_MSR_ ## address, &host_msr_state->flags);         \
         break
 
-#define IS_CANO_ADDRESS(add) 1
 static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
 {
     u64 msr_content = 0;
@@ -123,27 +116,38 @@ static inline int long_mode_do_msr_read(
         break;
 
     case MSR_FS_BASE:
-        if ( !(vmx_long_mode_enabled(v)) )
-            goto exit_and_crash;
-
         msr_content = __vmread(GUEST_FS_BASE);
-        break;
+        goto check_long_mode;
 
     case MSR_GS_BASE:
-        if ( !(vmx_long_mode_enabled(v)) )
-            goto exit_and_crash;
-
         msr_content = __vmread(GUEST_GS_BASE);
-        break;
+        goto check_long_mode;
 
     case MSR_SHADOW_GS_BASE:
         msr_content = guest_msr_state->shadow_gs;
-        break;
-
-    CASE_READ_MSR(STAR);
-    CASE_READ_MSR(LSTAR);
-    CASE_READ_MSR(CSTAR);
-    CASE_READ_MSR(SYSCALL_MASK);
+    check_long_mode:
+        if ( !(vmx_long_mode_enabled(v)) )
+        {
+            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
+            return 0;
+        }
+        break;
+
+    case MSR_STAR:
+        msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_STAR];
+        break;
+
+    case MSR_LSTAR:
+        msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_LSTAR];
+        break;
+
+    case MSR_CSTAR:
+        msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_CSTAR];
+        break;
+
+    case MSR_SYSCALL_MASK:
+        msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
+        break;
 
     default:
         return 0;
@@ -155,32 +159,28 @@ static inline int long_mode_do_msr_read(
     regs->edx = (u32)(msr_content >> 32);
 
     return 1;
-
- exit_and_crash:
-    gdprintk(XENLOG_ERR, "Fatal error reading MSR %lx\n", (long)regs->ecx);
-    domain_crash(v->domain);
-    return 1; /* handled */
 }
 
 static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
     u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
+    u32 ecx = regs->ecx;
     struct vcpu *v = current;
     struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
     struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state);
 
     HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%x msr_content 0x%"PRIx64"\n",
-                (u32)regs->ecx, msr_content);
-
-    switch ( (u32)regs->ecx ) {
+                ecx, msr_content);
+
+    switch ( ecx )
+    {
     case MSR_EFER:
         /* offending reserved bit will cause #GP */
         if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
         {
-            printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
-                   msr_content);
-            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
-            return 0;
+            gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
+                     "EFER: %"PRIx64"\n", msr_content);
+            goto gp_fault;
         }
 
         if ( (msr_content & EFER_LME)
@@ -188,9 +188,9 @@ static inline int long_mode_do_msr_write
         {
             if ( unlikely(vmx_paging_enabled(v)) )
             {
-                printk("Trying to set EFER.LME with paging enabled\n");
-                vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
-                return 0;
+                gdprintk(XENLOG_WARNING,
+                         "Trying to set EFER.LME with paging enabled\n");
+                goto gp_fault;
             }
         }
         else if ( !(msr_content & EFER_LME)
@@ -198,9 +198,9 @@ static inline int long_mode_do_msr_write
         {
             if ( unlikely(vmx_paging_enabled(v)) )
             {
-                printk("Trying to clear EFER.LME with paging enabled\n");
-                vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
-                return 0;
+                gdprintk(XENLOG_WARNING,
+                         "Trying to clear EFER.LME with paging enabled\n");
+                goto gp_fault;
             }
         }
 
@@ -209,35 +209,40 @@ static inline int long_mode_do_msr_write
 
     case MSR_FS_BASE:
     case MSR_GS_BASE:
+    case MSR_SHADOW_GS_BASE:
         if ( !vmx_long_mode_enabled(v) )
-            goto exit_and_crash;
-
-        if ( !IS_CANO_ADDRESS(msr_content) )
-        {
-            HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
-            vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
-            return 0;
-        }
-
-        if ( regs->ecx == MSR_FS_BASE )
+            goto gp_fault;
+
+        if ( !is_canonical_address(msr_content) )
+            goto uncanonical_address;
+
+        if ( ecx == MSR_FS_BASE )
             __vmwrite(GUEST_FS_BASE, msr_content);
+        else if ( ecx == MSR_GS_BASE )
+            __vmwrite(GUEST_GS_BASE, msr_content);
         else
-            __vmwrite(GUEST_GS_BASE, msr_content);
-
-        break;
-
-    case MSR_SHADOW_GS_BASE:
-        if ( !(vmx_long_mode_enabled(v)) )
-            goto exit_and_crash;
-
-        v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
-        wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
-        break;
-
-    CASE_WRITE_MSR(STAR);
-    CASE_WRITE_MSR(LSTAR);
-    CASE_WRITE_MSR(CSTAR);
-    CASE_WRITE_MSR(SYSCALL_MASK);
+        {
+            v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
+            wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
+        }
+
+        break;
+
+    case MSR_STAR:
+        WRITE_MSR(STAR);
+
+    case MSR_LSTAR:
+        if ( !is_canonical_address(msr_content) )
+            goto uncanonical_address;
+        WRITE_MSR(LSTAR);
+
+    case MSR_CSTAR:
+        if ( !is_canonical_address(msr_content) )
+            goto uncanonical_address;
+        WRITE_MSR(CSTAR);
+
+    case MSR_SYSCALL_MASK:
+        WRITE_MSR(SYSCALL_MASK);
 
     default:
         return 0;
@@ -245,10 +250,11 @@ static inline int long_mode_do_msr_write
 
     return 1;
 
- exit_and_crash:
-    gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
-    domain_crash(v->domain);
-    return 1; /* handled */
+ uncanonical_address:
+    HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
+ gp_fault:
+    vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
+    return 0;
 }
 
 /*
@@ -501,7 +507,7 @@ static unsigned long vmx_get_ctrl_reg(st
     return 0;                   /* dummy */
 }
 
-static unsigned long vmx_get_segment_base(struct vcpu *v, enum segment seg)
+static unsigned long vmx_get_segment_base(struct vcpu *v, enum x86_segment seg)
 {
     unsigned long base = 0;
     int long_mode = 0;
@@ -516,20 +522,92 @@ static unsigned long vmx_get_segment_bas
 
     switch ( seg )
     {
-    case seg_cs: if ( !long_mode ) base = __vmread(GUEST_CS_BASE); break;
-    case seg_ds: if ( !long_mode ) base = __vmread(GUEST_DS_BASE); break;
-    case seg_es: if ( !long_mode ) base = __vmread(GUEST_ES_BASE); break;
-    case seg_fs: base = __vmread(GUEST_FS_BASE); break;
-    case seg_gs: base = __vmread(GUEST_GS_BASE); break;
-    case seg_ss: if ( !long_mode ) base = __vmread(GUEST_SS_BASE); break;
-    case seg_tr: base = __vmread(GUEST_TR_BASE); break;
-    case seg_gdtr: base = __vmread(GUEST_GDTR_BASE); break;
-    case seg_idtr: base = __vmread(GUEST_IDTR_BASE); break;
-    case seg_ldtr: base = __vmread(GUEST_LDTR_BASE); break;
+    case x86_seg_cs: if ( !long_mode ) base = __vmread(GUEST_CS_BASE); break;
+    case x86_seg_ds: if ( !long_mode ) base = __vmread(GUEST_DS_BASE); break;
+    case x86_seg_es: if ( !long_mode ) base = __vmread(GUEST_ES_BASE); break;
+    case x86_seg_fs: base = __vmread(GUEST_FS_BASE); break;
+    case x86_seg_gs: base = __vmread(GUEST_GS_BASE); break;
+    case x86_seg_ss: if ( !long_mode ) base = __vmread(GUEST_SS_BASE); break;
+    case x86_seg_tr: base = __vmread(GUEST_TR_BASE); break;
+    case x86_seg_gdtr: base = __vmread(GUEST_GDTR_BASE); break;
+    case x86_seg_idtr: base = __vmread(GUEST_IDTR_BASE); break;
+    case x86_seg_ldtr: base = __vmread(GUEST_LDTR_BASE); break;
     default: BUG(); break;
     }
 
     return base;
+}
+
+static void vmx_get_segment_register(struct vcpu *v, enum x86_segment seg,
+                                     struct segment_register *reg)
+{
+    u16 attr = 0;
+
+    ASSERT(v == current);
+
+    switch ( seg )
+    {
+    case x86_seg_cs:
+        reg->sel   = __vmread(GUEST_CS_SELECTOR);
+        reg->limit = __vmread(GUEST_CS_LIMIT);
+        reg->base  = __vmread(GUEST_CS_BASE);
+        attr       = __vmread(GUEST_CS_AR_BYTES);
+        break;
+    case x86_seg_ds:
+        reg->sel   = __vmread(GUEST_DS_SELECTOR);
+        reg->limit = __vmread(GUEST_DS_LIMIT);
+        reg->base  = __vmread(GUEST_DS_BASE);
+        attr       = __vmread(GUEST_DS_AR_BYTES);
+        break;
+    case x86_seg_es:
+        reg->sel   = __vmread(GUEST_ES_SELECTOR);
+        reg->limit = __vmread(GUEST_ES_LIMIT);
+        reg->base  = __vmread(GUEST_ES_BASE);
+        attr       = __vmread(GUEST_ES_AR_BYTES);
+        break;
+    case x86_seg_fs:
+        reg->sel   = __vmread(GUEST_FS_SELECTOR);
+        reg->limit = __vmread(GUEST_FS_LIMIT);
+        reg->base  = __vmread(GUEST_FS_BASE);
+        attr       = __vmread(GUEST_FS_AR_BYTES);
+        break;
+    case x86_seg_gs:
+        reg->sel   = __vmread(GUEST_GS_SELECTOR);
+        reg->limit = __vmread(GUEST_GS_LIMIT);
+        reg->base  = __vmread(GUEST_GS_BASE);
+        attr       = __vmread(GUEST_GS_AR_BYTES);
+        break;
+    case x86_seg_ss:
+        reg->sel   = __vmread(GUEST_SS_SELECTOR);
+        reg->limit = __vmread(GUEST_SS_LIMIT);
+        reg->base  = __vmread(GUEST_SS_BASE);
+        attr       = __vmread(GUEST_SS_AR_BYTES);
+        break;
+    case x86_seg_tr:
+        reg->sel   = __vmread(GUEST_TR_SELECTOR);
+        reg->limit = __vmread(GUEST_TR_LIMIT);
+        reg->base  = __vmread(GUEST_TR_BASE);
+        attr       = __vmread(GUEST_TR_AR_BYTES);
+        break;
+    case x86_seg_gdtr:
+        reg->limit = __vmread(GUEST_GDTR_LIMIT);
+        reg->base  = __vmread(GUEST_GDTR_BASE);
+        break;
+    case x86_seg_idtr:
+        reg->limit = __vmread(GUEST_IDTR_LIMIT);
+        reg->base  = __vmread(GUEST_IDTR_BASE);
+        break;
+    case x86_seg_ldtr:
+        reg->sel   = __vmread(GUEST_LDTR_SELECTOR);
+        reg->limit = __vmread(GUEST_LDTR_LIMIT);
+        reg->base  = __vmread(GUEST_LDTR_BASE);
+        attr       = __vmread(GUEST_LDTR_AR_BYTES);
+        break;
+    default:
+        BUG();
+    }
+
+    reg->attr.bytes = (attr & 0xff) | ((attr >> 4) & 0xf00);
 }
 
 /* Make sure that xen intercepts any FP accesses from current */
@@ -630,6 +708,22 @@ static int vmx_pae_enabled(struct vcpu *
     return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
 }
 
+/* Works only for vcpu == current */
+static void vmx_update_host_cr3(struct vcpu *v)
+{
+    ASSERT(v == current);
+    __vmwrite(HOST_CR3, v->arch.cr3);
+}
+
+static void vmx_inject_exception(
+    unsigned int trapnr, int errcode, unsigned long cr2)
+{
+    struct vcpu *v = current;
+    vmx_inject_hw_exception(v, trapnr, errcode);
+    if ( trapnr == TRAP_page_fault )
+        v->arch.hvm_vmx.cpu_cr2 = cr2;
+}
+
 /* Setup HVM interfaces */
 static void vmx_setup_hvm_funcs(void)
 {
@@ -650,11 +744,14 @@ static void vmx_setup_hvm_funcs(void)
     hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
     hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
     hvm_funcs.get_segment_base = vmx_get_segment_base;
+    hvm_funcs.get_segment_register = vmx_get_segment_register;
 
     hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
 
     hvm_funcs.stts = vmx_stts;
     hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
+
+    hvm_funcs.inject_exception = vmx_inject_exception;
 
     hvm_funcs.init_ap_context = vmx_init_ap_context;
 
@@ -962,14 +1059,14 @@ static void vmx_do_invlpg(unsigned long 
 
 
 static int vmx_check_descriptor(int long_mode, unsigned long eip, int inst_len,
-                                enum segment seg, unsigned long *base,
+                                enum x86_segment seg, unsigned long *base,
                                 u32 *limit, u32 *ar_bytes)
 {
     enum vmcs_field ar_field, base_field, limit_field;
 
     *base = 0;
     *limit = 0;
-    if ( seg != seg_es )
+    if ( seg != x86_seg_es )
     {
         unsigned char inst[MAX_INST_LEN];
         int i;
@@ -999,22 +1096,22 @@ static int vmx_check_descriptor(int long
 #endif
                 continue;
             case 0x2e: /* CS */
-                seg = seg_cs;
+                seg = x86_seg_cs;
                 continue;
             case 0x36: /* SS */
-                seg = seg_ss;
+                seg = x86_seg_ss;
                 continue;
             case 0x26: /* ES */
-                seg = seg_es;
+                seg = x86_seg_es;
                 continue;
             case 0x64: /* FS */
-                seg = seg_fs;
+                seg = x86_seg_fs;
                 continue;
             case 0x65: /* GS */
-                seg = seg_gs;
+                seg = x86_seg_gs;
                 continue;
             case 0x3e: /* DS */
-                seg = seg_ds;
+                seg = x86_seg_ds;
                 continue;
             }
         }
@@ -1022,32 +1119,32 @@ static int vmx_check_descriptor(int long
 
     switch ( seg )
     {
-    case seg_cs:
+    case x86_seg_cs:
         ar_field = GUEST_CS_AR_BYTES;
         base_field = GUEST_CS_BASE;
         limit_field = GUEST_CS_LIMIT;
         break;
-    case seg_ds:
+    case x86_seg_ds:
         ar_field = GUEST_DS_AR_BYTES;
         base_field = GUEST_DS_BASE;
         limit_field = GUEST_DS_LIMIT;
         break;
-    case seg_es:
+    case x86_seg_es:
         ar_field = GUEST_ES_AR_BYTES;
         base_field = GUEST_ES_BASE;
         limit_field = GUEST_ES_LIMIT;
         break;
-    case seg_fs:
+    case x86_seg_fs:
         ar_field = GUEST_FS_AR_BYTES;
         base_field = GUEST_FS_BASE;
         limit_field = GUEST_FS_LIMIT;
         break;
-    case seg_gs:
+    case x86_seg_gs:
         ar_field = GUEST_FS_AR_BYTES;
         base_field = GUEST_FS_BASE;
         limit_field = GUEST_FS_LIMIT;
         break;
-    case seg_ss:
+    case x86_seg_ss:
         ar_field = GUEST_GS_AR_BYTES;
         base_field = GUEST_GS_BASE;
         limit_field = GUEST_GS_LIMIT;
@@ -1057,7 +1154,7 @@ static int vmx_check_descriptor(int long
         return 0;
     }
 
-    if ( !long_mode || seg == seg_fs || seg == seg_gs )
+    if ( !long_mode || seg == x86_seg_fs || seg == x86_seg_gs )
     {
         *base = __vmread(base_field);
         *limit = __vmread(limit_field);
@@ -1127,7 +1224,7 @@ static void vmx_io_instruction(unsigned 
          * selector is null.
          */
         if ( !vmx_check_descriptor(long_mode, regs->eip, inst_len,
-                                   dir == IOREQ_WRITE ? seg_ds : seg_es,
+                                   dir==IOREQ_WRITE ? x86_seg_ds : x86_seg_es,
                                    &base, &limit, &ar_bytes) ) {
             if ( !long_mode ) {
                 vmx_inject_hw_exception(current, TRAP_gp_fault, 0);
@@ -1196,6 +1293,32 @@ static void vmx_io_instruction(unsigned 
                 ASSERT(count);
             }
         }
+#ifdef __x86_64__
+        else
+        {
+            if ( !is_canonical_address(addr) ||
+                 !is_canonical_address(addr + size - 1) )
+            {
+                vmx_inject_hw_exception(current, TRAP_gp_fault, 0);
+                return;
+            }
+            if ( count > (1UL << 48) / size )
+                count = (1UL << 48) / size;
+            if ( !(regs->eflags & EF_DF) )
+            {
+                if ( addr + count * size - 1 < addr ||
+                     !is_canonical_address(addr + count * size - 1) )
+                    count = (addr & ~((1UL << 48) - 1)) / size;
+            }
+            else
+            {
+                if ( (count - 1) * size > addr ||
+                     !is_canonical_address(addr + (count - 1) * size) )
+                    count = (addr & ~((1UL << 48) - 1)) / size + 1;
+            }
+            ASSERT(count);
+        }
+#endif
 
         /*
          * Handle string pio instructions that cross pages or that
@@ -2413,7 +2536,6 @@ asmlinkage void vmx_vmexit_handler(struc
         break;
 
     case EXIT_REASON_TPR_BELOW_THRESHOLD:
-        vcpu_vlapic(v)->flush_tpr_threshold = 1;
         break;
 
     default:
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm.c Mon Dec 04 08:24:41 2006 -0700
@@ -3033,12 +3033,39 @@ long arch_memory_op(int op, XEN_GUEST_HA
  * Writable Pagetables
  */
 
+struct ptwr_emulate_ctxt {
+    struct x86_emulate_ctxt ctxt;
+    unsigned long cr2;
+    l1_pgentry_t  pte;
+};
+
+static int ptwr_emulated_read(
+    enum x86_segment seg,
+    unsigned long offset,
+    unsigned long *val,
+    unsigned int bytes,
+    struct x86_emulate_ctxt *ctxt)
+{
+    unsigned int rc;
+    unsigned long addr = offset;
+
+    *val = 0;
+    if ( (rc = copy_from_user((void *)val, (void *)addr, bytes)) != 0 )
+    {
+        propagate_page_fault(addr + bytes - rc, 0); /* read fault */
+        return X86EMUL_PROPAGATE_FAULT;
+    }
+
+    return X86EMUL_CONTINUE;
+}
+
 static int ptwr_emulated_update(
     unsigned long addr,
     paddr_t old,
     paddr_t val,
     unsigned int bytes,
-    unsigned int do_cmpxchg)
+    unsigned int do_cmpxchg,
+    struct ptwr_emulate_ctxt *ptwr_ctxt)
 {
     unsigned long gmfn, mfn;
     struct page_info *page;
@@ -3046,11 +3073,11 @@ static int ptwr_emulated_update(
     struct vcpu *v = current;
     struct domain *d = v->domain;
 
-    /* Aligned access only, thank you. */
-    if ( !access_ok(addr, bytes) || ((addr & (bytes-1)) != 0) )
-    {
-        MEM_LOG("ptwr_emulate: Unaligned or bad size ptwr access (%d, %lx)",
-                bytes, addr);
+    /* Only allow naturally-aligned stores within the original %cr2 page. */
+    if ( unlikely(((addr^ptwr_ctxt->cr2) & PAGE_MASK) || (addr & (bytes-1))) )
+    {
+        MEM_LOG("Bad ptwr access (cr2=%lx, addr=%lx, bytes=%u)",
+                ptwr_ctxt->cr2, addr, bytes);
         return X86EMUL_UNHANDLEABLE;
     }
 
@@ -3079,17 +3106,9 @@ static int ptwr_emulated_update(
         old  |= full;
     }
 
-    /* Read the PTE that maps the page being updated. */
-    guest_get_eff_l1e(v, addr, &pte);
-    if ( unlikely(!(l1e_get_flags(pte) & _PAGE_PRESENT)) )
-    {
-        MEM_LOG("%s: Cannot get L1 PTE for guest address %lx",
-                __func__, addr);
-        return X86EMUL_UNHANDLEABLE;
-    }
-
-    gmfn  = l1e_get_pfn(pte);
-    mfn = gmfn_to_mfn(d, gmfn);
+    pte  = ptwr_ctxt->pte;
+    gmfn = l1e_get_pfn(pte);
+    mfn  = gmfn_to_mfn(d, gmfn);
     page = mfn_to_page(mfn);
 
     /* We are looking only for read-only mappings of p.t. pages. */
@@ -3164,26 +3183,33 @@ static int ptwr_emulated_update(
 }
 
 static int ptwr_emulated_write(
-    unsigned long addr,
+    enum x86_segment seg,
+    unsigned long offset,
     unsigned long val,
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt)
 {
-    return ptwr_emulated_update(addr, 0, val, bytes, 0);
+    return ptwr_emulated_update(
+        offset, 0, val, bytes, 0,
+        container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
 }
 
 static int ptwr_emulated_cmpxchg(
-    unsigned long addr,
+    enum x86_segment seg,
+    unsigned long offset,
     unsigned long old,
     unsigned long new,
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt)
 {
-    return ptwr_emulated_update(addr, old, new, bytes, 1);
+    return ptwr_emulated_update(
+        offset, old, new, bytes, 1,
+        container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
 }
 
 static int ptwr_emulated_cmpxchg8b(
-    unsigned long addr,
+    enum x86_segment seg,
+    unsigned long offset,
     unsigned long old,
     unsigned long old_hi,
     unsigned long new,
@@ -3192,18 +3218,17 @@ static int ptwr_emulated_cmpxchg8b(
 {
     if ( CONFIG_PAGING_LEVELS == 2 )
         return X86EMUL_UNHANDLEABLE;
-    else
-        return ptwr_emulated_update(
-            addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1);
+    return ptwr_emulated_update(
+        offset, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1,
+        container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
 }
 
 static struct x86_emulate_ops ptwr_emulate_ops = {
-    .read_std           = x86_emulate_read_std,
-    .write_std          = x86_emulate_write_std,
-    .read_emulated      = x86_emulate_read_std,
-    .write_emulated     = ptwr_emulated_write,
-    .cmpxchg_emulated   = ptwr_emulated_cmpxchg,
-    .cmpxchg8b_emulated = ptwr_emulated_cmpxchg8b
+    .read       = ptwr_emulated_read,
+    .insn_fetch = ptwr_emulated_read,
+    .write      = ptwr_emulated_write,
+    .cmpxchg    = ptwr_emulated_cmpxchg,
+    .cmpxchg8b  = ptwr_emulated_cmpxchg8b
 };
 
 /* Write page fault handler: check if guest is trying to modify a PTE. */
@@ -3214,7 +3239,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
     unsigned long     pfn;
     struct page_info *page;
     l1_pgentry_t      pte;
-    struct x86_emulate_ctxt emul_ctxt;
+    struct ptwr_emulate_ctxt ptwr_ctxt;
 
     LOCK_BIGLOCK(d);
 
@@ -3235,10 +3260,11 @@ int ptwr_do_page_fault(struct vcpu *v, u
          (page_get_owner(page) != d) )
         goto bail;
 
-    emul_ctxt.regs = guest_cpu_user_regs();
-    emul_ctxt.cr2  = addr;
-    emul_ctxt.mode = X86EMUL_MODE_HOST;
-    if ( x86_emulate_memop(&emul_ctxt, &ptwr_emulate_ops) )
+    ptwr_ctxt.ctxt.regs = guest_cpu_user_regs();
+    ptwr_ctxt.ctxt.mode = X86EMUL_MODE_HOST;
+    ptwr_ctxt.cr2       = addr;
+    ptwr_ctxt.pte       = pte;
+    if ( x86_emulate_memop(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
         goto bail;
 
     UNLOCK_BIGLOCK(d);
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm/shadow/common.c   Mon Dec 04 08:24:41 2006 -0700
@@ -69,18 +69,122 @@ int _shadow_mode_refcounts(struct domain
 /* x86 emulator support for the shadow code
  */
 
+struct segment_register *hvm_get_seg_reg(
+    enum x86_segment seg, struct sh_emulate_ctxt *sh_ctxt)
+{
+    struct segment_register *seg_reg = &sh_ctxt->seg_reg[seg];
+    if ( !__test_and_set_bit(seg, &sh_ctxt->valid_seg_regs) )
+        hvm_get_segment_register(current, seg, seg_reg);
+    return seg_reg;
+}
+
+enum hvm_access_type {
+    hvm_access_insn_fetch, hvm_access_read, hvm_access_write
+};
+
+static int hvm_translate_linear_addr(
+    enum x86_segment seg,
+    unsigned long offset,
+    unsigned int bytes,
+    enum hvm_access_type access_type,
+    struct sh_emulate_ctxt *sh_ctxt,
+    unsigned long *paddr)
+{
+    struct segment_register *reg = hvm_get_seg_reg(seg, sh_ctxt);
+    unsigned long limit, addr = offset;
+    uint32_t last_byte;
+
+    if ( sh_ctxt->ctxt.mode != X86EMUL_MODE_PROT64 )
+    {
+        /*
+         * COMPATIBILITY MODE: Apply segment checks and add base.
+         */
+
+        switch ( access_type )
+        {
+        case hvm_access_read:
+            if ( (reg->attr.fields.type & 0xa) == 0x8 )
+                goto gpf; /* execute-only code segment */
+            break;
+        case hvm_access_write:
+            if ( (reg->attr.fields.type & 0xa) != 0x2 )
+                goto gpf; /* not a writable data segment */
+            break;
+        default:
+            break;
+        }
+
+        /* Calculate the segment limit, including granularity flag. */
+        limit = reg->limit;
+        if ( reg->attr.fields.g )
+            limit = (limit << 12) | 0xfff;
+
+        last_byte = offset + bytes - 1;
+
+        /* Is this a grows-down data segment? Special limit check if so. */
+        if ( (reg->attr.fields.type & 0xc) == 0x4 )
+        {
+            /* Is upper limit 0xFFFF or 0xFFFFFFFF? */
+            if ( !reg->attr.fields.db )
+                last_byte = (uint16_t)last_byte;
+
+            /* Check first byte and last byte against respective bounds. */
+            if ( (offset <= limit) || (last_byte < offset) )
+                goto gpf;
+        }
+        else if ( (last_byte > limit) || (last_byte < offset) )
+            goto gpf; /* last byte is beyond limit or wraps 0xFFFFFFFF */
+
+        /*
+         * Hardware truncates to 32 bits in compatibility mode.
+         * It does not truncate to 16 bits in 16-bit address-size mode.
+         */
+        addr = (uint32_t)(addr + reg->base);
+    }
+    else
+    {
+        /*
+         * LONG MODE: FS and GS add segment base. Addresses must be canonical.
+         */
+
+        if ( (seg == x86_seg_fs) || (seg == x86_seg_gs) )
+            addr += reg->base;
+
+        if ( !is_canonical_address(addr) )
+            goto gpf;
+    }
+
+    *paddr = addr;
+    return 0;    
+
+ gpf:
+    /* Inject #GP(0). */
+    hvm_inject_exception(TRAP_gp_fault, 0, 0);
+    return X86EMUL_PROPAGATE_FAULT;
+}
+
 static int
-sh_x86_emulate_read_std(unsigned long addr,
-                         unsigned long *val,
-                         unsigned int bytes,
-                         struct x86_emulate_ctxt *ctxt)
-{
+hvm_read(enum x86_segment seg,
+         unsigned long offset,
+         unsigned long *val,
+         unsigned int bytes,
+         enum hvm_access_type access_type,
+         struct sh_emulate_ctxt *sh_ctxt)
+{
+    unsigned long addr;
+    int rc, errcode;
+
+    rc = hvm_translate_linear_addr(
+        seg, offset, bytes, access_type, sh_ctxt, &addr);
+    if ( rc )
+        return rc;
+
     *val = 0;
     // XXX -- this is WRONG.
     //        It entirely ignores the permissions in the page tables.
     //        In this case, that is only a user vs supervisor access check.
     //
-    if ( hvm_copy_from_guest_virt(val, addr, bytes) == 0 )
+    if ( (rc = hvm_copy_from_guest_virt(val, addr, bytes)) == 0 )
     {
 #if 0
         struct vcpu *v = current;
@@ -95,93 +199,168 @@ sh_x86_emulate_read_std(unsigned long ad
      * was mapped here.  This should never happen: we're here because
      * of a write fault at the end of the instruction we're emulating. */ 
     SHADOW_PRINTK("read failed to va %#lx\n", addr);
+    errcode = ring_3(sh_ctxt->ctxt.regs) ? PFEC_user_mode : 0;
+    if ( access_type == hvm_access_insn_fetch )
+        errcode |= PFEC_insn_fetch;
+    hvm_inject_exception(TRAP_page_fault, errcode, addr + bytes - rc);
     return X86EMUL_PROPAGATE_FAULT;
 }
 
+void shadow_init_emulation(struct sh_emulate_ctxt *sh_ctxt, 
+                           struct cpu_user_regs *regs)
+{
+    struct segment_register *creg;
+    struct vcpu *v = current;
+    unsigned long addr;
+
+    sh_ctxt->ctxt.regs = regs;
+
+    /* Segment cache initialisation. Primed with CS. */
+    sh_ctxt->valid_seg_regs = 0;
+    creg = hvm_get_seg_reg(x86_seg_cs, sh_ctxt);
+
+    /* Work out the emulation mode. */
+    if ( hvm_long_mode_enabled(v) )
+        sh_ctxt->ctxt.mode = creg->attr.fields.l ?
+            X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32;
+    else if ( regs->eflags & X86_EFLAGS_VM )
+        sh_ctxt->ctxt.mode = X86EMUL_MODE_REAL;
+    else
+        sh_ctxt->ctxt.mode = creg->attr.fields.db ?
+            X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+
+    /* Attempt to prefetch whole instruction. */
+    sh_ctxt->insn_buf_bytes =
+        (!hvm_translate_linear_addr(
+            x86_seg_cs, regs->eip, sizeof(sh_ctxt->insn_buf),
+            hvm_access_insn_fetch, sh_ctxt, &addr) &&
+         !hvm_copy_from_guest_virt(
+             sh_ctxt->insn_buf, addr, sizeof(sh_ctxt->insn_buf)))
+        ? sizeof(sh_ctxt->insn_buf) : 0;
+}
+
 static int
-sh_x86_emulate_write_std(unsigned long addr,
-                          unsigned long val,
+sh_x86_emulate_read(enum x86_segment seg,
+                    unsigned long offset,
+                    unsigned long *val,
+                    unsigned int bytes,
+                    struct x86_emulate_ctxt *ctxt)
+{
+    return hvm_read(seg, offset, val, bytes, hvm_access_read,
+                    container_of(ctxt, struct sh_emulate_ctxt, ctxt));
+}
+
+static int
+sh_x86_emulate_insn_fetch(enum x86_segment seg,
+                          unsigned long offset,
+                          unsigned long *val,
                           unsigned int bytes,
                           struct x86_emulate_ctxt *ctxt)
 {
-#if 0
+    struct sh_emulate_ctxt *sh_ctxt =
+        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
+    unsigned int insn_off = offset - ctxt->regs->eip;
+
+    /* Fall back if requested bytes are not in the prefetch cache. */
+    if ( unlikely((insn_off + bytes) > sh_ctxt->insn_buf_bytes) )
+        return hvm_read(seg, offset, val, bytes,
+                        hvm_access_insn_fetch, sh_ctxt);
+
+    /* Hit the cache. Simple memcpy. */
+    *val = 0;
+    memcpy(val, &sh_ctxt->insn_buf[insn_off], bytes);
+    return X86EMUL_CONTINUE;
+}
+
+static int
+sh_x86_emulate_write(enum x86_segment seg,
+                     unsigned long offset,
+                     unsigned long val,
+                     unsigned int bytes,
+                     struct x86_emulate_ctxt *ctxt)
+{
+    struct sh_emulate_ctxt *sh_ctxt =
+        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
     struct vcpu *v = current;
-    SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
-                  v->domain->domain_id, v->vcpu_id, addr, val, bytes);
-#endif
-
-    // XXX -- this is WRONG.
-    //        It entirely ignores the permissions in the page tables.
-    //        In this case, that includes user vs supervisor, and
-    //        write access.
-    //
-    if ( hvm_copy_to_guest_virt(addr, &val, bytes) == 0 )
-        return X86EMUL_CONTINUE;
-
-    /* If we got here, there was nothing mapped here, or a bad GFN 
-     * was mapped here.  This should never happen: we're here because
-     * of a write fault at the end of the instruction we're emulating,
-     * which should be handled by sh_x86_emulate_write_emulated. */ 
-    SHADOW_PRINTK("write failed to va %#lx\n", addr);
-    return X86EMUL_PROPAGATE_FAULT;
-}
-
-static int
-sh_x86_emulate_write_emulated(unsigned long addr,
-                               unsigned long val,
-                               unsigned int bytes,
-                               struct x86_emulate_ctxt *ctxt)
-{
-    struct vcpu *v = current;
+    unsigned long addr;
+    int rc;
+
+    rc = hvm_translate_linear_addr(
+        seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
+    if ( rc )
+        return rc;
+
 #if 0
     SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
                   v->domain->domain_id, v->vcpu_id, addr, val, bytes);
 #endif
-    return v->arch.shadow.mode->x86_emulate_write(v, addr, &val, bytes, ctxt);
+    return v->arch.shadow.mode->x86_emulate_write(
+        v, addr, &val, bytes, sh_ctxt);
 }
 
 static int 
-sh_x86_emulate_cmpxchg_emulated(unsigned long addr,
-                                 unsigned long old,
-                                 unsigned long new,
-                                 unsigned int bytes,
-                                 struct x86_emulate_ctxt *ctxt)
-{
+sh_x86_emulate_cmpxchg(enum x86_segment seg,
+                       unsigned long offset,
+                       unsigned long old,
+                       unsigned long new,
+                       unsigned int bytes,
+                       struct x86_emulate_ctxt *ctxt)
+{
+    struct sh_emulate_ctxt *sh_ctxt =
+        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
     struct vcpu *v = current;
+    unsigned long addr;
+    int rc;
+
+    rc = hvm_translate_linear_addr(
+        seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
+    if ( rc )
+        return rc;
+
 #if 0
     SHADOW_PRINTK("d=%u v=%u a=%#lx o?=%#lx n:=%#lx bytes=%u\n",
                    v->domain->domain_id, v->vcpu_id, addr, old, new, bytes);
 #endif
-    return v->arch.shadow.mode->x86_emulate_cmpxchg(v, addr, old, new,
-                                                     bytes, ctxt);
+    return v->arch.shadow.mode->x86_emulate_cmpxchg(
+        v, addr, old, new, bytes, sh_ctxt);
 }
 
 static int 
-sh_x86_emulate_cmpxchg8b_emulated(unsigned long addr,
-                                   unsigned long old_lo,
-                                   unsigned long old_hi,
-                                   unsigned long new_lo,
-                                   unsigned long new_hi,
-                                   struct x86_emulate_ctxt *ctxt)
-{
+sh_x86_emulate_cmpxchg8b(enum x86_segment seg,
+                         unsigned long offset,
+                         unsigned long old_lo,
+                         unsigned long old_hi,
+                         unsigned long new_lo,
+                         unsigned long new_hi,
+                         struct x86_emulate_ctxt *ctxt)
+{
+    struct sh_emulate_ctxt *sh_ctxt =
+        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
     struct vcpu *v = current;
+    unsigned long addr;
+    int rc;
+
+    rc = hvm_translate_linear_addr(
+        seg, offset, 8, hvm_access_write, sh_ctxt, &addr);
+    if ( rc )
+        return rc;
+
 #if 0
     SHADOW_PRINTK("d=%u v=%u a=%#lx o?=%#lx:%lx n:=%#lx:%lx\n",
                    v->domain->domain_id, v->vcpu_id, addr, old_hi, old_lo,
                    new_hi, new_lo, ctxt);
 #endif
-    return v->arch.shadow.mode->x86_emulate_cmpxchg8b(v, addr, old_lo, old_hi,
-                                                       new_lo, new_hi, ctxt);
+    return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
+        v, addr, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
 }
 
 
 struct x86_emulate_ops shadow_emulator_ops = {
-    .read_std           = sh_x86_emulate_read_std,
-    .write_std          = sh_x86_emulate_write_std,
-    .read_emulated      = sh_x86_emulate_read_std,
-    .write_emulated     = sh_x86_emulate_write_emulated,
-    .cmpxchg_emulated   = sh_x86_emulate_cmpxchg_emulated,
-    .cmpxchg8b_emulated = sh_x86_emulate_cmpxchg8b_emulated,
+    .read       = sh_x86_emulate_read,
+    .insn_fetch = sh_x86_emulate_insn_fetch,
+    .write      = sh_x86_emulate_write,
+    .cmpxchg    = sh_x86_emulate_cmpxchg,
+    .cmpxchg8b  = sh_x86_emulate_cmpxchg8b,
 };
 
 /**************************************************************************/
@@ -938,12 +1117,13 @@ shadow_set_p2m_entry(struct domain *d, u
     void *table = sh_map_domain_page(table_mfn);
     unsigned long gfn_remainder = gfn;
     l1_pgentry_t *p2m_entry;
+    int rv=0;
 
 #if CONFIG_PAGING_LEVELS >= 4
     if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
                          L4_PAGETABLE_SHIFT - PAGE_SHIFT,
                          L4_PAGETABLE_ENTRIES, PGT_l3_page_table) )
-        return 0;
+        goto out;
 #endif
 #if CONFIG_PAGING_LEVELS >= 3
     // When using PAE Xen, we only allow 33 bits of pseudo-physical
@@ -957,12 +1137,12 @@ shadow_set_p2m_entry(struct domain *d, u
                           ? 8
                           : L3_PAGETABLE_ENTRIES),
                          PGT_l2_page_table) )
-        return 0;
+        goto out;
 #endif
     if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
                          L2_PAGETABLE_SHIFT - PAGE_SHIFT,
                          L2_PAGETABLE_ENTRIES, PGT_l1_page_table) )
-        return 0;
+        goto out;
 
     p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn,
                                0, L1_PAGETABLE_ENTRIES);
@@ -981,9 +1161,12 @@ shadow_set_p2m_entry(struct domain *d, u
         (void)__shadow_validate_guest_entry(
             d->vcpu[0], table_mfn, p2m_entry, sizeof(*p2m_entry));
 
+    /* Success */
+    rv = 1;
+ 
+ out:
     sh_unmap_domain_page(table);
-
-    return 1;
+    return rv;
 }
 
 // Allocate a new p2m table for a domain.
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c    Mon Dec 04 08:24:41 2006 -0700
@@ -581,7 +581,7 @@ guest_index(void *ptr)
     return (u32)((unsigned long)ptr & ~PAGE_MASK) / sizeof(guest_l1e_t);
 }
 
-static inline u32
+static u32
 shadow_l1_index(mfn_t *smfn, u32 guest_index)
 {
 #if (GUEST_PAGING_LEVELS == 2) && (SHADOW_PAGING_LEVELS != 2)
@@ -593,7 +593,7 @@ shadow_l1_index(mfn_t *smfn, u32 guest_i
 #endif
 }
 
-static inline u32
+static u32
 shadow_l2_index(mfn_t *smfn, u32 guest_index)
 {
 #if (GUEST_PAGING_LEVELS == 2) && (SHADOW_PAGING_LEVELS != 2)
@@ -613,13 +613,13 @@ shadow_l2_index(mfn_t *smfn, u32 guest_i
 
 #if GUEST_PAGING_LEVELS >= 4
 
-static inline u32
+static u32
 shadow_l3_index(mfn_t *smfn, u32 guest_index)
 {
     return guest_index;
 }
 
-static inline u32
+static u32
 shadow_l4_index(mfn_t *smfn, u32 guest_index)
 {
     return guest_index;
@@ -2582,7 +2582,7 @@ static int sh_page_fault(struct vcpu *v,
     mfn_t gmfn, sl1mfn=_mfn(0);
     shadow_l1e_t sl1e, *ptr_sl1e;
     paddr_t gpa;
-    struct x86_emulate_ctxt emul_ctxt;
+    struct sh_emulate_ctxt emul_ctxt;
     int r, mmio;
     fetch_type_t ft = 0;
 
@@ -2808,26 +2808,21 @@ static int sh_page_fault(struct vcpu *v,
     return EXCRET_fault_fixed;
 
  emulate:
-    /* Take the register set we were called with */
-    if ( is_hvm_domain(d) )
-        hvm_store_cpu_guest_regs(v, regs, NULL);
-    emul_ctxt.regs = regs;
-    emul_ctxt.cr2  = va;
-    emul_ctxt.mode = (is_hvm_domain(d) ?
-                      hvm_guest_x86_mode(v) : X86EMUL_MODE_HOST);
-
+    if ( !is_hvm_domain(d) || !guest_mode(regs) )
+        goto not_a_shadow_fault;
+
+    hvm_store_cpu_guest_regs(v, regs, NULL);
     SHADOW_PRINTK("emulate: eip=%#lx\n", regs->eip);
 
-    v->arch.shadow.propagate_fault = 0;
+    shadow_init_emulation(&emul_ctxt, regs);
 
     /*
      * We do not emulate user writes. Instead we use them as a hint that the
      * page is no longer a page table. This behaviour differs from native, but
      * it seems very unlikely that any OS grants user access to page tables.
-     * We also disallow guest PTE updates from within Xen.
      */
-    if ( (regs->error_code & PFEC_user_mode) || !guest_mode(regs) ||
-         x86_emulate_memop(&emul_ctxt, &shadow_emulator_ops) )
+    if ( (regs->error_code & PFEC_user_mode) ||
+         x86_emulate_memop(&emul_ctxt.ctxt, &shadow_emulator_ops) )
     {
         SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", 
                        mfn_x(gmfn));
@@ -2836,19 +2831,10 @@ static int sh_page_fault(struct vcpu *v,
          * to support more operations in the emulator.  More likely, 
          * though, this is a hint that this page should not be shadowed. */
         shadow_remove_all_shadows(v, gmfn);
-        /* This means that actual missing operations will cause the 
-         * guest to loop on the same page fault. */
-        goto done;
-    }
-
-    /* Emulation triggered another page fault? */
-    if ( v->arch.shadow.propagate_fault )
-        goto not_a_shadow_fault;
+    }
 
     /* Emulator has changed the user registers: write back */
-    if ( is_hvm_domain(d) )
-        hvm_load_cpu_guest_regs(v, regs);
-
+    hvm_load_cpu_guest_regs(v, regs);
     goto done;
 
  mmio:
@@ -3787,11 +3773,11 @@ int sh_remove_l3_shadow(struct vcpu *v, 
  * or NULL for error. */
 static inline void * emulate_map_dest(struct vcpu *v,
                                       unsigned long vaddr,
-                                      struct x86_emulate_ctxt *ctxt,
+                                      struct sh_emulate_ctxt *sh_ctxt,
                                       mfn_t *mfnp)
 {
     walk_t gw;
-    u32 flags;
+    u32 flags, errcode;
     gfn_t gfn;
     mfn_t mfn;
 
@@ -3802,13 +3788,17 @@ static inline void * emulate_map_dest(st
     sh_audit_gw(v, &gw);
     unmap_walk(v, &gw);
 
-    if ( !(flags & _PAGE_PRESENT) 
-         || !(flags & _PAGE_RW) 
-         || (!(flags & _PAGE_USER) && ring_3(ctxt->regs)) )
-    {
-        /* This write would have faulted even on bare metal */
-        v->arch.shadow.propagate_fault = 1;
-        return NULL;
+    if ( !(flags & _PAGE_PRESENT) )
+    {
+        errcode = 0;
+        goto page_fault;
+    }
+
+    if ( !(flags & _PAGE_RW) ||
+         (!(flags & _PAGE_USER) && ring_3(sh_ctxt->ctxt.regs)) )
+    {
+        errcode = PFEC_page_present;
+        goto page_fault;
     }
 
     /* Attempted a write to a bad gfn? This should never happen:
@@ -3818,11 +3808,18 @@ static inline void * emulate_map_dest(st
     ASSERT(sh_mfn_is_a_page_table(mfn));
     *mfnp = mfn;
     return sh_map_domain_page(mfn) + (vaddr & ~PAGE_MASK);
+
+ page_fault:
+    errcode |= PFEC_write_access;
+    if ( ring_3(sh_ctxt->ctxt.regs) )
+        errcode |= PFEC_user_mode;
+    hvm_inject_exception(TRAP_page_fault, errcode, vaddr);
+    return NULL;
 }
 
 int
 sh_x86_emulate_write(struct vcpu *v, unsigned long vaddr, void *src,
-                      u32 bytes, struct x86_emulate_ctxt *ctxt)
+                      u32 bytes, struct sh_emulate_ctxt *sh_ctxt)
 {
     mfn_t mfn;
     void *addr;
@@ -3833,7 +3830,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
     ASSERT(shadow_lock_is_acquired(v->domain));
     ASSERT(((vaddr & ~PAGE_MASK) + bytes) <= PAGE_SIZE);
 
-    if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
+    if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
         return X86EMUL_PROPAGATE_FAULT;
 
     memcpy(addr, src, bytes);
@@ -3851,7 +3848,7 @@ int
 int
 sh_x86_emulate_cmpxchg(struct vcpu *v, unsigned long vaddr, 
                         unsigned long old, unsigned long new,
-                        unsigned int bytes, struct x86_emulate_ctxt *ctxt)
+                        unsigned int bytes, struct sh_emulate_ctxt *sh_ctxt)
 {
     mfn_t mfn;
     void *addr;
@@ -3864,7 +3861,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
     if ( vaddr & (bytes-1) )
         return X86EMUL_UNHANDLEABLE;
 
-    if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
+    if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
         return X86EMUL_PROPAGATE_FAULT;
 
     switch ( bytes )
@@ -3900,7 +3897,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
 sh_x86_emulate_cmpxchg8b(struct vcpu *v, unsigned long vaddr, 
                           unsigned long old_lo, unsigned long old_hi,
                           unsigned long new_lo, unsigned long new_hi,
-                          struct x86_emulate_ctxt *ctxt)
+                          struct sh_emulate_ctxt *sh_ctxt)
 {
     mfn_t mfn;
     void *addr;
@@ -3912,7 +3909,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
     if ( vaddr & 7 )
         return X86EMUL_UNHANDLEABLE;
 
-    if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
+    if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
         return X86EMUL_PROPAGATE_FAULT;
 
     old = (((u64) old_hi) << 32) | (u64) old_lo;
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h  Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm/shadow/private.h  Mon Dec 04 08:24:41 2006 -0700
@@ -506,6 +506,25 @@ static inline void sh_unpin(struct vcpu 
     }
 }
 
+
+/**************************************************************************/
+/* PTE-write emulation. */
+
+struct sh_emulate_ctxt {
+    struct x86_emulate_ctxt ctxt;
+
+    /* Cache of up to 15 bytes of instruction. */
+    uint8_t insn_buf[15];
+    uint8_t insn_buf_bytes;
+
+    /* Cache of segment registers already gathered for this emulation. */
+    unsigned int valid_seg_regs;
+    struct segment_register seg_reg[6];
+};
+
+void shadow_init_emulation(struct sh_emulate_ctxt *sh_ctxt,
+                           struct cpu_user_regs *regs);
+
 #endif /* _XEN_SHADOW_PRIVATE_H */
 
 /*
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/oprofile/op_model_athlon.c
--- a/xen/arch/x86/oprofile/op_model_athlon.c   Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/oprofile/op_model_athlon.c   Mon Dec 04 08:24:41 2006 -0700
@@ -113,14 +113,15 @@ static int athlon_check_ctrs(unsigned in
        unsigned long eip = regs->eip;
        int mode = 0;
        struct vcpu *v = current;
-       struct cpu_user_regs tmp_regs;
+       struct cpu_user_regs *guest_regs = guest_cpu_user_regs();
 
        if (!guest_mode(regs) &&
            (regs->eip == (unsigned long)svm_stgi_label)) {
                /* SVM guest was running when NMI occurred */
-               hvm_store_cpu_guest_regs(v, &tmp_regs, NULL);
-               eip = tmp_regs.eip;
-               mode = xenoprofile_get_mode(v, &tmp_regs);
+               ASSERT(is_hvm_vcpu(v));
+               hvm_store_cpu_guest_regs(v, guest_regs, NULL);
+               eip = guest_regs->eip;
+               mode = xenoprofile_get_mode(v, guest_regs);
        } else {
                eip = regs->eip;
                mode = xenoprofile_get_mode(v, regs);
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/setup.c      Mon Dec 04 08:24:41 2006 -0700
@@ -27,6 +27,7 @@
 #include <asm/shadow.h>
 #include <asm/e820.h>
 #include <acm/acm_hooks.h>
+#include <xen/kexec.h>
 
 extern void dmi_scan_machine(void);
 extern void generic_apic_probe(void);
@@ -273,6 +274,20 @@ static void srat_detect_node(int cpu)
         printk(KERN_INFO "CPU %d APIC %d -> Node %d\n", cpu, apicid, node);
 }
 
+void __init move_memory(unsigned long dst,
+                          unsigned long src_start, unsigned long src_end)
+{
+#if defined(CONFIG_X86_32)
+    memmove((void *)dst,            /* use low mapping */
+            (void *)src_start,      /* use low mapping */
+            src_end - src_start);
+#elif defined(CONFIG_X86_64)
+    memmove(__va(dst),
+            __va(src_start),
+            src_end - src_start);
+#endif
+}
+
 void __init __start_xen(multiboot_info_t *mbi)
 {
     char __cmdline[] = "", *cmdline = __cmdline;
@@ -415,15 +430,8 @@ void __init __start_xen(multiboot_info_t
         initial_images_start = xenheap_phys_end;
     initial_images_end = initial_images_start + modules_length;
 
-#if defined(CONFIG_X86_32)
-    memmove((void *)initial_images_start,  /* use low mapping */
-            (void *)mod[0].mod_start,      /* use low mapping */
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
-#elif defined(CONFIG_X86_64)
-    memmove(__va(initial_images_start),
-            __va(mod[0].mod_start),
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
-#endif
+    move_memory(initial_images_start, 
+                mod[0].mod_start, mod[mbi->mods_count-1].mod_end);
 
     /* Initialise boot-time allocator with all RAM situated after modules. */
     xenheap_phys_start = init_boot_allocator(__pa(&_end));
@@ -471,10 +479,56 @@ void __init __start_xen(multiboot_info_t
 #endif
     }
 
+    if ( kexec_crash_area.size > 0 )
+    {
+        unsigned long kdump_start, kdump_size, k;
+
+        /* Mark images pages as free for now. */
+
+        init_boot_pages(initial_images_start, initial_images_end);
+
+        kdump_start = kexec_crash_area.start;
+        kdump_size = kexec_crash_area.size;
+
+        printk("Kdump: %luMB (%lukB) at 0x%lx\n",
+               kdump_size >> 20,
+               kdump_size >> 10,
+               kdump_start);
+
+        if ( (kdump_start & ~PAGE_MASK) || (kdump_size & ~PAGE_MASK) )
+            panic("Kdump parameters not page aligned\n");
+
+        kdump_start >>= PAGE_SHIFT;
+        kdump_size >>= PAGE_SHIFT;
+
+        /* allocate pages for Kdump memory area */
+
+        k = alloc_boot_pages_at(kdump_size, kdump_start);
+
+        if ( k != kdump_start )
+            panic("Unable to reserve Kdump memory\n");
+
+        /* allocate pages for relocated initial images */
+
+        k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
+        k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
+
+        k = alloc_boot_pages(k, 1);
+
+        if ( !k )
+            panic("Unable to allocate initial images memory\n");
+
+        move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end);
+
+        initial_images_end -= initial_images_start;
+        initial_images_start = k << PAGE_SHIFT;
+        initial_images_end += initial_images_start;
+    }
+
     memguard_init();
     percpu_guard_areas();
 
-    printk("System RAM: %luMB (%lukB)\n", 
+    printk("System RAM: %luMB (%lukB)\n",
            nr_pages >> (20 - PAGE_SHIFT),
            nr_pages << (PAGE_SHIFT - 10));
     total_pages = nr_pages;
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/traps.c      Mon Dec 04 08:24:41 2006 -0700
@@ -45,6 +45,7 @@
 #include <xen/iocap.h>
 #include <xen/nmi.h>
 #include <xen/version.h>
+#include <xen/kexec.h>
 #include <asm/shadow.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1633,6 +1634,7 @@ static void unknown_nmi_error(unsigned c
         printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
         printk("Dazed and confused, but trying to continue\n");
         printk("Do you have a strange power saving mode enabled?\n");
+        machine_crash_kexec();
     }
 }
 
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/x86_32/entry.S       Mon Dec 04 08:24:41 2006 -0700
@@ -659,6 +659,7 @@ ENTRY(hypercall_table)
         .long do_hvm_op
         .long do_sysctl             /* 35 */
         .long do_domctl
+        .long do_kexec_op
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
@@ -701,6 +702,7 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_hvm_op            */
         .byte 1 /* do_sysctl            */  /* 35 */
         .byte 1 /* do_domctl            */
+        .byte 2 /* do_kexec_op          */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/x86_64/entry.S       Mon Dec 04 08:24:41 2006 -0700
@@ -559,6 +559,7 @@ ENTRY(hypercall_table)
         .quad do_hvm_op
         .quad do_sysctl             /* 35 */
         .quad do_domctl
+        .quad do_kexec_op
         .rept NR_hypercalls-((.-hypercall_table)/8)
         .quad do_ni_hypercall
         .endr
@@ -601,6 +602,7 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_hvm_op            */
         .byte 1 /* do_sysctl            */  /* 35 */
         .byte 1 /* do_domctl            */
+        .byte 2 /* do_kexec             */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/x86_emulate.c        Mon Dec 04 08:24:41 2006 -0700
@@ -7,24 +7,17 @@
  */
 
 #ifndef __XEN__
-#include <stdio.h>
+#include <stddef.h>
 #include <stdint.h>
 #include <public/xen.h>
-#define dprintf(_f, _a...) printf( _f , ## _a )
 #else
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/lib.h>
-#include <xen/mm.h>
 #include <asm/regs.h>
-#define dprintf(_f, _a...) gdprintk(XENLOG_WARNING, _f , ## _a )
+#undef cmpxchg
 #endif
 #include <asm-x86/x86_emulate.h>
-
-#ifndef PFEC_write_access
-#define PFEC_write_access (1U<<1)
-#define PFEC_insn_fetch   (1U<<4)
-#endif
 
 /*
  * Opcode effective-address decode tables.
@@ -38,6 +31,7 @@
 /* Operand sizes: 8-bit operands or specified/overridden size. */
 #define ByteOp      (1<<0) /* 8-bit operands. */
 /* Destination operand type. */
+#define DstBitBase  (0<<1) /* Memory operand, bit string. */
 #define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
 #define DstReg      (2<<1) /* Register operand. */
 #define DstMem      (3<<1) /* Memory operand. */
@@ -111,8 +105,8 @@ static uint8_t opcode_table[256] = {
     /* 0x90 - 0x9F */
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xA0 - 0xA7 */
-    ByteOp|DstReg|SrcMem|Mov, DstReg|SrcMem|Mov,
-    ByteOp|DstMem|SrcReg|Mov, DstMem|SrcReg|Mov,
+    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
+    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
     ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0,
     /* 0xA8 - 0xAF */
     0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
@@ -170,17 +164,21 @@ static uint8_t twobyte_table[256] = {
     /* 0x90 - 0x9F */
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xA0 - 0xA7 */
-    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0, 
+    0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0, 
     /* 0xA8 - 0xAF */
-    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
+    0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0,
     /* 0xB0 - 0xB7 */
-    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstMem|SrcReg|ModRM,
+    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
+    0, DstBitBase|SrcReg|ModRM,
     0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
     /* 0xB8 - 0xBF */
-    0, 0, DstMem|SrcImmByte|ModRM, DstMem|SrcReg|ModRM,
+    0, 0, DstBitBase|SrcImmByte|ModRM, DstBitBase|SrcReg|ModRM,
     0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
-    /* 0xC0 - 0xCF */
-    0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
+    /* 0xC0 - 0xC7 */
+    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
+    0, 0, 0, ImplicitOps|ModRM,
+    /* 0xC8 - 0xCF */
+    0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xD0 - 0xDF */
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xE0 - 0xEF */
@@ -193,7 +191,12 @@ struct operand {
 struct operand {
     enum { OP_REG, OP_MEM, OP_IMM } type;
     unsigned int  bytes;
-    unsigned long val, orig_val, *ptr;
+    unsigned long val, orig_val;
+    /* OP_REG: Pointer to register field. */
+    unsigned long *reg;
+    /* OP_MEM: Segment and offset. */
+    enum x86_segment mem_seg;
+    unsigned long    mem_off;
 };
 
 /* EFLAGS bit definitions. */
@@ -366,24 +369,23 @@ do{ __asm__ __volatile__ (              
 #endif /* __i386__ */
 
 /* Fetch next part of the instruction being emulated. */
-#define _insn_fetch(_size)                                              \
-({ unsigned long _x, _ptr = _regs.eip;                                  \
-   if ( mode == X86EMUL_MODE_REAL ) _ptr += _regs.cs << 4;              \
-   rc = ops->read_std(_ptr, &_x, (_size), ctxt);                        \
+#define insn_fetch_bytes(_size)                                         \
+({ unsigned long _x;                                                    \
+   rc = ops->insn_fetch(x86_seg_cs, _regs.eip, &_x, (_size), ctxt);     \
    if ( rc != 0 )                                                       \
        goto done;                                                       \
    _regs.eip += (_size);                                                \
    _x;                                                                  \
 })
-#define insn_fetch(_type) ((_type)_insn_fetch(sizeof(_type)))
-
-/* Access/update address held in a register, based on addressing mode. */
-#define register_address(sel, reg)                                      \
-({  unsigned long __reg = (reg);                                        \
-    (((mode == X86EMUL_MODE_REAL) ? ((unsigned long)(sel) << 4) : 0) +  \
-     ((ad_bytes == sizeof(unsigned long)) ? __reg :                     \
-      (__reg & ((1UL << (ad_bytes << 3)) - 1))));                       \
+#define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type)))
+
+#define truncate_ea(ea)                                 \
+({  unsigned long __ea = (ea);                          \
+    ((ad_bytes == sizeof(unsigned long)) ? __ea :       \
+     (__ea & ((1UL << (ad_bytes << 3)) - 1)));          \
 })
+
+/* Update address held in a register, based on addressing mode. */
 #define register_address_increment(reg, inc)                            \
 do {                                                                    \
     int _inc = (inc); /* signed type ensures sign extension to long */  \
@@ -393,17 +395,6 @@ do {                                    
         (reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) |             \
                 (((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1));      \
 } while (0)
-
-/*
- * We cannot handle a page fault on a data access that straddles two pages
- * and faults on the second page. This is because CR2 is not equal to the
- * memory operand's effective address in this case. Rather than fix up the
- * effective address it is okay for us to fail the emulation.
- */
-#define page_boundary_test() do {                               \
-    if ( ((cr2 & (PAGE_SIZE-1)) == 0) && ((ea & 7) != 0) )      \
-        goto bad_ea;                                            \
-} while ( 0 )
 
 void *
 decode_register(
@@ -445,31 +436,6 @@ decode_register(
     return p;
 }
 
-static void
-dump_instr(
-    struct x86_emulate_ctxt *ctxt,
-    struct x86_emulate_ops  *ops)
-{
-#ifdef __XEN__
-    int i;
-    unsigned long x, pc;
-
-    pc = ctxt->regs->eip;
-    if ( ctxt->mode == X86EMUL_MODE_REAL )
-        pc += ctxt->regs->cs << 4;
-
-    dprintf("Instr:");
-    for ( i = 0; i < 16; i++, pc++ )
-    {
-        if ( ops->read_std(pc, &x, 1, ctxt) != 0 )
-            printk(" ??");
-        else
-            printk(" %02x", (uint8_t)x);
-    }
-    printk("\n");
-#endif
-}
-
 int
 x86_emulate_memop(
     struct x86_emulate_ctxt *ctxt,
@@ -480,19 +446,13 @@ x86_emulate_memop(
 
     uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0;
     uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
-    uint16_t *seg = &_regs.ds; /* override segment */
     unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
     int rc = 0;
     struct operand src, dst;
-    unsigned long ea = 0, cr2 = ctxt->cr2;
     int mode = ctxt->mode;
 
-    /*
-     * We do not emulate faults on instruction fetch. We assume that the
-     * guest never executes out of a special memory area.
-     */
-    if ( _regs.error_code & PFEC_insn_fetch )
-        return -1;
+    enum x86_segment ea_seg = x86_seg_ds;
+    unsigned long    ea_off = 0;
 
     switch ( mode )
     {
@@ -516,7 +476,7 @@ x86_emulate_memop(
     /* Legacy prefixes. */
     for ( i = 0; i < 8; i++ )
     {
-        switch ( b = insn_fetch(uint8_t) )
+        switch ( b = insn_fetch_type(uint8_t) )
         {
         case 0x66: /* operand-size override */
             op_bytes ^= 6;      /* switch between 2/4 bytes */
@@ -528,22 +488,22 @@ x86_emulate_memop(
                 ad_bytes ^= 6;  /* switch between 2/4 bytes */
             break;
         case 0x2e: /* CS override */
-            seg = &_regs.cs;
+            ea_seg = x86_seg_cs;
             break;
         case 0x3e: /* DS override */
-            seg = &_regs.ds;
+            ea_seg = x86_seg_ds;
             break;
         case 0x26: /* ES override */
-            seg = &_regs.es;
+            ea_seg = x86_seg_es;
             break;
         case 0x64: /* FS override */
-            seg = &_regs.fs;
+            ea_seg = x86_seg_fs;
             break;
         case 0x65: /* GS override */
-            seg = &_regs.gs;
+            ea_seg = x86_seg_gs;
             break;
         case 0x36: /* SS override */
-            seg = &_regs.ss;
+            ea_seg = x86_seg_ss;
             break;
         case 0xf0: /* LOCK */
             lock_prefix = 1;
@@ -565,7 +525,7 @@ x86_emulate_memop(
         rex_prefix = b;
         if ( b & 8 ) /* REX.W */
             op_bytes = 8;
-        b = insn_fetch(uint8_t);
+        b = insn_fetch_type(uint8_t);
     }
 
     /* Opcode byte(s). */
@@ -576,7 +536,7 @@ x86_emulate_memop(
         if ( b == 0x0f )
         {
             twobyte = 1;
-            b = insn_fetch(uint8_t);
+            b = insn_fetch_type(uint8_t);
             d = twobyte_table[b];
         }
 
@@ -588,36 +548,40 @@ x86_emulate_memop(
     /* ModRM and SIB bytes. */
     if ( d & ModRM )
     {
-        modrm = insn_fetch(uint8_t);
+        modrm = insn_fetch_type(uint8_t);
         modrm_mod = (modrm & 0xc0) >> 6;
         modrm_reg = ((rex_prefix & 4) << 1) | ((modrm & 0x38) >> 3);
         modrm_rm  = modrm & 0x07;
 
         if ( modrm_mod == 3 )
-        {
-            dprintf("Cannot parse ModRM.mod == 3.\n");
             goto cannot_emulate;
-        }
 
         if ( ad_bytes == 2 )
         {
             /* 16-bit ModR/M decode. */
             switch ( modrm_rm )
             {
-            case 0: ea = _regs.ebx + _regs.esi; break;
-            case 1: ea = _regs.ebx + _regs.edi; break;
-            case 2: ea = _regs.ebp + _regs.esi; break;
-            case 3: ea = _regs.ebp + _regs.edi; break;
-            case 4: ea = _regs.esi; break;
-            case 5: ea = _regs.edi; break;
-            case 6: ea = _regs.ebp; break;
-            case 7: ea = _regs.ebx; break;
+            case 0: ea_off = _regs.ebx + _regs.esi; break;
+            case 1: ea_off = _regs.ebx + _regs.edi; break;
+            case 2: ea_off = _regs.ebp + _regs.esi; break;
+            case 3: ea_off = _regs.ebp + _regs.edi; break;
+            case 4: ea_off = _regs.esi; break;
+            case 5: ea_off = _regs.edi; break;
+            case 6: ea_off = _regs.ebp; break;
+            case 7: ea_off = _regs.ebx; break;
             }
             switch ( modrm_mod )
             {
-            case 0: if ( modrm_rm == 6 ) ea = insn_fetch(int16_t); break;
-            case 1: ea += insn_fetch(int8_t);  break;
-            case 2: ea += insn_fetch(int16_t); break;
+            case 0:
+                if ( modrm_rm == 6 )
+                    ea_off = insn_fetch_type(int16_t);
+                break;
+            case 1:
+                ea_off += insn_fetch_type(int8_t);
+                break;
+            case 2:
+                ea_off += insn_fetch_type(int16_t);
+                break;
             }
         }
         else
@@ -625,87 +589,58 @@ x86_emulate_memop(
             /* 32/64-bit ModR/M decode. */
             if ( modrm_rm == 4 )
             {
-                sib = insn_fetch(uint8_t);
-                sib_index = ((sib >> 3) & 7) | ((modrm << 2) & 8);
-                sib_base  = (sib & 7) | ((modrm << 3) & 8);
+                sib = insn_fetch_type(uint8_t);
+                sib_index = ((sib >> 3) & 7) | ((rex_prefix << 2) & 8);
+                sib_base  = (sib & 7) | ((rex_prefix << 3) & 8);
                 if ( sib_index != 4 )
-                    ea = *(long *)decode_register(sib_index, &_regs, 0);
-                ea <<= (sib >> 6) & 3;
+                    ea_off = *(long *)decode_register(sib_index, &_regs, 0);
+                ea_off <<= (sib >> 6) & 3;
                 if ( (modrm_mod == 0) && ((sib_base & 7) == 5) )
-                    ea += insn_fetch(int32_t);
+                    ea_off += insn_fetch_type(int32_t);
                 else
-                    ea += *(long *)decode_register(sib_base, &_regs, 0);
+                    ea_off += *(long *)decode_register(sib_base, &_regs, 0);
             }
             else
             {
                 modrm_rm |= (rex_prefix & 1) << 3;
-                ea = *(long *)decode_register(modrm_rm, &_regs, 0);
+                ea_off = *(long *)decode_register(modrm_rm, &_regs, 0);
             }
             switch ( modrm_mod )
             {
             case 0:
                 if ( (modrm_rm & 7) != 5 )
                     break;
-                ea = insn_fetch(int32_t);
+                ea_off = insn_fetch_type(int32_t);
                 if ( mode != X86EMUL_MODE_PROT64 )
                     break;
                 /* Relative to RIP of next instruction. Argh! */
-                ea += _regs.eip;
+                ea_off += _regs.eip;
                 if ( (d & SrcMask) == SrcImm )
-                    ea += (d & ByteOp) ? 1 : ((op_bytes == 8) ? 4 : op_bytes);
+                    ea_off += (d & ByteOp) ? 1 :
+                        ((op_bytes == 8) ? 4 : op_bytes);
                 else if ( (d & SrcMask) == SrcImmByte )
-                    ea += 1;
+                    ea_off += 1;
                 else if ( ((b == 0xf6) || (b == 0xf7)) &&
                           ((modrm_reg & 7) <= 1) )
                     /* Special case in Grp3: test has immediate operand. */
-                    ea += (d & ByteOp) ? 1
+                    ea_off += (d & ByteOp) ? 1
                         : ((op_bytes == 8) ? 4 : op_bytes);
                 break;
-            case 1: ea += insn_fetch(int8_t);  break;
-            case 2: ea += insn_fetch(int32_t); break;
+            case 1:
+                ea_off += insn_fetch_type(int8_t);
+                break;
+            case 2:
+                ea_off += insn_fetch_type(int32_t);
+                break;
             }
         }
 
-        ea = register_address(*seg, ea);
-        page_boundary_test();
-    }
-
-    /* Decode and fetch the destination operand: register or memory. */
-    switch ( d & DstMask )
-    {
-    case ImplicitOps:
-        /* Special instructions do their own operand decoding. */
+        ea_off = truncate_ea(ea_off);
+    }
+
+    /* Special instructions do their own operand decoding. */
+    if ( (d & DstMask) == ImplicitOps )
         goto special_insn;
-    case DstReg:
-        dst.type = OP_REG;
-        if ( d & ByteOp )
-        {
-            dst.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
-            dst.val = *(uint8_t *)dst.ptr;
-            dst.bytes = 1;
-        }
-        else
-        {
-            dst.ptr = decode_register(modrm_reg, &_regs, 0);
-            switch ( (dst.bytes = op_bytes) )
-            {
-            case 2: dst.val = *(uint16_t *)dst.ptr; break;
-            case 4: dst.val = *(uint32_t *)dst.ptr; break;
-            case 8: dst.val = *(uint64_t *)dst.ptr; break;
-            }
-        }
-        break;
-    case DstMem:
-        dst.type  = OP_MEM;
-        dst.ptr   = (unsigned long *)cr2;
-        dst.bytes = (d & ByteOp) ? 1 : op_bytes;
-        if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
-             ((rc = ops->read_emulated((unsigned long)dst.ptr,
-                                       &dst.val, dst.bytes, ctxt)) != 0) )
-             goto done;
-        break;
-    }
-    dst.orig_val = dst.val;
 
     /* Decode and fetch the source operand: register, memory or immediate. */
     switch ( d & SrcMask )
@@ -716,18 +651,18 @@ x86_emulate_memop(
         src.type = OP_REG;
         if ( d & ByteOp )
         {
-            src.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
-            src.val = src.orig_val = *(uint8_t *)src.ptr;
+            src.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
+            src.val = src.orig_val = *(uint8_t *)src.reg;
             src.bytes = 1;
         }
         else
         {
-            src.ptr = decode_register(modrm_reg, &_regs, 0);
+            src.reg = decode_register(modrm_reg, &_regs, 0);
             switch ( (src.bytes = op_bytes) )
             {
-            case 2: src.val = src.orig_val = *(uint16_t *)src.ptr; break;
-            case 4: src.val = src.orig_val = *(uint32_t *)src.ptr; break;
-            case 8: src.val = src.orig_val = *(uint64_t *)src.ptr; break;
+            case 2: src.val = src.orig_val = *(uint16_t *)src.reg; break;
+            case 4: src.val = src.orig_val = *(uint32_t *)src.reg; break;
+            case 8: src.val = src.orig_val = *(uint64_t *)src.reg; break;
             }
         }
         break;
@@ -741,32 +676,101 @@ x86_emulate_memop(
         src.bytes = (d & ByteOp) ? 1 : op_bytes;
     srcmem_common:
         src.type  = OP_MEM;
-        src.ptr   = (unsigned long *)cr2;
-        if ( (rc = ops->read_emulated((unsigned long)src.ptr, 
-                                      &src.val, src.bytes, ctxt)) != 0 )
+        src.mem_seg = ea_seg;
+        src.mem_off = ea_off;
+        if ( (rc = ops->read(src.mem_seg, src.mem_off,
+                             &src.val, src.bytes, ctxt)) != 0 )
             goto done;
         src.orig_val = src.val;
         break;
     case SrcImm:
         src.type  = OP_IMM;
-        src.ptr   = (unsigned long *)_regs.eip;
         src.bytes = (d & ByteOp) ? 1 : op_bytes;
         if ( src.bytes == 8 ) src.bytes = 4;
         /* NB. Immediates are sign-extended as necessary. */
         switch ( src.bytes )
         {
-        case 1: src.val = insn_fetch(int8_t);  break;
-        case 2: src.val = insn_fetch(int16_t); break;
-        case 4: src.val = insn_fetch(int32_t); break;
+        case 1: src.val = insn_fetch_type(int8_t);  break;
+        case 2: src.val = insn_fetch_type(int16_t); break;
+        case 4: src.val = insn_fetch_type(int32_t); break;
         }
         break;
     case SrcImmByte:
         src.type  = OP_IMM;
-        src.ptr   = (unsigned long *)_regs.eip;
         src.bytes = 1;
-        src.val   = insn_fetch(int8_t);
-        break;
-    }
+        src.val   = insn_fetch_type(int8_t);
+        break;
+    }
+
+    /* Decode and fetch the destination operand: register or memory. */
+    switch ( d & DstMask )
+    {
+    case DstReg:
+        dst.type = OP_REG;
+        if ( d & ByteOp )
+        {
+            dst.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
+            dst.val = *(uint8_t *)dst.reg;
+            dst.bytes = 1;
+        }
+        else
+        {

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