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

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



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 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


 


Rackspace

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