WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 04 Apr 2007 13:30:17 -0700
Delivery-date: Wed, 04 Apr 2007 13:30:04 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1175296722 21600
# Node ID fc9e2f7920c95229caaf5ad8fc44965dd891f600
# Parent  e7da2fcb7a226a4a96a97f1c17711649309aa15c
# Parent  b0b20a09d2534a97dd871c1fe787af9a32864c0c
merge with xen-unstable.hg
---
 .hgignore                                                           |    1 
 Config.mk                                                           |   14 
 docs/xen-api/xenapi-datamodel.tex                                   |  273 ++
 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S                 |   16 
 linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c                |    2 
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c                 |    2 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c                  |    1 
 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c              |    2 
 linux-2.6-xen-sparse/drivers/xen/core/reboot.c                      |   19 
 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c                    |   35 
 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c |   35 
 linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c        |   14 
 linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c                 |   53 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c                |  104 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c              |   60 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h              |    1 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c      |   25 
 tools/Rules.mk                                                      |    6 
 tools/examples/Makefile                                             |    2 
 tools/examples/xend-config-xenapi.sxp                               |  195 +
 tools/examples/xend-config.sxp                                      |   14 
 tools/examples/xm-config-xenapi.xml                                 |   43 
 tools/ioemu/hw/ne2000.c                                             |   13 
 tools/ioemu/hw/pcnet.c                                              |   58 
 tools/ioemu/hw/piix4acpi.c                                          |   20 
 tools/ioemu/hw/rtl8139.c                                            |    9 
 tools/ioemu/hw/usb-uhci.c                                           |    1 
 tools/ioemu/vl.c                                                    |    7 
 tools/libxc/xc_hvm_restore.c                                        |   29 
 tools/libxen/Makefile                                               |    3 
 tools/libxen/include/xen_event.h                                    |  102 
 tools/libxen/include/xen_event_decl.h                               |   25 
 tools/libxen/include/xen_event_operation.h                          |   82 
 tools/libxen/include/xen_event_operation_internal.h                 |   37 
 tools/libxen/include/xen_network.h                                  |   33 
 tools/libxen/src/xen_common.c                                       |  132 -
 tools/libxen/src/xen_event.c                                        |  123 
 tools/libxen/src/xen_event_operation.c                              |   75 
 tools/libxen/src/xen_network.c                                      |   74 
 tools/libxen/test/test_event_handling.c                             |  211 +
 tools/pygrub/src/pygrub                                             |   17 
 tools/python/xen/lowlevel/xc/xc.c                                   |   28 
 tools/python/xen/util/xmlrpcclient.py                               |  123 
 tools/python/xen/util/xmlrpclib2.py                                 |   71 
 tools/python/xen/xend/XendAPI.py                                    |  400 ++-
 tools/python/xen/xend/XendCheckpoint.py                             |    8 
 tools/python/xen/xend/XendClient.py                                 |    2 
 tools/python/xen/xend/XendConfig.py                                 |   15 
 tools/python/xen/xend/XendConstants.py                              |    7 
 tools/python/xen/xend/XendDomain.py                                 |   20 
 tools/python/xen/xend/XendDomainInfo.py                             |   20 
 tools/python/xen/xend/XendLogging.py                                |    1 
 tools/python/xen/xend/XendMonitor.py                                |   16 
 tools/python/xen/xend/XendNetwork.py                                |   43 
 tools/python/xen/xend/XendNode.py                                   |   32 
 tools/python/xen/xend/XendOptions.py                                |    8 
 tools/python/xen/xend/XendPIFMetrics.py                             |    8 
 tools/python/xen/xend/XendStateStore.py                             |   13 
 tools/python/xen/xend/XendVMMetrics.py                              |   11 
 tools/python/xen/xend/server/SSLXMLRPCServer.py                     |  103 
 tools/python/xen/xend/server/SrvDaemon.py                           |   94 
 tools/python/xen/xend/server/SrvServer.py                           |   96 
 tools/python/xen/xend/server/XMLRPCServer.py                        |   50 
 tools/python/xen/xm/XenAPI.py                                       |   16 
 tools/python/xen/xm/create.dtd                                      |   17 
 tools/python/xen/xm/create.py                                       |   68 
 tools/python/xen/xm/main.py                                         |   68 
 tools/python/xen/xm/messages/en/xen-xm.po                           |    5 
 tools/python/xen/xm/opts.py                                         |   19 
 tools/python/xen/xm/xenapi_create.py                                |  193 +
 tools/security/policies/security_policy.xsd                         |   15 
 tools/security/secpol_tool.c                                        |   62 
 tools/security/secpol_xml2bin.c                                     |   78 
 tools/security/secpol_xml2bin.h                                     |   60 
 tools/xcutils/xc_restore.c                                          |    2 
 tools/xm-test/lib/XmTestLib/XenAPIDomain.py                         |    1 
 tools/xm-test/tests/destroy/06_destroy_dom0_neg.py                  |    2 
 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c            |   35 
 xen/acm/acm_chinesewall_hooks.c                                     |   13 
 xen/acm/acm_core.c                                                  |   67 
 xen/acm/acm_null_hooks.c                                            |    2 
 xen/acm/acm_policy.c                                                |   42 
 xen/acm/acm_simple_type_enforcement_hooks.c                         |   26 
 xen/arch/ia64/asm-offsets.c                                         |    9 
 xen/arch/ia64/linux-xen/irq_ia64.c                                  |    2 
 xen/arch/ia64/linux-xen/mca.c                                       |   10 
 xen/arch/ia64/linux-xen/smp.c                                       |    2 
 xen/arch/ia64/vmx/pal_emul.c                                        |    2 
 xen/arch/ia64/vmx/vlsapic.c                                         |    8 
 xen/arch/ia64/vmx/vmmu.c                                            |    2 
 xen/arch/ia64/vmx/vmx_process.c                                     |    2 
 xen/arch/ia64/vmx/vmx_support.c                                     |    4 
 xen/arch/ia64/vmx/vmx_virt.c                                        |   78 
 xen/arch/ia64/xen/dom0_ops.c                                        |    4 
 xen/arch/ia64/xen/domain.c                                          |   26 
 xen/arch/ia64/xen/faults.c                                          |    2 
 xen/arch/ia64/xen/fw_emul.c                                         |    4 
 xen/arch/ia64/xen/hypercall.c                                       |   20 
 xen/arch/ia64/xen/hyperprivop.S                                     |   13 
 xen/arch/ia64/xen/mm.c                                              |   31 
 xen/arch/ia64/xen/privop.c                                          |   30 
 xen/arch/ia64/xen/privop_stat.c                                     |   86 
 xen/arch/ia64/xen/tlb_track.c                                       |   42 
 xen/arch/ia64/xen/vcpu.c                                            |   10 
 xen/arch/ia64/xen/vhpt.c                                            |   40 
 xen/arch/powerpc/backtrace.c                                        |   15 
 xen/arch/powerpc/domain.c                                           |   11 
 xen/arch/powerpc/domain_build.c                                     |    4 
 xen/arch/powerpc/mm.c                                               |   12 
 xen/arch/x86/Rules.mk                                               |    4 
 xen/arch/x86/apic.c                                                 |    2 
 xen/arch/x86/domain.c                                               |   16 
 xen/arch/x86/domain_build.c                                         |    8 
 xen/arch/x86/domctl.c                                               |    4 
 xen/arch/x86/extable.c                                              |    2 
 xen/arch/x86/hvm/hvm.c                                              |   35 
 xen/arch/x86/hvm/io.c                                               |   64 
 xen/arch/x86/hvm/save.c                                             |    2 
 xen/arch/x86/hvm/svm/emulate.c                                      |    4 
 xen/arch/x86/hvm/svm/intr.c                                         |  122 
 xen/arch/x86/hvm/svm/svm.c                                          | 1248 
++--------
 xen/arch/x86/hvm/svm/vmcb.c                                         |    8 
 xen/arch/x86/hvm/vlapic.c                                           |    4 
 xen/arch/x86/hvm/vmx/intr.c                                         |   35 
 xen/arch/x86/hvm/vmx/vmcs.c                                         |  131 -
 xen/arch/x86/hvm/vmx/vmx.c                                          |  213 -
 xen/arch/x86/hvm/vpt.c                                              |    2 
 xen/arch/x86/i387.c                                                 |    4 
 xen/arch/x86/irq.c                                                  |    2 
 xen/arch/x86/mm.c                                                   |   48 
 xen/arch/x86/mm/hap/hap.c                                           |   23 
 xen/arch/x86/mm/paging.c                                            |   15 
 xen/arch/x86/mm/shadow/common.c                                     |   44 
 xen/arch/x86/mm/shadow/multi.c                                      |   62 
 xen/arch/x86/nmi.c                                                  |   16 
 xen/arch/x86/smp.c                                                  |    6 
 xen/arch/x86/time.c                                                 |   22 
 xen/arch/x86/traps.c                                                |   30 
 xen/arch/x86/x86_32/asm-offsets.c                                   |   19 
 xen/arch/x86/x86_32/domain_page.c                                   |    6 
 xen/arch/x86/x86_32/entry.S                                         |   18 
 xen/arch/x86/x86_32/seg_fixup.c                                     |    2 
 xen/arch/x86/x86_32/traps.c                                         |    2 
 xen/arch/x86/x86_64/asm-offsets.c                                   |   34 
 xen/arch/x86/x86_64/compat/entry.S                                  |   17 
 xen/arch/x86/x86_64/compat/traps.c                                  |    2 
 xen/arch/x86/x86_64/entry.S                                         |   44 
 xen/arch/x86/x86_64/traps.c                                         |    2 
 xen/arch/x86/x86_emulate.c                                          |   12 
 xen/common/compat/domain.c                                          |    2 
 xen/common/domain.c                                                 |  124 
 xen/common/domctl.c                                                 |   77 
 xen/common/event_channel.c                                          |   19 
 xen/common/grant_table.c                                            |   16 
 xen/common/kernel.c                                                 |    2 
 xen/common/keyhandler.c                                             |    8 
 xen/common/memory.c                                                 |    6 
 xen/common/multicall.c                                              |    5 
 xen/common/page_alloc.c                                             |    6 
 xen/common/perfc.c                                                  |  223 -
 xen/common/sched_credit.c                                           |    5 
 xen/common/sched_sedf.c                                             |    2 
 xen/common/schedule.c                                               |   81 
 xen/drivers/char/console.c                                          |   10 
 xen/include/acm/acm_core.h                                          |   10 
 xen/include/acm/acm_hooks.h                                         |   12 
 xen/include/asm-ia64/bug.h                                          |    1 
 xen/include/asm-ia64/event.h                                        |    6 
 xen/include/asm-ia64/linux-xen/asm/asmmacro.h                       |    4 
 xen/include/asm-ia64/linux-xen/asm/iosapic.h                        |   19 
 xen/include/asm-ia64/mm.h                                           |    5 
 xen/include/asm-ia64/perfc_defn.h                                   |  214 -
 xen/include/asm-ia64/privop_stat.h                                  |   25 
 xen/include/asm-ia64/tlb_track.h                                    |    4 
 xen/include/asm-ia64/vmx_vpd.h                                      |    3 
 xen/include/asm-powerpc/bug.h                                       |    1 
 xen/include/asm-powerpc/debugger.h                                  |    4 
 xen/include/asm-powerpc/event.h                                     |    8 
 xen/include/asm-powerpc/mm.h                                        |    5 
 xen/include/asm-x86/bug.h                                           |    6 
 xen/include/asm-x86/debugger.h                                      |    3 
 xen/include/asm-x86/event.h                                         |    6 
 xen/include/asm-x86/hvm/hvm.h                                       |    2 
 xen/include/asm-x86/hvm/support.h                                   |   41 
 xen/include/asm-x86/hvm/svm/emulate.h                               |    1 
 xen/include/asm-x86/hvm/svm/vmcb.h                                  |    1 
 xen/include/asm-x86/hvm/vcpu.h                                      |    4 
 xen/include/asm-x86/hvm/vmx/vmcs.h                                  |   20 
 xen/include/asm-x86/hvm/vmx/vmx.h                                   |   28 
 xen/include/asm-x86/i387.h                                          |   11 
 xen/include/asm-x86/mm.h                                            |    5 
 xen/include/asm-x86/msr.h                                           |    4 
 xen/include/asm-x86/multicall.h                                     |  104 
 xen/include/asm-x86/perfc_defn.h                                    |  126 -
 xen/include/asm-x86/x86_32/asm_defns.h                              |   12 
 xen/include/asm-x86/x86_32/bug.h                                    |    6 
 xen/include/asm-x86/x86_64/asm_defns.h                              |   19 
 xen/include/asm-x86/x86_64/bug.h                                    |    6 
 xen/include/public/acm.h                                            |   26 
 xen/include/public/foreign/Makefile                                 |    4 
 xen/include/xen/event.h                                             |    6 
 xen/include/xen/lib.h                                               |    4 
 xen/include/xen/list.h                                              |  704 
+++++
 xen/include/xen/perfc.h                                             |  120 
 xen/include/xen/perfc_defn.h                                        |   15 
 xen/include/xen/sched.h                                             |  139 -
 xen/include/xen/spinlock.h                                          |    7 
 xen/include/xen/types.h                                             |    2 
 208 files changed, 5559 insertions(+), 3511 deletions(-)

diff -r e7da2fcb7a22 -r fc9e2f7920c9 .hgignore
--- a/.hgignore Fri Mar 30 10:27:15 2007 -0600
+++ b/.hgignore Fri Mar 30 17:18:42 2007 -0600
@@ -126,6 +126,7 @@
 ^tools/ioemu/qemu\.pod$
 ^tools/libxc/xen/.*$
 ^tools/libxen/test/test_bindings$
+^tools/libxen/test/test_event_handling$
 ^tools/libaio/src/.*\.ol$
 ^tools/libaio/src/.*\.os$
 ^tools/misc/cpuperf/cpuperf-perfcntr$
diff -r e7da2fcb7a22 -r fc9e2f7920c9 Config.mk
--- a/Config.mk Fri Mar 30 10:27:15 2007 -0600
+++ b/Config.mk Fri Mar 30 17:18:42 2007 -0600
@@ -31,16 +31,26 @@ EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
 EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
 endif
 
-# cc-option
+# cc-option: Check if compiler supports first option, else fall back to second.
 # Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
               /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
 
-# cc-ver
+# cc-ver: Check compiler is at least specified version. Return boolean 'y'/'n'.
 # Usage: ifeq ($(call cc-ver,$(CC),0x030400),y)
 cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
            '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \
            then echo y; else echo n; fi ;)
+
+# cc-ver-check: Check compiler is at least specified version, else fail.
+# Usage: $(call cc-ver-check,CC,0x030400,"Require at least gcc-3.4")
+cc-ver-check = $(eval $(call cc-ver-check-closure,$(1),$(2),$(3)))
+define cc-ver-check-closure
+    ifeq ($$(call cc-ver,$$($(1)),$(2)),n)
+        override $(1) = echo "*** FATAL BUILD ERROR: "$(3) >&2; exit 1;
+        cc-option := n
+    endif
+endef
 
 ifneq ($(debug),y)
 CFLAGS += -DNDEBUG
diff -r e7da2fcb7a22 -r fc9e2f7920c9 docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Fri Mar 30 10:27:15 2007 -0600
+++ b/docs/xen-api/xenapi-datamodel.tex Fri Mar 30 17:18:42 2007 -0600
@@ -24,6 +24,7 @@ Name & Description \\
 \hline
 {\tt session} & A session \\
 {\tt task} & A long-running asynchronous task \\
+{\tt event} & Asynchronous event registration and handling \\
 {\tt VM} & A virtual machine (or 'guest') \\
 {\tt VM\_metrics} & The metrics associated with a VM \\
 {\tt VM\_guest\_metrics} & The metrics reported by the guest (as opposed to 
inferred from outside) \\
@@ -112,6 +113,17 @@ The following enumeration types are used
 
 \begin{longtable}{|ll|}
 \hline
+{\tt enum event\_operation} & \\
+\hline
+\hspace{0.5cm}{\tt add} & An object has been created \\
+\hspace{0.5cm}{\tt del} & An object has been deleted \\
+\hspace{0.5cm}{\tt mod} & An object has been modified \\
+\hline
+\end{longtable}
+
+\vspace{1cm}
+\begin{longtable}{|ll|}
+\hline
 {\tt enum console\_protocol} & \\
 \hline
 \hspace{0.5cm}{\tt vt100} & VT100 terminal \\
@@ -1013,6 +1025,116 @@ references to objects with match names
 \vspace{0.3cm}
 \vspace{0.3cm}
 \vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
+\section{Class: event}
+\subsection{Fields for class: event}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf event} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em
+Asynchronous event registration and handling.}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{ins}$ &  {\tt id} & int & An ID, monotonically 
increasing, and local to the current session \\
+$\mathit{RO}_\mathit{ins}$ &  {\tt timestamp} & datetime & The time at which 
the event occurred \\
+$\mathit{RO}_\mathit{ins}$ &  {\tt class} & string & The name of the class of 
the object that changed \\
+$\mathit{RO}_\mathit{ins}$ &  {\tt operation} & event\_operation & The 
operation that was performed \\
+$\mathit{RO}_\mathit{ins}$ &  {\tt ref} & string & A reference to the object 
that changed \\
+$\mathit{RO}_\mathit{ins}$ &  {\tt obj\_uuid} & string & The uuid of the 
object that changed \\
+\hline
+\end{longtable}
+\subsection{RPCs associated with class: event}
+\subsubsection{RPC name:~register}
+
+{\bf Overview:} 
+Registers this session with the event system.  Specifying the empty list
+will register for all classes.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void register (session_id s, string Set classes)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string Set } & classes & register for events for the indicated classes \\ 
\hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~unregister}
+
+{\bf Overview:} 
+Unregisters this session with the event system.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void unregister (session_id s, string Set 
classes)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string Set } & classes & remove this session's registration for the 
indicated classes \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~next}
+
+{\bf Overview:} 
+Blocking call which returns a (possibly empty) batch of events.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((event record) Set) next (session_id s)\end{verbatim}
+
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+(event record) Set
+}
+
+
+the batch of events
+\vspace{0.3cm}
+
+\noindent{\bf Possible Error Codes:} {\tt SESSION\_NOT\_REGISTERED}
+
+\vspace{0.6cm}
 
 \vspace{1cm}
 \newpage
@@ -6549,6 +6671,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt name/description} & string & a notes field containg 
human-readable description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VIFs} & (VIF ref) Set & list of connected 
vifs \\
 $\mathit{RO}_\mathit{run}$ &  {\tt PIFs} & (PIF ref) Set & list of connected 
pifs \\
+$\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & 
additional configuration \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: network}
@@ -6798,6 +6921,145 @@ Get the PIFs field of the given network.
 
 
 value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_other\_config}
+
+{\bf Overview:} 
+Get the other\_config field of the given network.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, 
network 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 network ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+(string $\rightarrow$ string) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_other\_config}
+
+{\bf Overview:} 
+Set the other\_config field of the given network.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void set_other_config (session_id s, network ref self, 
(string -> string) Map value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline 
+
+{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~add\_to\_other\_config}
+
+{\bf Overview:} 
+Add the given key-value pair to the other\_config field of the given
+network.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void add_to_other_config (session_id s, network ref self, 
string key, string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline 
+
+{\tt string } & key & Key to add \\ \hline 
+
+{\tt string } & value & Value to add \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~remove\_from\_other\_config}
+
+{\bf Overview:} 
+Remove the given key and its corresponding value from the other\_config
+field of the given network.  If the key is not in that Map, then do
+nothing.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void remove_from_other_config (session_id s, network ref 
self, string key)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline 
+
+{\tt string } & key & Key to remove \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
 \vspace{0.3cm}
 \vspace{0.3cm}
 \vspace{0.3cm}
@@ -13576,6 +13838,17 @@ current connection.  The handle paramete
 \begin{verbatim}SESSION_INVALID(handle)\end{verbatim}
 \begin{center}\rule{10em}{0.1pt}\end{center}
 
+\subsubsection{SESSION\_NOT\_REGISTERED}
+
+This session is not registered to receive events.  You must call
+event.register before event.next.  The session handle you are using is
+echoed.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}SESSION_NOT_REGISTERED(handle)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
 \subsubsection{VALUE\_NOT\_SUPPORTED}
 
 You attempted to set a value that is not supported by this implementation. 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Fri Mar 30 
17:18:42 2007 -0600
@@ -148,11 +148,11 @@ NMI_MASK = 0x80000000
        .endm
 
         /*
-         * Must be consistent with the definition in arch-x86_64.h:    
+         * Must be consistent with the definition in arch-x86/xen-x86_64.h:
          *     struct iret_context {
          *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
          *     };
-         * #define VGCF_IN_SYSCALL (1<<8) 
+         * with rax, r11, and rcx being taken care of in the hypercall stub.
          */
        .macro HYPERVISOR_IRET flag
        testb $3,1*8(%rsp)
@@ -164,21 +164,15 @@ NMI_MASK = 0x80000000
        jnz   1f
 
        /* Direct iret to kernel space. Correct CS and SS. */
-       orb   $3,1*8(%rsp)
-       orb   $3,4*8(%rsp)
+       orl   $3,1*8(%rsp)
+       orl   $3,4*8(%rsp)
 1:     iretq
 
 2:     /* Slow iret via hypervisor. */
-       andl  $~NMI_MASK, 16(%rsp)
+       andl  $~NMI_MASK, 2*8(%rsp)
        pushq $\flag
        jmp  hypercall_page + (__HYPERVISOR_iret * 32)
        .endm
-
-        .macro SWITCH_TO_KERNEL ssoff,adjust=0
-       jc  1f
-       orb  $1,\ssoff-\adjust+4(%rsp)
-1:
-        .endm
 
 /*
  * A newly forked process directly context switches into this.
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c      Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c      Fri Mar 30 
17:18:42 2007 -0600
@@ -104,6 +104,8 @@ void __init x86_64_start_kernel(char * r
        char *s;
        int i;
 
+       setup_xen_features();
+
        xen_start_info = (struct start_info *)real_mode_data;
        if (!xen_feature(XENFEAT_auto_translated_physmap))
                phys_to_machine_mapping =
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
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       Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Fri Mar 30 
17:18:42 2007 -0600
@@ -625,8 +625,6 @@ void __init setup_arch(char **cmdline_p)
 
 #endif
 
-       setup_xen_features();
-
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_writable_pagetables);
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Fri Mar 30 
17:18:42 2007 -0600
@@ -43,6 +43,7 @@
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
+#include <linux/mutex.h>
 #include <xen/xen_proc.h>
 #include <asm/hypervisor.h>
 #include <xen/balloon.h>
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Fri Mar 30 
17:18:42 2007 -0600
@@ -123,7 +123,7 @@ static int take_machine_down(void *p_fas
 static int take_machine_down(void *p_fast_suspend)
 {
        int fast_suspend = *(int *)p_fast_suspend;
-       int suspend_cancelled, err, cpu;
+       int suspend_cancelled, err;
        extern void time_resume(void);
 
        if (fast_suspend) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Fri Mar 30 10:27:15 
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Fri Mar 30 17:18:42 
2007 -0600
@@ -33,7 +33,24 @@ static DECLARE_WORK(shutdown_work, __shu
 #ifdef CONFIG_XEN
 int __xen_suspend(int fast_suspend);
 #else
-#define __xen_suspend(fast_suspend) 0
+extern void xenbus_suspend(void);
+extern void xenbus_resume(void);
+extern void platform_pci_suspend(void);
+extern void platform_pci_resume(void);
+int __xen_suspend(int fast_suspend)
+{
+       xenbus_suspend();
+       platform_pci_suspend();
+
+       /* pvdrv sleep in this hyper-call when save */
+       HYPERVISOR_shutdown(SHUTDOWN_suspend);
+
+       platform_pci_resume();
+       xenbus_resume();
+       printk("PV stuff on HVM resume successfully!\n");
+
+       return 0;
+}
 #endif
 
 static int shutdown_process(void *__unused)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Fri Mar 30 10:27:15 
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Fri Mar 30 17:18:42 
2007 -0600
@@ -47,6 +47,7 @@
 #include <linux/irq.h>
 #include <linux/init.h>
 #include <linux/gfp.h>
+#include <linux/mutex.h>
 #include <xen/evtchn.h>
 #include <xen/public/evtchn.h>
 
@@ -56,6 +57,7 @@ struct per_user_data {
 #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
        evtchn_port_t *ring;
        unsigned int ring_cons, ring_prod, ring_overflow;
+       struct mutex ring_cons_mutex; /* protect against concurrent readers */
 
        /* Processes wait on this queue when ring is empty. */
        wait_queue_head_t evtchn_wait;
@@ -108,11 +110,16 @@ static ssize_t evtchn_read(struct file *
                count = PAGE_SIZE;
 
        for (;;) {
+               mutex_lock(&u->ring_cons_mutex);
+
+               rc = -EFBIG;
                if (u->ring_overflow)
-                       return -EFBIG;
+                       goto unlock_out;
 
                if ((c = u->ring_cons) != (p = u->ring_prod))
                        break;
+
+               mutex_unlock(&u->ring_cons_mutex);
 
                if (file->f_flags & O_NONBLOCK)
                        return -EAGAIN;
@@ -141,20 +148,24 @@ static ssize_t evtchn_read(struct file *
                bytes2 = count - bytes1;
        }
 
+       rc = -EFAULT;
        if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
            ((bytes2 != 0) &&
             copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
-               return -EFAULT;
+               goto unlock_out;
 
        u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
-
-       return bytes1 + bytes2;
+       rc = bytes1 + bytes2;
+
+ unlock_out:
+       mutex_unlock(&u->ring_cons_mutex);
+       return rc;
 }
 
 static ssize_t evtchn_write(struct file *file, const char __user *buf,
                            size_t count, loff_t *ppos)
 {
-       int  rc, i;
+       int rc, i;
        evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
        struct per_user_data *u = file->private_data;
 
@@ -164,18 +175,16 @@ static ssize_t evtchn_write(struct file 
        /* Whole number of ports. */
        count &= ~(sizeof(evtchn_port_t)-1);
 
-       if (count == 0) {
-               rc = 0;
+       rc = 0;
+       if (count == 0)
                goto out;
-       }
 
        if (count > PAGE_SIZE)
                count = PAGE_SIZE;
 
-       if (copy_from_user(kbuf, buf, count) != 0) {
-               rc = -EFAULT;
+       rc = -EFAULT;
+       if (copy_from_user(kbuf, buf, count) != 0)
                goto out;
-       }
 
        spin_lock_irq(&port_user_lock);
        for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
@@ -321,9 +330,11 @@ static int evtchn_ioctl(struct inode *in
 
        case IOCTL_EVTCHN_RESET: {
                /* Initialise the ring to empty. Clear errors. */
+               mutex_lock(&u->ring_cons_mutex);
                spin_lock_irq(&port_user_lock);
                u->ring_cons = u->ring_prod = u->ring_overflow = 0;
                spin_unlock_irq(&port_user_lock);
+               mutex_unlock(&u->ring_cons_mutex);
                rc = 0;
                break;
        }
@@ -370,6 +381,8 @@ static int evtchn_open(struct inode *ino
                kfree(u);
                return -ENOMEM;
        }
+
+       mutex_init(&u->ring_cons_mutex);
 
        filp->private_data = u;
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c       
Fri Mar 30 10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c       
Fri Mar 30 17:18:42 2007 -0600
@@ -32,19 +32,19 @@ static int pm_ctrl_write(struct pci_dev 
                         void *data)
 {
        int err;
-       u16 cur_value;
-       pci_power_t new_state;
+       u16 old_value;
+       pci_power_t new_state, old_state;
 
-       /* Handle setting power state separately */
-       new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
-
-       err = pci_read_config_word(dev, offset, &cur_value);
+       err = pci_read_config_word(dev, offset, &old_value);
        if (err)
                goto out;
 
+       old_state = (pci_power_t)(old_value & PCI_PM_CTRL_STATE_MASK);
+       new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
+
        new_value &= PM_OK_BITS;
-       if ((cur_value & PM_OK_BITS) != new_value) {
-               new_value = (cur_value & ~PM_OK_BITS) | new_value;
+       if ((old_value & PM_OK_BITS) != new_value) {
+               new_value = (old_value & ~PM_OK_BITS) | new_value;
                err = pci_write_config_word(dev, offset, new_value);
                if (err)
                        goto out;
@@ -53,10 +53,25 @@ static int pm_ctrl_write(struct pci_dev 
        /* Let pci core handle the power management change */
        dev_dbg(&dev->dev, "set power state to %x\n", new_state);
        err = pci_set_power_state(dev, new_state);
-       if (err)
+       if (err) {
                err = PCIBIOS_SET_FAILED;
+               goto out;
+       }
 
-      out:
+       /*
+        * Device may lose PCI config info on D3->D0 transition. This
+        * is a problem for some guests which will not reset BARs. Even
+        * those that have a go will be foiled by our BAR-write handler
+        * which will discard the write! Since Linux won't re-init
+        * the config space automatically in all cases, we do it here.
+        * Future: Should we re-initialise all first 64 bytes of config space?
+        */
+       if (new_state == PCI_D0 &&
+           (old_state == PCI_D3hot || old_state == PCI_D3cold) &&
+           !(old_value & PCI_PM_CTRL_NO_SOFT_RESET))
+               pci_restore_bars(dev);
+
+ out:
        return err;
 }
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c      Fri Mar 
30 10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c      Fri Mar 
30 17:18:42 2007 -0600
@@ -20,11 +20,15 @@ struct pci_bar_info {
 
 static int command_write(struct pci_dev *dev, int offset, u16 value, void 
*data)
 {
+       int err;
+
        if (!dev->is_enabled && is_enable_cmd(value)) {
                if (unlikely(verbose_request))
                        printk(KERN_DEBUG "pciback: %s: enable\n",
                               pci_name(dev));
-               pci_enable_device(dev);
+               err = pci_enable_device(dev);
+               if (err)
+                       return err;
        } else if (dev->is_enabled && !is_enable_cmd(value)) {
                if (unlikely(verbose_request))
                        printk(KERN_DEBUG "pciback: %s: disable\n",
@@ -44,7 +48,13 @@ static int command_write(struct pci_dev 
                        printk(KERN_DEBUG
                               "pciback: %s: enable memory-write-invalidate\n",
                               pci_name(dev));
-               pci_set_mwi(dev);
+               err = pci_set_mwi(dev);
+               if (err) {
+                       printk(KERN_WARNING
+                              "pciback: %s: cannot enable 
memory-write-invalidate (%d)\n",
+                              pci_name(dev), err);
+                       value &= ~PCI_COMMAND_INVALIDATE;
+               }
        }
 
        return pci_write_config_word(dev, offset, value);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Fri Mar 30 
17:18:42 2007 -0600
@@ -805,6 +805,18 @@ static ssize_t permissive_show(struct de
 
 DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
 
+static void pcistub_exit(void)
+{
+       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
+       driver_remove_file(&pciback_pci_driver.driver,
+                          &driver_attr_remove_slot);
+       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
+       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
+       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
+
+       pci_unregister_driver(&pciback_pci_driver);
+}
+
 static int __init pcistub_init(void)
 {
        int pos = 0;
@@ -845,12 +857,23 @@ static int __init pcistub_init(void)
        if (err < 0)
                goto out;
 
-       driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
-       driver_create_file(&pciback_pci_driver.driver,
-                          &driver_attr_remove_slot);
-       driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
-       driver_create_file(&pciback_pci_driver.driver, &driver_attr_quirks);
-       driver_create_file(&pciback_pci_driver.driver, &driver_attr_permissive);
+       err = driver_create_file(&pciback_pci_driver.driver,
+                                &driver_attr_new_slot);
+       if (!err)
+               err = driver_create_file(&pciback_pci_driver.driver,
+                                        &driver_attr_remove_slot);
+       if (!err)
+               err = driver_create_file(&pciback_pci_driver.driver,
+                                        &driver_attr_slots);
+       if (!err)
+               err = driver_create_file(&pciback_pci_driver.driver,
+                                        &driver_attr_quirks);
+       if (!err)
+               err = driver_create_file(&pciback_pci_driver.driver,
+                                        &driver_attr_permissive);
+
+       if (err)
+               pcistub_exit();
 
       out:
        return err;
@@ -887,23 +910,17 @@ static int __init pciback_init(void)
 #endif
 
        pcistub_init_devices_late();
-       pciback_xenbus_register();
-
-       return 0;
+       err = pciback_xenbus_register();
+       if (err)
+               pcistub_exit();
+
+       return err;
 }
 
 static void __exit pciback_cleanup(void)
 {
        pciback_xenbus_unregister();
-
-       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
-       driver_remove_file(&pciback_pci_driver.driver,
-                          &driver_attr_remove_slot);
-       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
-       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
-       driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
-
-       pci_unregister_driver(&pciback_pci_driver);
+       pcistub_exit();
 }
 
 module_init(pciback_init);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Fri Mar 30 
17:18:42 2007 -0600
@@ -58,6 +58,13 @@ struct xenbus_dev_transaction {
        struct xenbus_transaction handle;
 };
 
+struct read_buffer {
+       struct list_head list;
+       unsigned int cons;
+       unsigned int len;
+       char msg[];
+};
+
 struct xenbus_dev_data {
        /* In-progress transaction. */
        struct list_head transactions;
@@ -73,9 +80,7 @@ struct xenbus_dev_data {
        } u;
 
        /* Response queue. */
-#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1))
-       char read_buffer[PAGE_SIZE];
-       unsigned int read_cons, read_prod;
+       struct list_head read_buffers;
        wait_queue_head_t read_waitq;
 
        struct mutex reply_mutex;
@@ -88,18 +93,34 @@ static ssize_t xenbus_dev_read(struct fi
                               size_t len, loff_t *ppos)
 {
        struct xenbus_dev_data *u = filp->private_data;
-       int i;
-
-       if (wait_event_interruptible(u->read_waitq,
-                                    u->read_prod != u->read_cons))
-               return -EINTR;
-
-       for (i = 0; i < len; i++) {
-               if (u->read_cons == u->read_prod)
-                       break;
-               put_user(u->read_buffer[MASK_READ_IDX(u->read_cons)], ubuf+i);
-               u->read_cons++;
-       }
+       struct read_buffer *rb;
+       int i, ret;
+
+       mutex_lock(&u->reply_mutex);
+       while (list_empty(&u->read_buffers)) {
+               mutex_unlock(&u->reply_mutex);
+               ret = wait_event_interruptible(u->read_waitq,
+                                              !list_empty(&u->read_buffers));
+               if (ret)
+                       return ret;
+               mutex_lock(&u->reply_mutex);
+       }
+
+       rb = list_entry(u->read_buffers.next, struct read_buffer, list);
+       for (i = 0; i < len;) {
+               put_user(rb->msg[rb->cons], ubuf + i);
+               i++;
+               rb->cons++;
+               if (rb->cons == rb->len) {
+                       list_del(&rb->list);
+                       kfree(rb);
+                       if (list_empty(&u->read_buffers))
+                               break;
+                       rb = list_entry(u->read_buffers.next,
+                                       struct read_buffer, list);
+               }
+       }
+       mutex_unlock(&u->reply_mutex);
 
        return i;
 }
@@ -107,16 +128,20 @@ static void queue_reply(struct xenbus_de
 static void queue_reply(struct xenbus_dev_data *u,
                        char *data, unsigned int len)
 {
-       int i;
-
-       mutex_lock(&u->reply_mutex);
-
-       for (i = 0; i < len; i++, u->read_prod++)
-               u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
-
-       BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
-
-       mutex_unlock(&u->reply_mutex);
+       struct read_buffer *rb;
+
+       if (len == 0)
+               return;
+
+       rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL);
+       BUG_ON(rb == NULL);
+
+       rb->cons = 0;
+       rb->len = len;
+
+       memcpy(rb->msg, data, len);
+
+       list_add_tail(&rb->list, &u->read_buffers);
 
        wake_up(&u->read_waitq);
 }
@@ -155,10 +180,12 @@ static void watch_fired(struct xenbus_wa
 
        hdr.type = XS_WATCH_EVENT;
        hdr.len = body_len;
-       
+
+       mutex_lock(&adap->dev_data->reply_mutex);
        queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr));
        queue_reply(adap->dev_data, (char *)path, path_len);
        queue_reply(adap->dev_data, (char *)token, tok_len);
+       mutex_unlock(&adap->dev_data->reply_mutex);
 }
 
 static LIST_HEAD(watch_list);
@@ -230,13 +257,18 @@ static ssize_t xenbus_dev_write(struct f
                        list_del(&trans->list);
                        kfree(trans);
                }
+               mutex_lock(&u->reply_mutex);
                queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
                queue_reply(u, (char *)reply, u->u.msg.len);
+               mutex_unlock(&u->reply_mutex);
                kfree(reply);
                break;
 
        case XS_WATCH:
-       case XS_UNWATCH:
+       case XS_UNWATCH: {
+               static const char *XS_RESP = "OK";
+               struct xsd_sockmsg hdr;
+
                path = u->u.buffer + sizeof(u->u.msg);
                token = memchr(path, 0, u->u.msg.len);
                if (token == NULL) {
@@ -246,9 +278,6 @@ static ssize_t xenbus_dev_write(struct f
                token++;
 
                if (msg_type == XS_WATCH) {
-                       static const char * XS_WATCH_RESP = "OK";
-                       struct xsd_sockmsg hdr;
-
                        watch = kmalloc(sizeof(*watch), GFP_KERNEL);
                        watch->watch.node = kmalloc(strlen(path)+1,
                                                     GFP_KERNEL);
@@ -266,11 +295,6 @@ static ssize_t xenbus_dev_write(struct f
                        }
                        
                        list_add(&watch->list, &u->watches);
-
-                       hdr.type = XS_WATCH;
-                       hdr.len = strlen(XS_WATCH_RESP) + 1;
-                       queue_reply(u, (char *)&hdr, sizeof(hdr));
-                       queue_reply(u, (char *)XS_WATCH_RESP, hdr.len);
                } else {
                        list_for_each_entry_safe(watch, tmp_watch,
                                                  &u->watches, list) {
@@ -285,7 +309,14 @@ static ssize_t xenbus_dev_write(struct f
                        }
                }
 
+               hdr.type = msg_type;
+               hdr.len = strlen(XS_RESP) + 1;
+               mutex_lock(&u->reply_mutex);
+               queue_reply(u, (char *)&hdr, sizeof(hdr));
+               queue_reply(u, (char *)XS_RESP, hdr.len);
+               mutex_unlock(&u->reply_mutex);
                break;
+       }
 
        default:
                rc = -EINVAL;
@@ -312,6 +343,7 @@ static int xenbus_dev_open(struct inode 
 
        INIT_LIST_HEAD(&u->transactions);
        INIT_LIST_HEAD(&u->watches);
+       INIT_LIST_HEAD(&u->read_buffers);
        init_waitqueue_head(&u->read_waitq);
 
        mutex_init(&u->reply_mutex);
@@ -349,7 +381,7 @@ static unsigned int xenbus_dev_poll(stru
        struct xenbus_dev_data *u = file->private_data;
 
        poll_wait(file, &u->read_waitq, wait);
-       if (u->read_cons != u->read_prod)
+       if (!list_empty(&u->read_buffers))
                return POLLIN | POLLRDNORM;
        return 0;
 }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Fri Mar 30 
17:18:42 2007 -0600
@@ -335,6 +335,9 @@ int xenbus_register_driver_common(struct
 {
        int ret;
 
+       if (bus->error)
+               return bus->error;
+
        drv->driver.name = drv->name;
        drv->driver.bus = &bus->bus;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
@@ -476,6 +479,9 @@ int xenbus_probe_node(struct xen_bus_typ
 
        enum xenbus_state state = xenbus_read_driver_state(nodename);
 
+       if (bus->error)
+               return bus->error;
+
        if (state != XenbusStateInitialising) {
                /* Device is not new, so ignore it.  This can happen if a
                   device is going away after switching to Closed.  */
@@ -513,10 +519,18 @@ int xenbus_probe_node(struct xen_bus_typ
        if (err)
                goto fail;
 
-       device_create_file(&xendev->dev, &dev_attr_nodename);
-       device_create_file(&xendev->dev, &dev_attr_devtype);
-
-       return 0;
+       err = device_create_file(&xendev->dev, &dev_attr_nodename);
+       if (err)
+               goto unregister;
+       err = device_create_file(&xendev->dev, &dev_attr_devtype);
+       if (err)
+               goto unregister;
+
+       return 0;
+unregister:
+       device_remove_file(&xendev->dev, &dev_attr_nodename);
+       device_remove_file(&xendev->dev, &dev_attr_devtype);
+       device_unregister(&xendev->dev);
 fail:
        kfree(xendev);
        return err;
@@ -564,6 +578,9 @@ int xenbus_probe_devices(struct xen_bus_
        int err = 0;
        char **dir;
        unsigned int i, dir_n;
+
+       if (bus->error)
+               return bus->error;
 
        dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
        if (IS_ERR(dir))
@@ -608,7 +625,7 @@ void dev_changed(const char *node, struc
        char type[BUS_ID_SIZE];
        const char *p, *root;
 
-       if (char_count(node, '/') < 2)
+       if (bus->error || char_count(node, '/') < 2)
                return;
 
        exists = xenbus_exists(XBT_NIL, node, "");
@@ -742,7 +759,8 @@ void xenbus_suspend(void)
 {
        DPRINTK("");
 
-       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
+       if (!xenbus_frontend.error)
+               bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
        xenbus_backend_suspend(suspend_dev);
        xs_suspend();
 }
@@ -752,7 +770,8 @@ void xenbus_resume(void)
 {
        xb_init_comms();
        xs_resume();
-       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
+       if (!xenbus_frontend.error)
+               bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
        xenbus_backend_resume(resume_dev);
 }
 EXPORT_SYMBOL_GPL(xenbus_resume);
@@ -760,7 +779,8 @@ void xenbus_suspend_cancel(void)
 void xenbus_suspend_cancel(void)
 {
        xs_suspend_cancel();
-       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
+       if (!xenbus_frontend.error)
+               bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, 
suspend_cancel_dev);
        xenbus_backend_resume(suspend_cancel_dev);
 }
 EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
@@ -854,7 +874,11 @@ static int __init xenbus_probe_init(void
                return -ENODEV;
 
        /* Register ourselves with the kernel bus subsystem */
-       bus_register(&xenbus_frontend.bus);
+       xenbus_frontend.error = bus_register(&xenbus_frontend.bus);
+       if (xenbus_frontend.error)
+               printk(KERN_WARNING
+                      "XENBUS: Error registering frontend bus: %i\n",
+                      xenbus_frontend.error);
        xenbus_backend_bus_register();
 
        /*
@@ -925,7 +949,15 @@ static int __init xenbus_probe_init(void
        }
 
        /* Register ourselves with the kernel device subsystem */
-       device_register(&xenbus_frontend.dev);
+       if (!xenbus_frontend.error) {
+               xenbus_frontend.error = device_register(&xenbus_frontend.dev);
+               if (xenbus_frontend.error) {
+                       bus_unregister(&xenbus_frontend.bus);
+                       printk(KERN_WARNING
+                              "XENBUS: Error registering frontend device: 
%i\n",
+                              xenbus_frontend.error);
+               }
+       }
        xenbus_backend_device_register();
 
        if (!is_initial_xendomain())
@@ -972,6 +1004,8 @@ static int is_disconnected_device(struct
 
 static int exists_disconnected_device(struct device_driver *drv)
 {
+       if (xenbus_frontend.error)
+               return xenbus_frontend.error;
        return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
                                is_disconnected_device);
 }
@@ -1036,8 +1070,10 @@ static void wait_for_devices(struct xenb
 #ifndef MODULE
 static int __init boot_wait_for_devices(void)
 {
-       ready_to_wait_for_devices = 1;
-       wait_for_devices(NULL);
+       if (!xenbus_frontend.error) {
+               ready_to_wait_for_devices = 1;
+               wait_for_devices(NULL);
+       }
        return 0;
 }
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h    Fri Mar 30 
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h    Fri Mar 30 
17:18:42 2007 -0600
@@ -51,6 +51,7 @@ struct xen_bus_type
 struct xen_bus_type
 {
        char *root;
+       int error;
        unsigned int levels;
        int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
        int (*probe)(const char *type, const char *dir);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c    Fri Mar 
30 10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c    Fri Mar 
30 17:18:42 2007 -0600
@@ -245,13 +245,15 @@ void xenbus_backend_suspend(int (*fn)(st
 void xenbus_backend_suspend(int (*fn)(struct device *, void *))
 {
        DPRINTK("");
-       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+       if (!xenbus_backend.error)
+               bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
 }
 
 void xenbus_backend_resume(int (*fn)(struct device *, void *))
 {
        DPRINTK("");
-       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+       if (!xenbus_backend.error)
+               bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
 }
 
 void xenbus_backend_probe_and_watch(void)
@@ -262,10 +264,23 @@ void xenbus_backend_probe_and_watch(void
 
 void xenbus_backend_bus_register(void)
 {
-       bus_register(&xenbus_backend.bus);
+       xenbus_backend.error = bus_register(&xenbus_backend.bus);
+       if (xenbus_backend.error)
+               printk(KERN_WARNING
+                      "XENBUS: Error registering backend bus: %i\n",
+                      xenbus_backend.error);
 }
 
 void xenbus_backend_device_register(void)
 {
-       device_register(&xenbus_backend.dev);
-}
+       if (xenbus_backend.error)
+               return;
+
+       xenbus_backend.error = device_register(&xenbus_backend.dev);
+       if (xenbus_backend.error) {
+               bus_unregister(&xenbus_backend.bus);
+               printk(KERN_WARNING
+                      "XENBUS: Error registering backend device: %i\n",
+                      xenbus_backend.error);
+       }
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/Rules.mk
--- a/tools/Rules.mk    Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/Rules.mk    Fri Mar 30 17:18:42 2007 -0600
@@ -24,9 +24,9 @@ CFLAGS += $(CFLAGS-y)
 CFLAGS += $(CFLAGS-y)
 
 # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
-ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn)
-$(error Xen tools require at least gcc-3.4)
-endif
+check-$(CONFIG_X86) = $(call cc-ver-check,CC,0x030400,\
+                        "Xen requires at least gcc-3.4")
+$(eval $(check-y))
 
 %.opic: %.c
        $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/Makefile
--- a/tools/examples/Makefile   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/examples/Makefile   Fri Mar 30 17:18:42 2007 -0600
@@ -9,7 +9,9 @@ XENDOMAINS_SYSCONFIG = init.d/sysconfig.
 # Xen configuration dir and configs to go there.
 XEN_CONFIG_DIR = /etc/xen
 XEN_CONFIGS = xend-config.sxp
+XEN_CONFIGS += xend-config-xenapi.sxp
 XEN_CONFIGS += xm-config.xml
+XEN_CONFIGS += xm-config-xenapi.xml
 XEN_CONFIGS += xmexample1 
 XEN_CONFIGS += xmexample2
 XEN_CONFIGS += xmexample.hvm
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/xend-config-xenapi.sxp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/xend-config-xenapi.sxp     Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,195 @@
+# -*- sh -*-
+
+#
+# Xend configuration file.
+#
+
+# This example configuration is appropriate for an installation that 
+# utilizes a bridged network configuration. Access to xend via http
+# is disabled.  
+
+# Commented out entries show the default for that entry, unless otherwise
+# specified.
+
+#(logfile /var/log/xen/xend.log)
+#(loglevel DEBUG)
+
+
+# The Xen-API server configuration.  (Please note that this server is
+# available as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied
+# upon).
+#
+# This value configures the ports, interfaces, and access controls for the
+# Xen-API server.  Each entry in the list starts with either unix, a port
+# number, or an address:port pair.  If this is "unix", then a UDP socket is
+# opened, and this entry applies to that.  If it is a port, then Xend will
+# listen on all interfaces on that TCP port, and if it is an address:port
+# pair, then Xend will listen on the specified port, using the interface with
+# the specified address.
+#
+# The subsequent string configures the user-based access control for the
+# listener in question.  This can be one of "none" or "pam", indicating either
+# that users should be allowed access unconditionally, or that the local
+# Pluggable Authentication Modules configuration should be used.  If this
+# string is missing or empty, then "pam" is used.
+#
+# The final string gives the host-based access control for that listener. If
+# this is missing or empty, then all connections are accepted.  Otherwise,
+# this should be a space-separated sequence of regular expressions; any host
+# with a fully-qualified domain name or an IP address that matches one of
+# these regular expressions will be accepted.
+#
+# Example: listen on TCP port 9363 on all interfaces, accepting connections
+# only from machines in example.com or localhost, and allow access through
+# the unix domain socket unconditionally:
+#
+   (xen-api-server ((9363 none)))
+#                    (unix none)))
+#
+# Optionally, the TCP Xen-API server can use SSL by specifying the private
+# key and certificate location:
+#
+#                    (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
+#
+# Default:
+#   (xen-api-server ((unix)))
+
+
+#(xend-http-server no)
+#(xend-unix-server no)
+#(xend-tcp-xmlrpc-server no)
+#(xend-unix-xmlrpc-server yes)
+#(xend-relocation-server no)
+(xend-relocation-server yes)
+
+#(xend-unix-path /var/lib/xend/xend-socket)
+
+
+# Address and port xend should use for the legacy TCP XMLRPC interface, 
+# if xen-tcp-xmlrpc-server is set.
+#(xen-tcp-xmlrpc-server-address 'localhost')
+#(xen-tcp-xmlrpc-server-port 8006)
+
+# SSL key and certificate to use for the legacy TCP XMLRPC interface.
+# Setting these will mean that this port serves only SSL connections as
+# opposed to plaintext ones.
+#(xend-tcp-xmlrpc-server-ssl-key-file  /etc/xen/xmlrpc.key)
+#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
+
+
+# Port xend should use for the HTTP interface, if xend-http-server is set.
+#(xend-port            8000)
+
+# Port xend should use for the relocation interface, if xend-relocation-server
+# is set.
+#(xend-relocation-port 8002)
+
+# Address xend should listen on for HTTP connections, if xend-http-server is
+# set.
+# Specifying 'localhost' prevents remote connections.
+# Specifying the empty string '' (the default) allows all connections.
+#(xend-address '')
+#(xend-address localhost)
+
+# Address xend should listen on for relocation-socket connections, if
+# xend-relocation-server is set.
+# Meaning and default as for xend-address above.
+#(xend-relocation-address '')
+
+# The hosts allowed to talk to the relocation port.  If this is empty (the
+# default), then all connections are allowed (assuming that the connection
+# arrives on a port and interface on which we are listening; see
+# xend-relocation-port and xend-relocation-address above).  Otherwise, this
+# should be a space-separated sequence of regular expressions.  Any host with
+# a fully-qualified domain name or an IP address that matches one of these
+# regular expressions will be accepted.
+#
+# For example:
+#  (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$')
+#
+#(xend-relocation-hosts-allow '')
+(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
+
+# The limit (in kilobytes) on the size of the console buffer
+#(console-limit 1024)
+
+##
+# To bridge network traffic, like this:
+#
+# dom0: fake eth0 -> vif0.0 -+
+#                            |
+#                          bridge -> real eth0 -> the network
+#                            |
+# domU: fake eth0 -> vifN.0 -+
+#
+# use
+#
+# (network-script network-bridge)
+#
+# Your default ethernet device is used as the outgoing interface, by default. 
+# To use a different one (e.g. eth1) use
+#
+# (network-script 'network-bridge netdev=eth1')
+#
+# The bridge is named xenbr0, by default.  To rename the bridge, use
+#
+# (network-script 'network-bridge bridge=<name>')
+#
+# It is possible to use the network-bridge script in more complicated
+# scenarios, such as having two outgoing interfaces, with two bridges, and
+# two fake interfaces per guest domain.  To do things like this, write
+# yourself a wrapper script, and call network-bridge from it, as appropriate.
+#
+(network-script network-bridge)
+
+# The script used to control virtual interfaces.  This can be overridden on a
+# per-vif basis when creating a domain or a configuring a new vif.  The
+# vif-bridge script is designed for use with the network-bridge script, or
+# similar configurations.
+#
+# If you have overridden the bridge name using
+# (network-script 'network-bridge bridge=<name>') then you may wish to do the
+# same here.  The bridge name can also be set when creating a domain or
+# configuring a new vif, but a value specified here would act as a default.
+#
+# If you are using only one bridge, the vif-bridge script will discover that,
+# so there is no need to specify it explicitly.
+#
+(vif-script vif-bridge)
+
+
+## Use the following if network traffic is routed, as an alternative to the
+# settings for bridged networking given above.
+#(network-script network-route)
+#(vif-script     vif-route)
+
+
+## Use the following if network traffic is routed with NAT, as an alternative
+# to the settings for bridged networking given above.
+#(network-script network-nat)
+#(vif-script     vif-nat)
+
+
+# Dom0 will balloon out when needed to free memory for domU.
+# dom0-min-mem is the lowest memory level (in MB) dom0 will get down to.
+# If dom0-min-mem=0, dom0 will never balloon out.
+(dom0-min-mem 196)
+
+# In SMP system, dom0 will use dom0-cpus # of CPUS
+# If dom0-cpus = 0, dom0 will take all cpus available
+(dom0-cpus 0)
+
+# Whether to enable core-dumps when domains crash.
+#(enable-dump no)
+
+# The tool used for initiating virtual TPM migration
+#(external-migration-tool '')
+
+# The interface for VNC servers to listen on. Defaults
+# to 127.0.0.1  To restore old 'listen everywhere' behaviour
+# set this to 0.0.0.0
+#(vnc-listen '127.0.0.1')
+
+# The default password for VNC console on HVM domain.
+# Empty string is no authentication.
+(vncpasswd '')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/examples/xend-config.sxp    Fri Mar 30 17:18:42 2007 -0600
@@ -46,6 +46,11 @@
 #   (xen-api-server ((9363 pam '^localhost$ example\\.com$')
 #                    (unix none)))
 #
+# Optionally, the TCP Xen-API server can use SSL by specifying the private
+# key and certificate location:
+#
+#                    (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
+#
 # Default:
 #   (xen-api-server ((unix)))
 
@@ -59,10 +64,17 @@
 
 #(xend-unix-path /var/lib/xend/xend-socket)
 
-# Address and port xend should use for the TCP XMLRPC interface, 
+
+# Address and port xend should use for the legacy TCP XMLRPC interface, 
 # if xen-tcp-xmlrpc-server is set.
 #(xen-tcp-xmlrpc-server-address 'localhost')
 #(xen-tcp-xmlrpc-server-port 8006)
+
+# SSL key and certificate to use for the legacy TCP XMLRPC interface.
+# Setting these will mean that this port serves only SSL connections as
+# opposed to plaintext ones.
+#(xend-tcp-xmlrpc-server-ssl-key-file  /etc/xen/xmlrpc.key)
+#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
 
 
 # Port xend should use for the HTTP interface, if xend-http-server is set.
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/xm-config-xenapi.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/xm-config-xenapi.xml       Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,43 @@
+<!--
+
+Copyright (C) 2006 XenSource Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of version 2.1 of the GNU Lesser General Public
+License as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+-->
+
+<!--
+
+This is a configuration file for xm; it should be placed in
+/etc/xen/xm-config.xml.  If this file is missing, then xm will fall back to
+the normal behaviour that's in Xen 3.0.4 and below.  The settings here are
+most useful for experimenting with the Xen-API preview in Xen 3.0.4.
+
+-->
+
+<xm>
+  <!-- The server element describes how to talk to Xend.  The type may be 
+       Xen-API or LegacyXMLRPC (the default).  The URI is that of the
+       server; you might try http://server:9363/ or
+       httpu:///var/run/xend/xen-api.sock for the Xen-API, or
+       httpu:///var/run/xend/xmlrpc.sock for the legacy server.
+
+       The username and password attributes will be used to log in if Xen-API
+       is being used.
+    -->
+  <server type='Xen-API'
+          uri='http://localhost:9363/'
+          username='me'
+          password='mypassword' />
+</xm>
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/ne2000.c   Fri Mar 30 17:18:42 2007 -0600
@@ -770,7 +770,7 @@ void isa_ne2000_init(int base, int irq, 
              s->macaddr[4],
              s->macaddr[5]);
              
-    register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
+    register_savevm("ne2000", base, 2, ne2000_save, ne2000_load, s);
 }
 
 /***********************************************************/
@@ -806,6 +806,7 @@ void pci_ne2000_init(PCIBus *bus, NICInf
     PCINE2000State *d;
     NE2000State *s;
     uint8_t *pci_conf;
+    int instance;
     
     d = (PCINE2000State *)pci_register_device(bus,
                                               "NE2000", sizeof(PCINE2000State),
@@ -840,8 +841,8 @@ void pci_ne2000_init(PCIBus *bus, NICInf
              s->macaddr[4],
              s->macaddr[5]);
              
-    /* XXX: instance number ? */
-    register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
-    register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load, 
-                    &d->dev);
-}
+    instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
+    register_savevm("ne2000", instance, 2, ne2000_save, ne2000_load, s);
+    register_savevm("ne2000_pci", instance, 1, generic_pci_save, 
+                    generic_pci_load, &d->dev);
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/pcnet.c
--- a/tools/ioemu/hw/pcnet.c    Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/pcnet.c    Fri Mar 30 17:18:42 2007 -0600
@@ -1727,10 +1727,63 @@ static void pcnet_mmio_map(PCIDevice *pc
     cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_io_addr);
 }
 
+
+static void pcnet_save(QEMUFile *f, void *opaque)
+{
+    PCNetState *s = opaque;
+    unsigned int i;
+
+    qemu_put_be32s(f, &s->rap);
+    qemu_put_be32s(f, &s->isr);
+    qemu_put_be32s(f, &s->lnkst);
+    qemu_put_be32s(f, &s->rdra);
+    qemu_put_be32s(f, &s->tdra);
+    qemu_put_buffer(f, s->prom, 16);
+    for (i = 0; i < 128; i++)
+        qemu_put_be16s(f, &s->csr[i]);
+    for (i = 0; i < 32; i++)
+        qemu_put_be16s(f, &s->bcr[i]);
+    qemu_put_be64s(f, &s->timer);
+    qemu_put_be32s(f, &s->xmit_pos);
+    qemu_put_be32s(f, &s->recv_pos);
+    qemu_put_buffer(f, s->buffer, 4096);
+    qemu_put_be32s(f, &s->tx_busy);
+    qemu_put_timer(f, s->poll_timer);
+}
+
+static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PCNetState *s = opaque;
+    int i, ret;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_be32s(f, &s->rap);
+    qemu_get_be32s(f, &s->isr);
+    qemu_get_be32s(f, &s->lnkst);
+    qemu_get_be32s(f, &s->rdra);
+    qemu_get_be32s(f, &s->tdra);
+    qemu_get_buffer(f, s->prom, 16);
+    for (i = 0; i < 128; i++)
+        qemu_get_be16s(f, &s->csr[i]);
+    for (i = 0; i < 32; i++)
+        qemu_get_be16s(f, &s->bcr[i]);
+    qemu_get_be64s(f, &s->timer);
+    qemu_get_be32s(f, &s->xmit_pos);
+    qemu_get_be32s(f, &s->recv_pos);
+    qemu_get_buffer(f, s->buffer, 4096);
+    qemu_get_be32s(f, &s->tx_busy);
+    qemu_get_timer(f, s->poll_timer);
+
+    return 0;
+}
+
 void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
 {
     PCNetState *d;
     uint8_t *pci_conf;
+    int instance;
 
 #if 0
     printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
@@ -1775,6 +1828,11 @@ void pci_pcnet_init(PCIBus *bus, NICInfo
 
     d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
                                  pcnet_can_receive, d);
+
+    instance = pci_bus_num(bus) << 8 | d->dev.devfn;
+    register_savevm("pcnet", instance, 1, pcnet_save, pcnet_load, d);
+    register_savevm("pcnet_pci", instance, 1, generic_pci_save,
+                    generic_pci_load, &d->dev);
     
     snprintf(d->vc->info_str, sizeof(d->vc->info_str),
              "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/piix4acpi.c
--- a/tools/ioemu/hw/piix4acpi.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/piix4acpi.c        Fri Mar 30 17:18:42 2007 -0600
@@ -57,6 +57,20 @@ typedef struct PCIAcpiState {
     uint16_t pm1_control; /* pm1a_ECNT_BLK */
 } PCIAcpiState;
 
+static void piix4acpi_save(QEMUFile *f, void *opaque)
+{
+    PCIAcpiState *s = opaque;
+    qemu_put_be16s(f, &s->pm1_control);
+}
+
+static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PCIAcpiState *s = opaque;
+    if (version_id > 1) 
+        return -EINVAL;
+    qemu_get_be16s(f, &s->pm1_control);
+}
+
 static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     PCIAcpiState *s = opaque;
@@ -193,4 +207,8 @@ void pci_piix4_acpi_init(PCIBus *bus, in
     d->pm1_control = SCI_EN;
 
     acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
-}
+
+    register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);    
+    register_savevm("piix4acpi_pci", 0, 1, generic_pci_save, generic_pci_load, 
+                    &d->dev);
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/rtl8139.c
--- a/tools/ioemu/hw/rtl8139.c  Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/rtl8139.c  Fri Mar 30 17:18:42 2007 -0600
@@ -3406,6 +3406,7 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
     PCIRTL8139State *d;
     RTL8139State *s;
     uint8_t *pci_conf;
+    int instance;
     
     d = (PCIRTL8139State *)pci_register_device(bus,
                                               "RTL8139", 
sizeof(PCIRTL8139State),
@@ -3460,10 +3461,10 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
     s->cplus_txbuffer_len = 0;
     s->cplus_txbuffer_offset = 0;
              
-    /* XXX: instance number ? */
-    register_savevm("rtl8139", 0, 2, rtl8139_save, rtl8139_load, s);
-    register_savevm("rtl8139_pci", 0, 1, generic_pci_save, generic_pci_load, 
-                    &d->dev);
+    instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
+    register_savevm("rtl8139", instance, 2, rtl8139_save, rtl8139_load, s);
+    register_savevm("rtl8139_pci", instance, 1, generic_pci_save, 
+                    generic_pci_load, &d->dev);
 
 #if RTL8139_ONBOARD_TIMER
     s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/usb-uhci.c
--- a/tools/ioemu/hw/usb-uhci.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/usb-uhci.c Fri Mar 30 17:18:42 2007 -0600
@@ -700,6 +700,7 @@ int uhci_usb_load(QEMUFile *f, void *opa
 
     qemu_get_timer(f, s->frame_timer);
 
+    return 0;
 }
 
 void usb_uhci_init(PCIBus *bus, int devfn)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/vl.c  Fri Mar 30 17:18:42 2007 -0600
@@ -6109,10 +6109,9 @@ int main(int argc, char **argv)
 #endif /* !CONFIG_DM */
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
-    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-
-    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
-    for(i = 1; i < MAX_SERIAL_PORTS; i++)
+    pstrcpy(monitor_device, sizeof(monitor_device), "null");
+
+    for(i = 0; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i][0] = '\0';
     serial_device_index = 0;
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxc/xc_hvm_restore.c
--- a/tools/libxc/xc_hvm_restore.c      Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxc/xc_hvm_restore.c      Fri Mar 30 17:18:42 2007 -0600
@@ -81,7 +81,7 @@ int xc_hvm_restore(int xc_handle, int io
     unsigned int rc = 1, n, i;
     uint32_t rec_len, nr_vcpus;
     uint8_t *hvm_buf = NULL;
-    unsigned long long v_end, memsize;
+    unsigned long long v_end;
     unsigned long shared_page_nr;
 
     unsigned long pfn;
@@ -91,16 +91,19 @@ int xc_hvm_restore(int xc_handle, int io
     /* Types of the pfns in the current region */
     unsigned long region_pfn_type[MAX_BATCH_SIZE];
 
-    /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
-    unsigned long nr_pages;
-
     /* The size of an array big enough to contain all guest pfns */
     unsigned long pfn_array_size = max_pfn + 1;
 
-    /* hvm guest mem size (Mb) */
-    memsize = (unsigned long long)*store_mfn;
-    v_end = memsize << 20;
-    nr_pages = (unsigned long) memsize << (20 - PAGE_SHIFT);
+    /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
+    unsigned long nr_pages = max_pfn + 1;
+    /* MMIO hole doesn't contain RAM */
+    if ( nr_pages >= HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT ) 
+        nr_pages -= HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; 
+    /* VGA hole doesn't contain RAM */
+    nr_pages -= 0x20;
+
+    /* XXX: Unlikely to be true, but matches previous behaviour. :( */
+    v_end = (nr_pages + 0x20) << PAGE_SHIFT;
 
     DPRINTF("xc_hvm_restore:dom=%d, nr_pages=0x%lx, store_evtchn=%d, "
             "*store_mfn=%ld, pae=%u, apic=%u.\n", 
@@ -146,7 +149,7 @@ int xc_hvm_restore(int xc_handle, int io
         0, 0, &pfns[0x00]);
     if ( (rc == 0) && (nr_pages > 0xc0) )
         rc = xc_domain_memory_populate_physmap(
-            xc_handle, dom, nr_pages - 0xc0, 0, 0, &pfns[0xc0]);
+            xc_handle, dom, nr_pages - 0xa0, 0, 0, &pfns[0xc0]);
     if ( rc != 0 )
     {
         PERROR("Could not allocate memory for HVM guest.\n");
@@ -276,14 +279,6 @@ int xc_hvm_restore(int xc_handle, int io
     else
         shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
 
-    /* Paranoia: clean pages. */
-    if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) ||
-         xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) ||
-         xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) ) {
-        ERROR("error clearing comms frames!\n");
-        goto out;
-    }
-
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/Makefile
--- a/tools/libxen/Makefile     Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/Makefile     Fri Mar 30 17:18:42 2007 -0600
@@ -51,6 +51,9 @@ test/test_bindings: test/test_bindings.o
 test/test_bindings: test/test_bindings.o libxenapi.so
        $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
 
+test/test_event_handling: test/test_event_handling.o libxenapi.so
+       $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
+
 test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so
        $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_event.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event.h  Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#ifndef XEN_EVENT_H
+#define XEN_EVENT_H
+
+#include "xen_common.h"
+#include "xen_event_decl.h"
+#include "xen_event_operation.h"
+#include "xen_string_set.h"
+
+
+/*
+ * The event class.
+ * 
+ * Asynchronous event registration and handling.
+ */
+
+
+
+typedef struct xen_event_record
+{
+    int64_t id;
+    time_t timestamp;
+    char *class;
+    enum xen_event_operation operation;
+    char *ref;
+    char *obj_uuid;
+} xen_event_record;
+
+/**
+ * Allocate a xen_event_record.
+ */
+extern xen_event_record *
+xen_event_record_alloc(void);
+
+/**
+ * Free the given xen_event_record, and all referenced values.  The
+ * given record must have been allocated by this library.
+ */
+extern void
+xen_event_record_free(xen_event_record *record);
+
+
+typedef struct xen_event_record_set
+{
+    size_t size;
+    xen_event_record *contents[];
+} xen_event_record_set;
+
+/**
+ * Allocate a xen_event_record_set of the given size.
+ */
+extern xen_event_record_set *
+xen_event_record_set_alloc(size_t size);
+
+/**
+ * Free the given xen_event_record_set, and all referenced values.  The
+ * given set must have been allocated by this library.
+ */
+extern void
+xen_event_record_set_free(xen_event_record_set *set);
+
+
+/**
+ * Registers this session with the event system.  Specifying the empty
+ * list will register for all classes.
+ */
+extern bool
+xen_event_register(xen_session *session, struct xen_string_set *classes);
+
+
+/**
+ * Unregisters this session with the event system.
+ */
+extern bool
+xen_event_unregister(xen_session *session, struct xen_string_set *classes);
+
+
+/**
+ * Blocking call which returns a (possibly empty) batch of events.
+ */
+extern bool
+xen_event_next(xen_session *session, struct xen_event_record_set **result);
+
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_event_decl.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event_decl.h     Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#ifndef XEN_EVENT_DECL_H
+#define XEN_EVENT_DECL_H
+
+struct xen_event_record;
+struct xen_event_record_set;
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_event_operation.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event_operation.h        Fri Mar 30 17:18:42 
2007 -0600
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#ifndef XEN_EVENT_OPERATION_H
+#define XEN_EVENT_OPERATION_H
+
+
+#include "xen_common.h"
+
+
+enum xen_event_operation
+{
+    /**
+     * An object has been created
+     */
+    XEN_EVENT_OPERATION_ADD,
+
+    /**
+     * An object has been deleted
+     */
+    XEN_EVENT_OPERATION_DEL,
+
+    /**
+     * An object has been modified
+     */
+    XEN_EVENT_OPERATION_MOD
+};
+
+
+typedef struct xen_event_operation_set
+{
+    size_t size;
+    enum xen_event_operation contents[];
+} xen_event_operation_set;
+
+/**
+ * Allocate a xen_event_operation_set of the given size.
+ */
+extern xen_event_operation_set *
+xen_event_operation_set_alloc(size_t size);
+
+/**
+ * Free the given xen_event_operation_set.  The given set must have
+ * been allocated by this library.
+ */
+extern void
+xen_event_operation_set_free(xen_event_operation_set *set);
+
+
+/**
+ * Return the name corresponding to the given code.  This string must
+ * not be modified or freed.
+ */
+extern const char *
+xen_event_operation_to_string(enum xen_event_operation val);
+
+
+/**
+ * Return the correct code for the given string, or set the session
+ * object to failure and return an undefined value if the given string does
+ * not match a known code.
+ */
+extern enum xen_event_operation
+xen_event_operation_from_string(xen_session *session, const char *str);
+
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
tools/libxen/include/xen_event_operation_internal.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event_operation_internal.h       Fri Mar 30 
17:18:42 2007 -0600
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+
+/*
+ * Declarations of the abstract types used during demarshalling of enum
+ * xen_event_operation.  Internal to this library -- do not use from outside.
+ */
+
+
+#ifndef XEN_EVENT_OPERATION_INTERNAL_H
+#define XEN_EVENT_OPERATION_INTERNAL_H
+
+
+#include "xen_internal.h"
+
+
+extern const abstract_type xen_event_operation_abstract_type_;
+extern const abstract_type xen_event_operation_set_abstract_type_;
+
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_network.h
--- a/tools/libxen/include/xen_network.h        Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/include/xen_network.h        Fri Mar 30 17:18:42 2007 -0600
@@ -22,6 +22,7 @@
 #include "xen_common.h"
 #include "xen_network_decl.h"
 #include "xen_pif_decl.h"
+#include "xen_string_string_map.h"
 #include "xen_vif_decl.h"
 
 
@@ -68,6 +69,7 @@ typedef struct xen_network_record
     char *name_description;
     struct xen_vif_record_opt_set *vifs;
     struct xen_pif_record_opt_set *pifs;
+    xen_string_string_map *other_config;
 } xen_network_record;
 
 /**
@@ -220,6 +222,13 @@ xen_network_get_pifs(xen_session *sessio
 
 
 /**
+ * Get the other_config field of the given network.
+ */
+extern bool
+xen_network_get_other_config(xen_session *session, xen_string_string_map 
**result, xen_network network);
+
+
+/**
  * Set the name/label field of the given network.
  */
 extern bool
@@ -234,6 +243,30 @@ xen_network_set_name_description(xen_ses
 
 
 /**
+ * Set the other_config field of the given network.
+ */
+extern bool
+xen_network_set_other_config(xen_session *session, xen_network network, 
xen_string_string_map *other_config);
+
+
+/**
+ * Add the given key-value pair to the other_config field of the given
+ * network.
+ */
+extern bool
+xen_network_add_to_other_config(xen_session *session, xen_network network, 
char *key, char *value);
+
+
+/**
+ * Remove the given key and its corresponding value from the
+ * other_config field of the given network.  If the key is not in that Map,
+ * then do nothing.
+ */
+extern bool
+xen_network_remove_from_other_config(xen_session *session, xen_network 
network, char *key);
+
+
+/**
  * Return a list of all the networks known to the system.
  */
 extern bool
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_common.c
--- a/tools/libxen/src/xen_common.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/src/xen_common.c     Fri Mar 30 17:18:42 2007 -0600
@@ -1217,11 +1217,88 @@ static void parse_result(xen_session *se
 }
 
 
+static void
+make_body_add_type(enum abstract_typename typename, abstract_value *v,
+                   xmlNode *params_node)
+{
+    char buf[20];
+    switch (typename)
+    {
+    case STRING:
+        add_param(params_node, "string", v->u.string_val);
+        break;
+
+    case INT:
+        snprintf(buf, sizeof(buf), "%"PRId64, v->u.int_val);
+        add_param(params_node, "string", buf);
+        break;
+
+    case FLOAT:
+        snprintf(buf, sizeof(buf), "%lf", v->u.float_val);
+        add_param(params_node, "double", buf);
+        break;
+
+    case BOOL:
+        add_param(params_node, "boolean", v->u.bool_val ? "1" : "0");
+        break;
+        
+    case VOID:
+        add_param(params_node, "string", "");
+        break;
+
+    case ENUM:
+        add_param(params_node, "string",
+                  v->type->enum_marshaller(v->u.enum_val));
+        break;
+
+    case SET:
+    {
+        const struct abstract_type *member_type = v->type->child;
+        arbitrary_set *set_val = v->u.struct_val;
+        abstract_value v;
+        xmlNode *data_node = add_param_struct(params_node);
+
+        for (size_t i = 0; i < set_val->size; i++)
+        {
+            switch (member_type->typename) {
+                case STRING:
+                    v.u.string_val = (char *)set_val->contents[i];
+                    make_body_add_type(member_type->typename, &v, data_node);
+                    break;
+                default:
+                    assert(false);
+            }
+        }
+    }
+    break;
+
+    case STRUCT:
+    {
+        size_t member_count = v->type->member_count;
+
+        xmlNode *struct_node = add_param_struct(params_node);
+
+        for (size_t i = 0; i < member_count; i++)
+        {
+            const struct struct_member *mem = v->type->members + i;
+            const char *key = mem->key;
+            void *struct_value = v->u.struct_val;
+
+            add_struct_value(mem->type, struct_value + mem->offset,
+                             add_struct_member, key, struct_node);
+        }
+    }
+    break;
+
+    default:
+        assert(false);
+    }
+}
+
+
 static char *
 make_body(const char *method_name, abstract_value params[], int param_count)
 {
-    char buf[20];
-
     xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
     xmlNode *methodCall = xmlNewNode(NULL, BAD_CAST "methodCall");
     xmlDocSetRootElement(doc, methodCall);
@@ -1235,56 +1312,7 @@ make_body(const char *method_name, abstr
     for (int p = 0; p < param_count; p++)
     {
         abstract_value *v = params + p;
-        switch (v->type->typename)
-        {
-        case STRING:
-            add_param(params_node, "string", v->u.string_val);
-            break;
-
-        case INT:
-            snprintf(buf, sizeof(buf), "%"PRId64, v->u.int_val);
-            add_param(params_node, "string", buf);
-            break;
-
-        case FLOAT:
-            snprintf(buf, sizeof(buf), "%lf", v->u.float_val);
-            add_param(params_node, "double", buf);
-            break;
-
-        case BOOL:
-            add_param(params_node, "boolean", v->u.bool_val ? "1" : "0");
-            break;
-            
-        case VOID:
-            add_param(params_node, "string", "");
-            break;
-
-        case ENUM:
-            add_param(params_node, "string",
-                      v->type->enum_marshaller(v->u.enum_val));
-            break;
-
-        case STRUCT:
-        {
-            size_t member_count = v->type->member_count;
-
-            xmlNode *struct_node = add_param_struct(params_node);
-
-            for (size_t i = 0; i < member_count; i++)
-            {
-                const struct struct_member *mem = v->type->members + i;
-                const char *key = mem->key;
-                void *struct_value = v->u.struct_val;
-
-                add_struct_value(mem->type, struct_value + mem->offset,
-                                 add_struct_member, key, struct_node);
-            }
-        }
-        break;
-
-        default:
-            assert(false);
-        }
+        make_body_add_type(v->type->typename, v, params_node);
     }
 
     xmlBufferPtr buffer = xmlBufferCreate();
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_event.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_event.c      Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "xen_common.h"
+#include "xen_event.h"
+#include "xen_event_operation_internal.h"
+#include "xen_internal.h"
+
+
+XEN_ALLOC(xen_event_record)
+XEN_SET_ALLOC_FREE(xen_event_record)
+
+
+static const struct_member xen_event_record_struct_members[] =
+    {
+        { .key = "id",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_event_record, id) },
+        { .key = "timestamp",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_event_record, timestamp) },
+        { .key = "class",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_event_record, class) },
+        { .key = "operation",
+          .type = &xen_event_operation_abstract_type_,
+          .offset = offsetof(xen_event_record, operation) },
+        { .key = "ref",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_event_record, ref) },
+        { .key = "obj_uuid",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_event_record, obj_uuid) }
+    };
+
+const abstract_type xen_event_record_abstract_type_ =
+    {
+       .typename = STRUCT,
+       .struct_size = sizeof(xen_event_record),
+       .member_count =
+           sizeof(xen_event_record_struct_members) / sizeof(struct_member),
+       .members = xen_event_record_struct_members
+    };
+
+
+const abstract_type xen_event_record_set_abstract_type_ =
+    {
+       .typename = SET,
+        .child = &xen_event_record_abstract_type_
+    };
+
+
+void
+xen_event_record_free(xen_event_record *record)
+{
+    if (record == NULL)
+    {
+        return;
+    }
+    free(record->class);
+    free(record->ref);
+    free(record->obj_uuid);
+    free(record);
+}
+
+
+bool
+xen_event_register(xen_session *session, struct xen_string_set *classes)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string_set,
+              .u.set_val = (arbitrary_set *)classes }
+        };
+
+    xen_call_(session, "event.register", param_values, 1, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_event_unregister(xen_session *session, struct xen_string_set *classes)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string_set,
+              .u.set_val = (arbitrary_set *)classes }
+        };
+
+    xen_call_(session, "event.unregister", param_values, 1, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_event_next(xen_session *session, struct xen_event_record_set **result)
+{
+
+    abstract_type result_type = xen_event_record_set_abstract_type_;
+
+    *result = NULL;
+    xen_call_(session, "event.next", NULL, 0, &result_type, result);
+    return session->ok;
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_event_operation.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_event_operation.c    Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#include <string.h>
+
+#include "xen_internal.h"
+#include "xen_event_operation.h"
+#include "xen_event_operation_internal.h"
+
+
+/*
+ * Maintain this in the same order as the enum declaration!
+ */
+static const char *lookup_table[] =
+{
+    "add",
+    "del",
+    "mod"
+};
+
+
+extern xen_event_operation_set *
+xen_event_operation_set_alloc(size_t size)
+{
+    return calloc(1, sizeof(xen_event_operation_set) +
+                  size * sizeof(enum xen_event_operation));
+}
+
+
+extern void
+xen_event_operation_set_free(xen_event_operation_set *set)
+{
+    free(set);
+}
+
+
+const char *
+xen_event_operation_to_string(enum xen_event_operation val)
+{
+    return lookup_table[val];
+}
+
+
+extern enum xen_event_operation
+xen_event_operation_from_string(xen_session *session, const char *str)
+{
+    return ENUM_LOOKUP(session, str, lookup_table);
+}
+
+
+const abstract_type xen_event_operation_abstract_type_ =
+    {
+        .typename = ENUM,
+        .enum_marshaller =
+             (const char *(*)(int))&xen_event_operation_to_string,
+        .enum_demarshaller =
+             (int (*)(xen_session *, const char 
*))&xen_event_operation_from_string
+    };
+
+
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_network.c
--- a/tools/libxen/src/xen_network.c    Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/src/xen_network.c    Fri Mar 30 17:18:42 2007 -0600
@@ -24,6 +24,7 @@
 #include "xen_internal.h"
 #include "xen_network.h"
 #include "xen_pif.h"
+#include "xen_string_string_map.h"
 #include "xen_vif.h"
 
 
@@ -52,7 +53,10 @@ static const struct_member xen_network_r
           .offset = offsetof(xen_network_record, vifs) },
         { .key = "PIFs",
           .type = &abstract_type_ref_set,
-          .offset = offsetof(xen_network_record, pifs) }
+          .offset = offsetof(xen_network_record, pifs) },
+        { .key = "other_config",
+          .type = &abstract_type_string_string_map,
+          .offset = offsetof(xen_network_record, other_config) }
     };
 
 const abstract_type xen_network_record_abstract_type_ =
@@ -78,6 +82,7 @@ xen_network_record_free(xen_network_reco
     free(record->name_description);
     xen_vif_record_opt_set_free(record->vifs);
     xen_pif_record_opt_set_free(record->pifs);
+    xen_string_string_map_free(record->other_config);
     free(record);
 }
 
@@ -239,6 +244,23 @@ xen_network_get_pifs(xen_session *sessio
 
 
 bool
+xen_network_get_other_config(xen_session *session, xen_string_string_map 
**result, xen_network network)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network }
+        };
+
+    abstract_type result_type = abstract_type_string_string_map;
+
+    *result = NULL;
+    XEN_CALL_("network.get_other_config");
+    return session->ok;
+}
+
+
+bool
 xen_network_set_name_label(xen_session *session, xen_network network, char 
*label)
 {
     abstract_value param_values[] =
@@ -271,6 +293,56 @@ xen_network_set_name_description(xen_ses
 
 
 bool
+xen_network_set_other_config(xen_session *session, xen_network network, 
xen_string_string_map *other_config)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network },
+            { .type = &abstract_type_string_string_map,
+              .u.set_val = (arbitrary_set *)other_config }
+        };
+
+    xen_call_(session, "network.set_other_config", param_values, 2, NULL, 
NULL);
+    return session->ok;
+}
+
+
+bool
+xen_network_add_to_other_config(xen_session *session, xen_network network, 
char *key, char *value)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network },
+            { .type = &abstract_type_string,
+              .u.string_val = key },
+            { .type = &abstract_type_string,
+              .u.string_val = value }
+        };
+
+    xen_call_(session, "network.add_to_other_config", param_values, 3, NULL, 
NULL);
+    return session->ok;
+}
+
+
+bool
+xen_network_remove_from_other_config(xen_session *session, xen_network 
network, char *key)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network },
+            { .type = &abstract_type_string,
+              .u.string_val = key }
+        };
+
+    xen_call_(session, "network.remove_from_other_config", param_values, 2, 
NULL, NULL);
+    return session->ok;
+}
+
+
+bool
 xen_network_get_all(xen_session *session, struct xen_network_set **result)
 {
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/test/test_event_handling.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/test/test_event_handling.c   Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2006-2007 XenSource, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/parser.h>
+#include <curl/curl.h>
+
+#include "xen_event.h"
+
+//#define PRINT_XML
+
+static void usage()
+{
+    fprintf(stderr,
+"Usage:\n"
+"\n"
+"    test_event_handling <server> <username> <password>\n"
+"\n"
+"where\n"
+"        <server>   is the server's host and port, e.g. localhost:9363;\n"
+"        <username> is the username to use at the server; and\n"
+"        <password> is the password.\n");
+
+    exit(EXIT_FAILURE);
+}
+
+
+static char *url;
+
+
+typedef struct
+{
+    xen_result_func func;
+    void *handle;
+} xen_comms;
+
+
+static size_t
+write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
+{
+    size_t n = size * nmemb;
+#ifdef PRINT_XML
+    printf("\n\n---Result from server -----------------------\n");
+    printf("%s\n",((char*) ptr));
+    fflush(stdout);
+#endif
+    return comms->func(ptr, n, comms->handle) ? n : 0;
+}
+
+
+static int
+call_func(const void *data, size_t len, void *user_handle,
+          void *result_handle, xen_result_func result_func)
+{
+    (void)user_handle;
+
+#ifdef PRINT_XML
+    printf("\n\n---Data to server: -----------------------\n");
+    printf("%s\n",((char*) data));
+    fflush(stdout);
+#endif
+
+    CURL *curl = curl_easy_init();
+    if (!curl) {
+        return -1;
+    }
+
+    xen_comms comms = {
+        .func = result_func,
+        .handle = result_handle
+    };
+
+    curl_easy_setopt(curl, CURLOPT_URL, url);
+    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(curl, CURLOPT_MUTE, 1);
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
+    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
+    curl_easy_setopt(curl, CURLOPT_POST, 1);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
+
+    CURLcode result = curl_easy_perform(curl);
+
+    curl_easy_cleanup(curl);
+
+    return result;
+}
+
+
+static void print_error(xen_session *session)
+{
+    fprintf(stderr, "Error: %d", session->error_description_count);
+    for (int i = 0; i < session->error_description_count; i++)
+    {
+        fprintf(stderr, "%s ", session->error_description[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+
+/**
+ * Workaround for whinging GCCs, as suggested by strftime(3).
+ */
+static size_t my_strftime(char *s, size_t max, const char *fmt,
+                          const struct tm *tm)
+{
+    return strftime(s, max, fmt, tm);
+}
+
+
+int main(int argc, char **argv)
+{
+    if (argc != 4)
+    {
+        usage();
+    }
+
+    url = argv[1];
+    char *username = argv[2];
+    char *password = argv[3];
+
+    xmlInitParser();
+    xen_init();
+    curl_global_init(CURL_GLOBAL_ALL);
+
+#define CLEANUP                                 \
+    do {                                        \
+        xen_session_logout(session);            \
+        curl_global_cleanup();                  \
+        xen_fini();                             \
+        xmlCleanupParser();                     \
+    } while(0)                                  \
+
+    
+    xen_session *session =
+        xen_session_login_with_password(call_func, NULL, username, password);
+
+    struct xen_string_set *classes = xen_string_set_alloc(0);
+    xen_event_register(session, classes);
+    xen_string_set_free(classes);
+
+    if (!session->ok)
+    {
+        print_error(session);
+        CLEANUP;
+        return 1;
+    }
+
+    while (true)
+    {
+        struct xen_event_record_set *events;
+        if (!xen_event_next(session, &events))
+        {
+            print_error(session);
+            CLEANUP;
+            return 1;
+        }
+
+        for (size_t i = 0; i < events->size; i++)
+        {
+            xen_event_record *ev = events->contents[i];
+            char time[256];
+            struct tm *tm = localtime(&ev->timestamp);
+            my_strftime(time, 256, "%c, local time", tm);
+            printf("Event received: ID = %"PRId64", %s.\n", ev->id, time);
+            switch (ev->operation)
+            {
+            case XEN_EVENT_OPERATION_ADD:
+                printf("%s created with UUID %s.\n", ev->class, ev->obj_uuid);
+                break;
+
+            case XEN_EVENT_OPERATION_DEL:
+                printf("%s with UUID %s deleted.\n", ev->class, ev->obj_uuid);
+                break;
+
+            case XEN_EVENT_OPERATION_MOD:
+                printf("%s with UUID %s modified.\n", ev->class, ev->obj_uuid);
+                break;
+            default:
+                assert(false);
+            }
+        }
+
+        xen_event_record_set_free(events);
+    }
+
+    CLEANUP;
+
+    return 0;
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/pygrub/src/pygrub   Fri Mar 30 17:18:42 2007 -0600
@@ -125,16 +125,13 @@ class GrubLineEditor(curses.textpad.Text
         is that we can handle lines longer than the window."""
 
         self.win.clear()
-        if self.pos > 70:
-            if self.pos > 130:
-                off = 120
-            else:
-                off = 55
-            l = [ "<" ] + self.line[off:]
-            p = self.pos - off
-        else:
-            l = self.line[:70]
-            p = self.pos
+        p = self.pos
+        off = 0
+        while p > 70:
+            p -= 55
+            off += 55
+
+        l = self.line[off:off+70]
         self.win.addstr(0, 0, string.join(l, ("")))
         if self.pos > 70:
             self.win.addch(0, 0, curses.ACS_LARROW)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Mar 30 17:18:42 2007 -0600
@@ -467,6 +467,26 @@ static PyObject *pyxc_linux_build(XcObje
     return pyxc_error_to_exception();
 }
 
+static PyObject *pyxc_get_hvm_param(XcObject *self,
+                                    PyObject *args,
+                                    PyObject *kwds)
+{
+    uint32_t dom;
+    int param;
+    unsigned long value;
+
+    static char *kwd_list[] = { "domid", "param", NULL }; 
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
+                                      &dom, &param) )
+        return NULL;
+
+    if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
+        return pyxc_error_to_exception();
+
+    return Py_BuildValue("i", value);
+
+}
+
 static PyObject *pyxc_hvm_build(XcObject *self,
                                 PyObject *args,
                                 PyObject *kwds)
@@ -1224,6 +1244,14 @@ static PyMethodDef pyxc_methods[] = {
       " image   [str]:      Name of HVM loader image file.\n"
       " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "hvm_get_param", 
+      (PyCFunction)pyxc_get_hvm_param, 
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "get a parameter of HVM guest OS.\n"
+      " dom     [int]:      Identifier of domain to build into.\n"
+      " param   [int]:      No. of HVM param.\n"
+      "Returns: [int] value of the param.\n" },
 
     { "sched_id_get",
       (PyCFunction)pyxc_sched_id_get,
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/util/xmlrpcclient.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xmlrpcclient.py     Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,123 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+# Copyright (C) 2007 XenSource Inc.
+#============================================================================
+
+
+from httplib import FakeSocket, HTTPConnection, HTTP
+import socket
+import string
+import xmlrpclib
+from types import StringTypes
+
+
+try:
+    import SSHTransport
+    ssh_enabled = True
+except ImportError:
+    # SSHTransport is disabled on Python <2.4, because it uses the subprocess
+    # package.
+    ssh_enabled = False
+
+
+# A new ServerProxy that also supports httpu urls.  An http URL comes in the
+# form:
+#
+# httpu:///absolute/path/to/socket.sock
+#
+# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
+
+class HTTPUnixConnection(HTTPConnection):
+    def connect(self):
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.sock.connect(self.host)
+
+class HTTPUnix(HTTP):
+    _connection_class = HTTPUnixConnection
+
+class UnixTransport(xmlrpclib.Transport):
+    def request(self, host, handler, request_body, verbose=0):
+        self.__handler = handler
+        return xmlrpclib.Transport.request(self, host, '/RPC2',
+                                           request_body, verbose)
+    def make_connection(self, host):
+        return HTTPUnix(self.__handler)
+
+
+# We need our own transport for HTTPS, because xmlrpclib.SafeTransport is
+# broken -- it does not handle ERROR_ZERO_RETURN properly.
+class HTTPSTransport(xmlrpclib.SafeTransport):
+    def _parse_response(self, file, sock):
+        p, u = self.getparser()
+        while 1:
+            try:
+                if sock:
+                    response = sock.recv(1024)
+                else:
+                    response = file.read(1024)
+            except socket.sslerror, exn:
+                if exn[0] == socket.SSL_ERROR_ZERO_RETURN:
+                    break
+                raise
+                
+            if not response:
+                break
+            if self.verbose:
+                print 'body:', repr(response)
+            p.feed(response)
+            
+        file.close()
+        p.close()
+        return u.close()
+
+
+# See xmlrpclib2.TCPXMLRPCServer._marshalled_dispatch.
+def conv_string(x):
+    if isinstance(x, StringTypes):
+        s = string.replace(x, "'", r"\047")
+        exec "s = '" + s + "'"
+        return s
+    else:
+        return x
+
+
+class ServerProxy(xmlrpclib.ServerProxy):
+    def __init__(self, uri, transport=None, encoding=None, verbose=0,
+                 allow_none=1):
+        if transport == None:
+            (protocol, rest) = uri.split(':', 1)
+            if protocol == 'httpu':
+                uri = 'http:' + rest
+                transport = UnixTransport()
+            elif protocol == 'https':
+                transport = HTTPSTransport()
+            elif protocol == 'ssh':
+                global ssh_enabled
+                if ssh_enabled:
+                    (transport, uri) = SSHTransport.getHTTPURI(uri)
+                else:
+                    raise ValueError(
+                        "SSH transport not supported on Python <2.4.")
+        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+                                       verbose, allow_none)
+
+    def __request(self, methodname, params):
+        response = xmlrpclib.ServerProxy.__request(self, methodname, params)
+
+        if isinstance(response, tuple):
+            return tuple([conv_string(x) for x in response])
+        else:
+            return conv_string(response)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py       Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/util/xmlrpclib2.py       Fri Mar 30 17:18:42 2007 -0600
@@ -21,12 +21,10 @@ An enhanced XML-RPC client/server interf
 """
 
 import re
-import string
 import fcntl
 from types import *
     
 
-from httplib import HTTPConnection, HTTP
 from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
 import SocketServer
 import xmlrpclib, socket, os, stat
@@ -35,14 +33,6 @@ import mkdir
 
 from xen.web import connection
 from xen.xend.XendLogging import log
-
-try:
-    import SSHTransport
-    ssh_enabled = True
-except ImportError:
-    # SSHTransport is disabled on Python <2.4, because it uses the subprocess
-    # package.
-    ssh_enabled = False
 
 #
 # Convert all integers to strings as described in the Xen API
@@ -64,13 +54,6 @@ def stringify(value):
         return value
 
 
-# A new ServerProxy that also supports httpu urls.  An http URL comes in the
-# form:
-#
-# httpu:///absolute/path/to/socket.sock
-#
-# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
-
 # We're forced to subclass the RequestHandler class so that we can work around
 # some bugs in Keep-Alive handling and also enabled it by default
 class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
@@ -105,60 +88,6 @@ class XMLRPCRequestHandler(SimpleXMLRPCR
         self.wfile.flush()
         if self.close_connection == 1:
             self.connection.shutdown(1)
-
-class HTTPUnixConnection(HTTPConnection):
-    def connect(self):
-        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        self.sock.connect(self.host)
-
-class HTTPUnix(HTTP):
-    _connection_class = HTTPUnixConnection
-
-class UnixTransport(xmlrpclib.Transport):
-    def request(self, host, handler, request_body, verbose=0):
-        self.__handler = handler
-        return xmlrpclib.Transport.request(self, host, '/RPC2',
-                                           request_body, verbose)
-    def make_connection(self, host):
-        return HTTPUnix(self.__handler)
-
-
-# See _marshalled_dispatch below.
-def conv_string(x):
-    if isinstance(x, StringTypes):
-        s = string.replace(x, "'", r"\047")
-        exec "s = '" + s + "'"
-        return s
-    else:
-        return x
-
-
-class ServerProxy(xmlrpclib.ServerProxy):
-    def __init__(self, uri, transport=None, encoding=None, verbose=0,
-                 allow_none=1):
-        if transport == None:
-            (protocol, rest) = uri.split(':', 1)
-            if protocol == 'httpu':
-                uri = 'http:' + rest
-                transport = UnixTransport()
-            elif protocol == 'ssh':
-                global ssh_enabled
-                if ssh_enabled:
-                    (transport, uri) = SSHTransport.getHTTPURI(uri)
-                else:
-                    raise ValueError(
-                        "SSH transport not supported on Python <2.4.")
-        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
-                                       verbose, allow_none)
-
-    def __request(self, methodname, params):
-        response = xmlrpclib.ServerProxy.__request(self, methodname, params)
-
-        if isinstance(response, tuple):
-            return tuple([conv_string(x) for x in response])
-        else:
-            return conv_string(response)
-
 
 # This is a base XML-RPC server for TCP.  It sets allow_reuse_address to
 # true, and has an improved marshaller that logs and serializes exceptions.
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendAPI.py  Fri Mar 30 17:18:42 2007 -0600
@@ -17,6 +17,8 @@
 
 import inspect
 import os
+import Queue
+import sets
 import string
 import sys
 import traceback
@@ -32,7 +34,9 @@ from xen.xend.XendError import *
 from xen.xend.XendError import *
 from xen.xend.XendClient import ERROR_INVALID_DOMAIN
 from xen.xend.XendLogging import log
+from xen.xend.XendNetwork import XendNetwork
 from xen.xend.XendTask import XendTask
+from xen.xend.XendPIFMetrics import XendPIFMetrics
 from xen.xend.XendVMMetrics import XendVMMetrics
 
 from xen.xend.XendAPIConstants import *
@@ -82,6 +86,91 @@ def xen_api_todo():
 
 def now():
     return xmlrpclib.DateTime(time.strftime("%Y%m%dT%H:%M:%S", time.gmtime()))
+
+
+# ---------------------------------------------------
+# Event dispatch
+# ---------------------------------------------------
+
+EVENT_QUEUE_LENGTH = 50
+event_registrations = {}
+
+def event_register(session, reg_classes):
+    if session not in event_registrations:
+        event_registrations[session] = {
+            'classes' : sets.Set(),
+            'queue'   : Queue.Queue(EVENT_QUEUE_LENGTH),
+            'next-id' : 1
+            }
+    if not reg_classes:
+        reg_classes = classes
+    event_registrations[session]['classes'].union_update(reg_classes)
+
+
+def event_unregister(session, unreg_classes):
+    if session not in event_registrations:
+        return
+
+    if unreg_classes:
+        event_registrations[session]['classes'].intersection_update(
+            unreg_classes)
+        if len(event_registrations[session]['classes']) == 0:
+            del event_registrations[session]
+    else:
+        del event_registrations[session]
+
+
+def event_next(session):
+    if session not in event_registrations:
+        return xen_api_error(['SESSION_NOT_REGISTERED', session])
+    queue = event_registrations[session]['queue']
+    events = [queue.get()]
+    try:
+        while True:
+            events.append(queue.get(False))
+    except Queue.Empty:
+        pass
+
+    return xen_api_success(events)
+
+
+def _ctor_event_dispatch(xenapi, ctor, api_cls, session, args):
+    result = ctor(xenapi, session, *args)
+    if result['Status'] == 'Success':
+        ref = result['Value']
+        _event_dispatch('add', api_cls, ref, '')
+    return result
+
+
+def _dtor_event_dispatch(xenapi, dtor, api_cls, session, ref, args):
+    result = dtor(xenapi, session, ref, *args)
+    if result['Status'] == 'Success':
+        _event_dispatch('del', api_cls, ref, '')
+    return result
+
+
+def _setter_event_dispatch(xenapi, setter, api_cls, attr_name, session, ref,
+                           args):
+    result = setter(xenapi, session, ref, *args)
+    if result['Status'] == 'Success':
+        _event_dispatch('mod', api_cls, ref, attr_name)
+    return result
+
+
+def _event_dispatch(operation, api_cls, ref, attr_name):
+    event = {
+        'timestamp' : now(),
+        'class'     : api_cls,
+        'operation' : operation,
+        'ref'       : ref,
+        'obj_uuid'  : ref,
+        'field'     : attr_name,
+        }
+    for reg in event_registrations.values():
+        if api_cls in reg['classes']:
+            event['id'] = reg['next-id']
+            reg['next-id'] += 1
+            reg['queue'].put(event)
 
 
 # ---------------------------------------------------
@@ -373,6 +462,36 @@ def do_vm_func(fn_name, vm_ref, *args, *
                               exn.actual])
 
 
+classes = {
+    'session'      : None,
+    'event'        : None,
+    'host'         : valid_host,
+    'host_cpu'     : valid_host_cpu,
+    'host_metrics' : valid_host_metrics,
+    'network'      : valid_network,
+    'VM'           : valid_vm,
+    'VM_metrics'   : valid_vm_metrics,
+    'VBD'          : valid_vbd,
+    'VBD_metrics'  : valid_vbd_metrics,
+    'VIF'          : valid_vif,
+    'VIF_metrics'  : valid_vif_metrics,
+    'VDI'          : valid_vdi,
+    'VTPM'         : valid_vtpm,
+    'console'      : valid_console,
+    'SR'           : valid_sr,
+    'PIF'          : valid_pif,
+    'PIF_metrics'  : valid_pif_metrics,
+    'task'         : valid_task,
+    'debug'        : valid_debug,
+}
+
+autoplug_classes = {
+    'network'     : XendNetwork,
+    'VM_metrics'  : XendVMMetrics,
+    'PIF_metrics' : XendPIFMetrics,
+}
+
+
 class XendAPI(object):
     """Implementation of the Xen-API in Xend. Expects to be
     used via XMLRPCServer.
@@ -414,27 +533,7 @@ class XendAPI(object):
         server.
         """
         global_validators = [session_required, catch_typeerror]
-        classes = {
-            'session'      : None,
-            'host'         : valid_host,
-            'host_cpu'     : valid_host_cpu,
-            'host_metrics' : valid_host_metrics,
-            'network'      : valid_network,
-            'VM'           : valid_vm,
-            'VM_metrics'   : valid_vm_metrics,
-            'VBD'          : valid_vbd,
-            'VBD_metrics'  : valid_vbd_metrics,
-            'VIF'          : valid_vif,
-            'VIF_metrics'  : valid_vif_metrics,
-            'VDI'          : valid_vdi,
-            'VTPM'         : valid_vtpm,
-            'console'      : valid_console,
-            'SR'           : valid_sr,
-            'PIF'          : valid_pif,
-            'PIF_metrics'  : valid_pif_metrics,
-            'task'         : valid_task,
-            'debug'        : valid_debug,
-        }
+
 
         # Cheat methods
         # -------------
@@ -457,6 +556,77 @@ class XendAPI(object):
             setattr(cls, get_by_uuid, _get_by_uuid)
             setattr(cls, get_uuid,    _get_uuid)
 
+
+        # Autoplugging classes
+        # --------------------
+        # These have all of their methods grabbed out from the implementation
+        # class, and wrapped up to be compatible with the Xen-API.
+        
+        for api_cls, impl_cls in autoplug_classes.items():
+            def doit(n):
+                getter = getattr(cls, '_%s_get' % api_cls)
+                dot_n = '%s.%s' % (api_cls, n)
+                full_n = '%s_%s' % (api_cls, n)
+                if not hasattr(cls, full_n):
+                    f = getattr(impl_cls, n)
+                    argcounts[dot_n] = f.func_code.co_argcount + 1
+                    setattr(cls, full_n,
+                            lambda s, session, ref, *args: \
+                               xen_api_success( \
+                                   f(getter(s, session, ref), *args)))
+
+            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
+            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
+            methods  = getattr(cls, '%s_methods' % api_cls, [])
+            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
+            
+            for attr_name in ro_attrs + rw_attrs:
+                doit('get_%s' % attr_name)
+            for attr_name in rw_attrs + cls.Base_attr_rw:
+                doit('set_%s' % attr_name)
+            for method_name, return_type in methods + cls.Base_methods:
+                doit('%s' % method_name)
+            for func_name, return_type in funcs + cls.Base_funcs:
+                doit('%s' % func_name)
+
+
+        def wrap_method(name, new_f):
+            try:
+                f = getattr(cls, name)
+                wrapped_f = (lambda *args: new_f(f, *args))
+                wrapped_f.api = f.api
+                wrapped_f.async = f.async
+                setattr(cls, name, wrapped_f)
+            except AttributeError:
+                # Logged below (API call: %s not found)
+                pass
+
+
+        def setter_event_wrapper(api_cls, attr_name):
+            setter_name = '%s_set_%s' % (api_cls, attr_name)
+            wrap_method(
+                setter_name,
+                lambda setter, s, session, ref, *args:
+                _setter_event_dispatch(s, setter, api_cls, attr_name,
+                                       session, ref, args))
+
+
+        def ctor_event_wrapper(api_cls):
+            ctor_name = '%s_create' % api_cls
+            wrap_method(
+                ctor_name,
+                lambda ctor, s, session, *args:
+                _ctor_event_dispatch(s, ctor, api_cls, session, args))
+
+
+        def dtor_event_wrapper(api_cls):
+            dtor_name = '%s_destroy' % api_cls
+            wrap_method(
+                dtor_name,
+                lambda dtor, s, session, ref, *args:
+                _dtor_event_dispatch(s, dtor, api_cls, session, ref, args))
+
+
         # Wrapping validators around XMLRPC calls
         # ---------------------------------------
 
@@ -466,7 +636,8 @@ class XendAPI(object):
                 n_ = n.replace('.', '_')
                 try:
                     f = getattr(cls, n_)
-                    argcounts[n] = f.func_code.co_argcount - 1
+                    if n not in argcounts:
+                        argcounts[n] = f.func_code.co_argcount - 1
                     
                     validators = takes_instance and validator and \
                                  [validator] or []
@@ -498,6 +669,7 @@ class XendAPI(object):
             for attr_name in rw_attrs + cls.Base_attr_rw:
                 doit('%s.set_%s' % (api_cls, attr_name), True,
                      async_support = False)
+                setter_event_wrapper(api_cls, attr_name)
 
             # wrap validators around methods
             for method_name, return_type in methods + cls.Base_methods:
@@ -509,6 +681,10 @@ class XendAPI(object):
                 doit('%s.%s' % (api_cls, func_name), False, async_support = 
True,
                      return_type = return_type)
 
+            ctor_event_wrapper(api_cls)
+            dtor_event_wrapper(api_cls)
+
+
     _decorate = classmethod(_decorate)
 
     def __init__(self, auth):
@@ -516,7 +692,7 @@ class XendAPI(object):
 
     Base_attr_ro = ['uuid']
     Base_attr_rw = []
-    Base_methods = [('destroy', None), ('get_record', 'Struct')]
+    Base_methods = [('get_record', 'Struct')]
     Base_funcs   = [('get_all', 'Set'), ('get_by_uuid', None)]
 
     # Xen API: Class Session
@@ -916,59 +1092,40 @@ class XendAPI(object):
 
     network_attr_ro = ['VIFs', 'PIFs']
     network_attr_rw = ['name_label',
-                       'name_description']
-    
-    network_funcs = [('create', 'network')]
-    
-    def network_create(self, _, name_label, name_description):
-        return xen_api_success(
-            XendNode.instance().network_create(name_label, name_description))
+                       'name_description',
+                       'other_config']
+    network_methods = [('add_to_other_config', None),
+                       ('remove_from_other_config', None),
+                       ('destroy', None)]
+    network_funcs = [('create', None)]
+    
+    def _network_get(self, _, ref):
+        return XendNode.instance().get_network(ref)
+
+    def network_get_all(self, _):
+        return xen_api_success(XendNode.instance().get_network_refs())
+
+    def network_create(self, _, record):
+        return xen_api_success(XendNode.instance().network_create(record))
 
     def network_destroy(self, _, ref):
         return xen_api_success(XendNode.instance().network_destroy(ref))
 
-    def _get_network(self, ref):
-        return XendNode.instance().get_network(ref)
-
-    def network_get_all(self, _):
-        return xen_api_success(XendNode.instance().get_network_refs())
-
-    def network_get_record(self, _, ref):
-        return xen_api_success(
-            XendNode.instance().get_network(ref).get_record())
-
-    def network_get_name_label(self, _, ref):
-        return xen_api_success(self._get_network(ref).name_label)
-
-    def network_get_name_description(self, _, ref):
-        return xen_api_success(self._get_network(ref).name_description)
-
-    def network_get_VIFs(self, _, ref):
-        return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
-
-    def network_get_PIFs(self, session, ref):
-        return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
-
-    def network_set_name_label(self, _, ref, val):
-        return xen_api_success(self._get_network(ref).set_name_label(val))
-
-    def network_set_name_description(self, _, ref, val):
-        return 
xen_api_success(self._get_network(ref).set_name_description(val))
 
     # Xen API: Class PIF
     # ----------------------------------------------------------------
 
-    PIF_attr_ro = ['metrics']
+    PIF_attr_ro = ['network',
+                   'host',
+                   'metrics']
     PIF_attr_rw = ['device',
-                   'network',
-                   'host',
                    'MAC',
                    'MTU',
                    'VLAN']
 
     PIF_attr_inst = PIF_attr_rw
 
-    PIF_methods = [('create_VLAN', 'int')]
+    PIF_methods = [('create_VLAN', 'int'), ('destroy', None)]
 
     def _get_PIF(self, ref):
         return XendNode.instance().pifs[ref]
@@ -1044,25 +1201,13 @@ class XendAPI(object):
                            'io_write_kbs',
                            'last_updated']
     PIF_metrics_attr_rw = []
-    PIF_methods = []
+    PIF_metrics_methods = []
 
     def PIF_metrics_get_all(self, _):
         return xen_api_success(XendNode.instance().pif_metrics.keys())
 
-    def _PIF_metrics_get(self, ref):
+    def _PIF_metrics_get(self, _, ref):
         return XendNode.instance().pif_metrics[ref]
-
-    def PIF_metrics_get_record(self, _, ref):
-        return xen_api_success(self._PIF_metrics_get(ref).get_record())
-
-    def PIF_metrics_get_io_read_kbs(self, _, ref):
-        return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
-
-    def PIF_metrics_get_io_write_kbs(self, _, ref):
-        return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
-
-    def PIF_metrics_get_last_updated(self, _1, _2):
-        return xen_api_success(now())
 
 
     # Xen API: Class VM
@@ -1131,7 +1276,8 @@ class XendAPI(object):
                   ('save', None),
                   ('set_memory_dynamic_max_live', None),
                   ('set_memory_dynamic_min_live', None),
-                  ('send_trigger', None)]
+                  ('send_trigger', None),
+                  ('destroy', None)]
     
     VM_funcs  = [('create', 'VM'),
                  ('restore', None),
@@ -1390,7 +1536,8 @@ class XendAPI(object):
             if key.startswith("cpumap"):
                 vcpu = int(key[6:])
                 try:
-                    xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
+                    cpus = map(int, value.split(","))
+                    xendom.domain_pincpu(xeninfo.getDomid(), vcpu, cpus)
                 except Exception, ex:
                     log.exception(ex)
 
@@ -1633,14 +1780,15 @@ class XendAPI(object):
 
     def VM_send_sysrq(self, _, vm_ref, req):
         xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
+        if xeninfo.state == XEN_API_VM_POWER_STATE_RUNNING \
+               or xeninfo.state == XEN_API_VM_POWER_STATE_PAUSED:
+            xeninfo.send_sysrq(req)
+            return xen_api_success_void()
+        else:
             return xen_api_error(
                 ['VM_BAD_POWER_STATE', vm_ref,
                  XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
                  XendDomain.POWER_STATE_NAMES[xeninfo.state]])
-        xeninfo.send_sysrq(req)
-        return xen_api_success_void()
-
 
     def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
         xendom = XendDomain.instance()
@@ -1675,58 +1823,28 @@ class XendAPI(object):
     VM_metrics_attr_rw = []
     VM_metrics_methods = []
 
-    def _VM_metrics_get(self, ref):
+    def _VM_metrics_get(self, _, ref):
         return XendVMMetrics.get_by_uuid(ref)
 
     def VM_metrics_get_all(self, _):
         return xen_api_success(XendVMMetrics.get_all())
 
-    def VM_metrics_get_record(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_record())
-
-    def VM_metrics_get_memory_actual(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
-
-    def VM_metrics_get_VCPUs_number(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
-
-    def VM_metrics_get_VCPUs_utilisation(self, _, ref):
-        return 
xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
-
-    def VM_metrics_get_VCPUs_CPU(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
-    
-    def VM_metrics_get_VCPUs_flags(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
-
-    def VM_metrics_get_VCPUs_params(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
-
-    def VM_metrics_get_start_time(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_start_time())
-
-    def VM_metrics_get_state(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_state())
-
-    def VM_metrics_get_last_updated(self, _1, _2):
-        return xen_api_success(now())
-
 
     # Xen API: Class VBD
     # ----------------------------------------------------------------
 
-    VBD_attr_ro = ['metrics',
+    VBD_attr_ro = ['VM',
+                   'VDI',
+                   'metrics',
                    'runtime_properties']
-    VBD_attr_rw = ['VM',
-                   'VDI',
-                   'device',
+    VBD_attr_rw = ['device',
                    'bootable',
                    'mode',
                    'type']
 
     VBD_attr_inst = VBD_attr_rw
 
-    VBD_methods = [('media_change', None)]
+    VBD_methods = [('media_change', None), ('destroy', None)]
     VBD_funcs = [('create', 'VBD')]
     
     # object methods
@@ -1868,7 +1986,10 @@ class XendAPI(object):
                            'io_write_kbs',
                            'last_updated']
     VBD_metrics_attr_rw = []
-    VBD_methods = []
+    VBD_metrics_methods = []
+
+    def VBD_metrics_get_all(self, session):
+        return self.VBD_get_all(session)
 
     def VBD_metrics_get_record(self, _, ref):
         vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
@@ -1893,16 +2014,17 @@ class XendAPI(object):
     # Xen API: Class VIF
     # ----------------------------------------------------------------
 
-    VIF_attr_ro = ['metrics',
+    VIF_attr_ro = ['network',
+                   'VM',
+                   'metrics',
                    'runtime_properties']
     VIF_attr_rw = ['device',
-                   'network',
-                   'VM',
                    'MAC',
                    'MTU']
 
     VIF_attr_inst = VIF_attr_rw
 
+    VIF_methods = [('destroy', None)]
     VIF_funcs = [('create', 'VIF')]
 
                  
@@ -1960,10 +2082,10 @@ class XendAPI(object):
         return xen_api_success(vif_ref)
 
     def VIF_get_VM(self, session, vif_ref):
-        xendom = XendDomain.instance()        
-        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)        
+        xendom = XendDomain.instance()
+        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
         return xen_api_success(vm.get_uuid())
-    
+
     def VIF_get_MTU(self, session, vif_ref):
         return self._VIF_get(vif_ref, 'MTU')
     
@@ -2008,7 +2130,10 @@ class XendAPI(object):
                            'io_write_kbs',
                            'last_updated']
     VIF_metrics_attr_rw = []
-    VIF_methods = []
+    VIF_metrics_methods = []
+
+    def VIF_metrics_get_all(self, session):
+        return self.VIF_get_all(session)
 
     def VIF_metrics_get_record(self, _, ref):
         vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
@@ -2044,7 +2169,7 @@ class XendAPI(object):
                    'other_config']
     VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
 
-    VDI_methods = [('snapshot', 'VDI')]
+    VDI_methods = [('snapshot', 'VDI'), ('destroy', None)]
     VDI_funcs = [('create', 'VDI'),
                   ('get_by_name_label', 'Set(VDI)')]
 
@@ -2161,6 +2286,7 @@ class XendAPI(object):
 
     VTPM_attr_inst = VTPM_attr_rw
 
+    VTPM_methods = [('destroy', None)]
     VTPM_funcs = [('create', 'VTPM')]
     
     # object methods
@@ -2319,7 +2445,7 @@ class XendAPI(object):
                     'name_label',
                     'name_description']
     
-    SR_methods = [('clone', 'SR')]
+    SR_methods = [('clone', 'SR'), ('destroy', None)]
     SR_funcs = [('get_by_name_label', 'Set(SR)'),
                 ('get_by_uuid', 'SR')]
 
@@ -2394,6 +2520,26 @@ class XendAPI(object):
             XendNode.instance().save()        
         return xen_api_success_void()
 
+
+    # Xen API: Class event
+    # ----------------------------------------------------------------
+
+    event_attr_ro = []
+    event_attr_rw = []
+    event_funcs = [('register', None),
+                   ('unregister', None),
+                   ('next', None)]
+
+    def event_register(self, session, reg_classes):
+        event_register(session, reg_classes)
+        return xen_api_success_void()
+
+    def event_unregister(self, session, unreg_classes):
+        event_unregister(session, reg_classes)
+        return xen_api_success_void()
+
+    def event_next(self, session):
+        return event_next(session)
 
     # Xen API: Class debug
     # ----------------------------------------------------------------
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendCheckpoint.py   Fri Mar 30 17:18:42 2007 -0600
@@ -192,13 +192,11 @@ def restore(xd, fd, dominfo = None, paus
     image_cfg = dominfo.info.get('image', {})
     is_hvm = dominfo.info.is_hvm()
     if is_hvm:
-        hvm  = dominfo.info['memory_static_min']
         apic = int(dominfo.info['platform'].get('apic', 0))
         pae  = int(dominfo.info['platform'].get('pae',  0))
-        log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d",
-                 dominfo.domid, hvm, apic, pae)
+        log.info("restore hvm domain %d, apic=%d, pae=%d",
+                 dominfo.domid, apic, pae)
     else:
-        hvm  = 0
         apic = 0
         pae  = 0
 
@@ -224,7 +222,7 @@ def restore(xd, fd, dominfo = None, paus
 
         cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
                         fd, dominfo.getDomid(), max_pfn,
-                        store_port, console_port, hvm, pae, apic])
+                        store_port, console_port, int(is_hvm), pae, apic])
         log.debug("[xc_restore]: %s", string.join(cmd))
 
         handler = RestoreInputHandler()
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendClient.py       Fri Mar 30 17:18:42 2007 -0600
@@ -17,7 +17,7 @@
 # Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
 #============================================================================
 
-from xen.util.xmlrpclib2 import ServerProxy
+from xen.util.xmlrpcclient import ServerProxy
 import os
 import sys
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendConfig.py       Fri Mar 30 17:18:42 2007 -0600
@@ -298,7 +298,7 @@ class XendConfig(dict):
             'actions_after_reboot': 'restart',
             'actions_after_crash': 'restart',
             'actions_after_suspend': '',
-            'is_template': False,
+            'is_a_template': False,
             'is_control_domain': False,
             'features': '',
             'PV_bootloader': '',
@@ -452,7 +452,10 @@ class XendConfig(dict):
         for key, typ in XENAPI_CFG_TYPES.items():
             val = sxp.child_value(sxp_cfg, key)
             if val is not None:
-                cfg[key] = typ(val)
+                try:
+                    cfg[key] = typ(val)
+                except (ValueError, TypeError), e:
+                    log.warn('Unable to convert type value for key: %s' % key)
 
         # Convert deprecated options to current equivalents.
         
@@ -727,7 +730,7 @@ class XendConfig(dict):
             
             for key in XENAPI_PLATFORM_CFG:
                 val = sxp.child_value(image_sxp, key, None)
-                if val is not None:
+                if val is not None and val != '':
                     self['platform'][key] = val
             
             notes = sxp.children(image_sxp, 'notes')
@@ -845,6 +848,8 @@ class XendConfig(dict):
                     sxpr.append([name, s])
 
         for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
+            if legacy in ('cpus'): # skip this
+                continue
             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
@@ -858,7 +863,7 @@ class XendConfig(dict):
         sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
 
         for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
-            if legacy in ('domid', 'uuid'): # skip these
+            if legacy in ('domid', 'uuid', 'cpus'): # skip these
                 continue
             if self.has_key(legacy) and self[legacy] not in (None, []):
                 sxpr.append([legacy, self[legacy]])
@@ -1354,7 +1359,7 @@ class XendConfig(dict):
 
         for key in XENAPI_PLATFORM_CFG:
             val = sxp.child_value(image_sxp, key, None)
-            if val is not None:
+            if val is not None and val != '':
                 self['platform'][key] = val
 
         notes = sxp.children(image_sxp, 'notes')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendConstants.py
--- a/tools/python/xen/xend/XendConstants.py    Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendConstants.py    Fri Mar 30 17:18:42 2007 -0600
@@ -36,6 +36,13 @@ DOMAIN_SHUTDOWN_REASONS = {
 }
 REVERSE_DOMAIN_SHUTDOWN_REASONS = \
     dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()])
+
+HVM_PARAM_CALLBACK_IRQ = 0
+HVM_PARAM_STORE_PFN    = 1
+HVM_PARAM_STORE_EVTCHN = 2
+HVM_PARAM_PAE_ENABLED  = 4
+HVM_PARAM_IOREQ_PFN    = 5
+HVM_PARAM_BUFIOREQ_PFN = 6
 
 restart_modes = [
     "restart",
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendDomain.py       Fri Mar 30 17:18:42 2007 -0600
@@ -569,6 +569,26 @@ class XendDomain:
         finally:
             self.domains_lock.release()
 
+    def autostart_domains(self):
+        """ Autostart managed domains that are marked as such. """
+
+        need_starting = []
+        
+        self.domains_lock.acquire()
+        try:
+            for dom_uuid, dom in self.managed_domains.items():
+                if dom and dom.state == DOM_STATE_HALTED:
+                    on_xend_start = dom.info.get('on_xend_start', 'ignore')
+                    auto_power_on = dom.info.get('auto_power_on', False)
+                    should_start = (on_xend_start == 'start') or auto_power_on
+                    if should_start:
+                        need_starting.append(dom_uuid)
+        finally:
+            self.domains_lock.release()
+
+        for dom_uuid in need_starting:
+            self.domain_start(dom_uuid, False)
+
     def cleanup_domains(self):
         """Clean up domains that are marked as autostop.
         Should be called when Xend goes down. This is currently
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Mar 30 17:18:42 2007 -0600
@@ -152,8 +152,9 @@ def recreate(info, priv):
     try:
         vmpath = xstransact.Read(dompath, "vm")
         if not vmpath:
-            log.warn('/local/domain/%d/vm is missing. recreate is '
-                     'confused, trying our best to recover' % domid)
+            if not priv:
+                log.warn('/local/domain/%d/vm is missing. recreate is '
+                         'confused, trying our best to recover' % domid)
             needs_reinitialising = True
             raise XendError('reinit')
         
@@ -447,13 +448,13 @@ class XendDomainInfo:
         self._removeVm('xend/previous_restart_time')
         self.storeDom("control/shutdown", reason)
 
-        ## shutdown hypercall for hvm domain desides xenstore write
+        # HVM domain shuts itself down only if it has PV drivers
         if self.info.is_hvm():
-            for code in DOMAIN_SHUTDOWN_REASONS.keys():
-                if DOMAIN_SHUTDOWN_REASONS[code] == reason:
-                    break
-            xc.domain_shutdown(self.domid, code)
-
+            hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ)
+            if not hvm_pvdrv:
+                code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
+                log.info("HVM save:remote shutdown dom %d!", self.domid)
+                xc.domain_shutdown(self.domid, code)
 
     def pause(self):
         """Pause domain
@@ -2354,7 +2355,8 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
         
-        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING \
+               or self.state == XEN_API_VM_POWER_STATE_PAUSED:
 
             _, config = self.info['devices'][dev_uuid]
             dev_control = self.getDeviceController('vif')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py      Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendLogging.py      Fri Mar 30 17:18:42 2007 -0600
@@ -62,6 +62,7 @@ if 'TRACE' not in logging.__dict__:
     # Work around a bug in Python's inspect module: findsource is supposed to
     # raise IOError if it fails, with other functions in that module coping
     # with that, but some people are seeing IndexError raised from there.
+    # This is Python bug 1628987.  http://python.org/sf/1628987.
     if hasattr(inspect, 'findsource'):
         real_findsource = getattr(inspect, 'findsource')
         def findsource(*args, **kwargs):
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendMonitor.py
--- a/tools/python/xen/xend/XendMonitor.py      Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendMonitor.py      Fri Mar 30 17:18:42 2007 -0600
@@ -24,8 +24,8 @@ import re
 """Monitoring thread to keep track of Xend statistics. """
 
 VBD_SYSFS_PATH = '/sys/devices/xen-backend/'
-VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_req'
-VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_req'
+VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_sect'
+VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_sect'
 VBD_DOMAIN_RE = r'vbd-(?P<domid>\d+)-(?P<devid>\d+)$'
 
 NET_PROCFS_PATH = '/proc/net/dev'
@@ -51,14 +51,9 @@ VIF_DOMAIN_RE = re.compile(r'vif(?P<domi
                            PROC_NET_DEV_RE)
 PIF_RE = re.compile(r'^\s*(?P<iface>peth\d+):\s*' + PROC_NET_DEV_RE)
 
-# The VBD transfer figures are in "requests" where we don't
-# really know how many bytes per requests. For now we make
-# up a number roughly could be.
-VBD_ROUGH_BYTES_PER_REQUEST = 1024 * 8 * 4
-
 # Interval to poll xc, sysfs and proc
 POLL_INTERVAL = 2.0
-
+SECTOR_SIZE = 512
 class XendMonitor(threading.Thread):
     """Monitors VCPU, VBD, VIF and PIF statistics for Xen API.
 
@@ -186,9 +181,8 @@ class XendMonitor(threading.Thread):
                 usage_at = time.time()
                 rd_stat = int(open(rd_stat_path).readline().strip())
                 wr_stat = int(open(wr_stat_path).readline().strip())
-                rd_stat *= VBD_ROUGH_BYTES_PER_REQUEST
-                wr_stat *= VBD_ROUGH_BYTES_PER_REQUEST
-                
+                rd_stat *= SECTOR_SIZE
+                wr_stat *= SECTOR_SIZE
                 if domid not in stats:
                     stats[domid] = {}
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendNetwork.py
--- a/tools/python/xen/xend/XendNetwork.py      Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendNetwork.py      Fri Mar 30 17:18:42 2007 -0600
@@ -28,10 +28,17 @@ IP_ROUTE_RE = r'^default via ([\d\.]+) d
 IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
 
 class XendNetwork:
-    def __init__(self, uuid, name, description):
+    def __init__(self, uuid, record):
         self.uuid = uuid
-        self.name_label = name 
-        self.name_description = description
+        self.name_label = record.get('name_label', '')
+        self.name_description = record.get('name_description', '')
+        self.other_config = record.get('other_config', {})
+
+    def get_name_label(self):
+        return self.name_label
+
+    def get_name_description(self):
+        return self.name_description
 
     def set_name_label(self, new_name):
         self.name_label = new_name
@@ -41,7 +48,7 @@ class XendNetwork:
         self.name_description = new_desc
         XendNode.instance().save_networks()
 
-    def get_VIF_UUIDs(self):
+    def get_VIFs(self):
         result = []
         vms = XendDomain.instance().get_all_vms()
         for vm in vms:
@@ -52,17 +59,37 @@ class XendNetwork:
                     result.append(vif)
         return result
 
-    def get_PIF_UUIDs(self):
+    def get_PIFs(self):
         return [x.uuid for x in XendNode.instance().pifs.values()
                 if x.network == self]
 
-    def get_record(self, transient = True):
+    def get_other_config(self):
+        return self.other_config
+
+    def set_other_config(self, value):
+        self.other_config = value
+        XendNode.instance().save_networks()
+
+    def add_to_other_config(self, key, value):
+        self.other_config[key] = value
+        XendNode.instance().save_networks()
+
+    def remove_from_other_config(self, key):
+        if key in self.other_config:
+            del self.other_config[key]
+        XendNode.instance().save_networks()
+
+    def get_record(self):
+        return self.get_record_internal(True)
+
+    def get_record_internal(self, transient):
         result = {
             'uuid': self.uuid,
             'name_label': self.name_label,
             'name_description': self.name_description,
+            'other_config' : self.other_config,
         }
         if transient:
-            result['VIFs'] = self.get_VIF_UUIDs()
-            result['PIFs'] = self.get_PIF_UUIDs()
+            result['VIFs'] = self.get_VIFs()
+            result['PIFs'] = self.get_PIFs()
         return result
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendNode.py Fri Mar 30 17:18:42 2007 -0600
@@ -141,12 +141,16 @@ class XendNode:
         saved_networks = self.state_store.load_state('network')
         if saved_networks:
             for net_uuid, network in saved_networks.items():
-                self.network_create(network.get('name_label'),
-                                    network.get('name_description', ''),
-                                    False, net_uuid)
+                self.network_create(network, False, net_uuid)
         else:
-            self.network_create('net0', '', False)
-
+            bridges = Brctl.get_state().keys()
+            for bridge in bridges:
+                self.network_create({'name_label' : bridge }, False)
+                
+        # Get a mapping from interface to bridge
+
+        if_to_br = dict(reduce(lambda ls,(b,ifs):[(i,b) for i in ifs] + ls,
+                               Brctl.get_state().items(), []))
         # initialise PIFs
         saved_pifs = self.state_store.load_state('pif')
         if saved_pifs:
@@ -176,8 +180,14 @@ class XendNode:
                                   pif_uuid, pif['network'], exn.pif_uuid)
         else:
             for name, mtu, mac in linux_get_phy_ifaces():
-                network = self.networks.values()[0]
-                self._PIF_create(name, mtu, -1, mac, network, False)
+                bridge_name = if_to_br.get(name, None)
+                if bridge_name is not None:
+                    networks = [network for
+                                network in self.networks.values()
+                                if network.get_name_label() == bridge_name]
+                    if len(networks) > 0:
+                        network = networks[0]
+                        self._PIF_create(name, mtu, -1, mac, network, False)
 
         # initialise storage
         saved_srs = self.state_store.load_state('sr')
@@ -199,12 +209,10 @@ class XendNode:
 
 
 
-    def network_create(self, name_label, name_description, persist = True,
-                       net_uuid = None):
+    def network_create(self, record, persist = True, net_uuid = None):
         if net_uuid is None:
             net_uuid = uuid.createString()
-        self.networks[net_uuid] = XendNetwork(net_uuid, name_label,
-                                              name_description)
+        self.networks[net_uuid] = XendNetwork(net_uuid, record)
         if persist:
             self.save_networks()
         return net_uuid
@@ -280,7 +288,7 @@ class XendNode:
         self.state_store.save_state('pif', pif_records)
 
     def save_networks(self):
-        net_records = dict([(k, v.get_record(transient = False))
+        net_records = dict([(k, v.get_record_internal(False))
                             for k, v in self.networks.items()])
         self.state_store.save_state('network', net_records)
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py      Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendOptions.py      Fri Mar 30 17:18:42 2007 -0600
@@ -165,7 +165,13 @@ class XendOptions:
 
     def get_xend_tcp_xmlrpc_server_address(self):
         return self.get_config_string("xend-tcp-xmlrpc-server-address",
-                                    
self.xend_tcp_xmlrpc_server_address_default)    
+                                      
self.xend_tcp_xmlrpc_server_address_default)
+
+    def get_xend_tcp_xmlrpc_server_ssl_key_file(self):
+        return self.get_config_string("xend-tcp-xmlrpc-server-ssl-key-file")
+
+    def get_xend_tcp_xmlrpc_server_ssl_cert_file(self):
+        return self.get_config_string("xend-tcp-xmlrpc-server-ssl-cert-file")
 
     def get_xend_unix_xmlrpc_server(self):
         return self.get_config_bool("xend-unix-xmlrpc-server",
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendPIFMetrics.py
--- a/tools/python/xen/xend/XendPIFMetrics.py   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendPIFMetrics.py   Fri Mar 30 17:18:42 2007 -0600
@@ -39,11 +39,13 @@ class XendPIFMetrics:
             return pifs_util[pifname][n]
         return 0.0
 
+    def get_last_updated(self):
+        import xen.xend.XendAPI as XendAPI
+        return XendAPI.now()
+
     def get_record(self):
-        import xen.xend.XendAPI as XendAPI
         return {'uuid'         : self.uuid,
-                'PIF'          : self.pif.uuid,
                 'io_read_kbs'  : self.get_io_read_kbs(),
                 'io_write_kbs' : self.get_io_write_kbs(),
-                'last_updated' : XendAPI.now(),
+                'last_updated' : self.get_last_updated(),
                 }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendStateStore.py
--- a/tools/python/xen/xend/XendStateStore.py   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendStateStore.py   Fri Mar 30 17:18:42 2007 -0600
@@ -126,6 +126,13 @@ class XendStateStore:
                     if val_name not in cls_dict:
                         cls_dict[val_name] = {}
                     cls_dict[val_name][val_uuid] = None
+                elif val_type == '':
+                    # dictionary
+                    k = val_elem.getAttribute('key').encode('utf8')
+                    v = val_elem.getAttribute('value').encode('utf8')
+                    if val_name not in cls_dict:
+                        cls_dict[val_name] = {}
+                    cls_dict[val_name][k] = v
                 elif val_type == 'string':
                     cls_dict[val_name] = val_text.encode('utf8')
                 elif val_type == 'float':
@@ -197,7 +204,11 @@ class XendStateStore:
                 if type(val) == dict:
                     for val_uuid in val.keys():
                         val_node = doc.createElement(key)
-                        val_node.setAttribute('uuid', val_uuid)
+                        if key == 'other_config':
+                            val_node.setAttribute('key', str(val_uuid))
+                            val_node.setAttribute('value', str(val[val_uuid]))
+                        else:
+                            val_node.setAttribute('uuid', val_uuid)
                         node.appendChild(val_node)
                 elif type(val) in (list, tuple):
                     for val_uuid in val:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendVMMetrics.py
--- a/tools/python/xen/xend/XendVMMetrics.py    Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendVMMetrics.py    Fri Mar 30 17:18:42 2007 -0600
@@ -92,7 +92,7 @@ class XendVMMetrics:
                 set_flag('blocked')
                 set_flag('online')
                 set_flag('running')
-                vcpus_flags[i] = ",".join(flags)
+                vcpus_flags[i] = flags
             return vcpus_flags
         else:
             return {}
@@ -115,7 +115,7 @@ class XendVMMetrics:
                 addState("dying")
                 addState("crashed")
                 addState("shutdown")
-                return ",".join(states)
+                return states
         except Exception, err:
             # ignore missing domain
             log.trace("domain_getinfo(%d) failed, ignoring: %s", domid, 
str(err))
@@ -140,8 +140,11 @@ class XendVMMetrics:
     def get_start_time(self):
         return self.xend_domain_instance.info.get("start_time", -1)
     
+    def get_last_updated(self):
+        import xen.xend.XendAPI as XendAPI
+        return XendAPI.now()
+    
     def get_record(self):
-        import xen.xend.XendAPI as XendAPI
         return { 'uuid'              : self.uuid,
                  'memory_actual'     : self.get_memory_actual(),
                  'VCPUs_number'      : self.get_VCPUs_number(),
@@ -151,5 +154,5 @@ class XendVMMetrics:
                  'VCPUs_params'      : self.get_VCPUs_params(),
                  'start_time'        : self.get_start_time(),
                  'state'             : self.get_state(),
-                 'last_updated'      : XendAPI.now(),
+                 'last_updated'      : self.get_last_updated(),
                }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
tools/python/xen/xend/server/SSLXMLRPCServer.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/SSLXMLRPCServer.py   Fri Mar 30 17:18:42 
2007 -0600
@@ -0,0 +1,103 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2007 XenSource Inc.
+#============================================================================
+
+
+"""
+HTTPS wrapper for an XML-RPC server interface.  Requires PyOpenSSL (Debian
+package python-pyopenssl).
+"""
+
+import socket
+
+from OpenSSL import SSL
+
+from xen.util.xmlrpclib2 import XMLRPCRequestHandler, TCPXMLRPCServer
+
+
+class SSLXMLRPCRequestHandler(XMLRPCRequestHandler):
+    def setup(self):
+        self.connection = self.request
+        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+#
+# Taken from pyOpenSSL-0.6 examples (public-domain)
+#
+
+class SSLWrapper:
+    """
+    """
+    def __init__(self, conn):
+        """
+        Connection is not yet a new-style class,
+        so I'm making a proxy instead of subclassing.
+        """
+        self.__dict__["conn"] = conn
+    def __getattr__(self, name):
+        return getattr(self.__dict__["conn"], name)
+    def __setattr__(self, name, value):
+        setattr(self.__dict__["conn"], name, value)
+
+    def close(self):
+        self.shutdown()
+        return self.__dict__["conn"].close()
+
+    def shutdown(self, how=1):
+        """
+        SimpleXMLRpcServer.doPOST calls shutdown(1),
+        and Connection.shutdown() doesn't take
+        an argument. So we just discard the argument.
+        """
+        # Block until the shutdown is complete
+        self.__dict__["conn"].shutdown()
+        self.__dict__["conn"].shutdown()
+
+    def accept(self):
+        """
+        This is the other part of the shutdown() workaround.
+        Since servers create new sockets, we have to infect
+        them with our magic. :)
+        """
+        c, a = self.__dict__["conn"].accept()
+        return (SSLWrapper(c), a)
+
+#
+# End of pyOpenSSL-0.6 example code.
+#
+
+class SSLXMLRPCServer(TCPXMLRPCServer):
+    def __init__(self, addr, allowed, xenapi, logRequests = 1,
+                 ssl_key_file = None, ssl_cert_file = None):
+
+        TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
+                                 SSLXMLRPCRequestHandler, logRequests)
+
+        if not ssl_key_file or not ssl_cert_file:
+            raise ValueError("SSLXMLRPCServer requires ssl_key_file "
+                             "and ssl_cert_file to be set.")
+
+        # make a SSL socket
+        ctx = SSL.Context(SSL.SSLv23_METHOD)
+        ctx.set_options(SSL.OP_NO_SSLv2)
+        ctx.use_privatekey_file (ssl_key_file)
+        ctx.use_certificate_file(ssl_cert_file)
+        self.socket = SSLWrapper(SSL.Connection(ctx,
+                                 socket.socket(self.address_family,
+                                               self.socket_type)))
+        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        self.server_bind()
+        self.server_activate()
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/server/SrvDaemon.py Fri Mar 30 17:18:42 2007 -0600
@@ -38,7 +38,8 @@ class Daemon:
         self.traceon = False
         self.tracefile = None
         self.traceindent = 0
-        self.child = 0 
+        self.child = 0
+        self.traceLock = threading.Lock()
 
 
     def cleanup_xend(self, kill):
@@ -253,6 +254,7 @@ class Daemon:
                 pass
 
     def print_trace(self, string):
+        self.tracefile.write("%s: "% threading.currentThread().getName())
         for i in range(self.traceindent):
             ch = " "
             if (i % 5):
@@ -263,50 +265,54 @@ class Daemon:
         self.tracefile.write(string)
             
     def trace(self, frame, event, arg):
-        if not self.traceon:
-            print >>self.tracefile
-            print >>self.tracefile, '-' * 20, 'TRACE OFF', '-' * 20
-            self.tracefile.close()
-            self.tracefile = None
-            return None
-        if event == 'call':
-            code = frame.f_code
-            filename = code.co_filename
-            m = re.search('.*xend/(.*)', filename)
-            if not m:
+        self.traceLock.acquire()
+        try:
+            if not self.traceon:
+                print >>self.tracefile
+                print >>self.tracefile, '-' * 20, 'TRACE OFF', '-' * 20
+                self.tracefile.close()
+                self.tracefile = None
                 return None
-            modulename = m.group(1)
-            if modulename.endswith('.pyc'):
-                modulename = modulename[:-1]
-            if modulename == 'sxp.py' or \
-               modulename == 'XendLogging.py' or \
-               modulename == 'XendMonitor.py' or \
-               modulename == 'server/SrvServer.py':
-                return None
-            self.traceindent += 1
-            self.print_trace("> %s:%s\n"
-                             % (modulename, code.co_name))
-        elif event == 'line':
-            filename = frame.f_code.co_filename
-            lineno = frame.f_lineno
-            self.print_trace("%4d %s" %
-                             (lineno, linecache.getline(filename, lineno)))
-        elif event == 'return':
-            code = frame.f_code
-            filename = code.co_filename
-            m = re.search('.*xend/(.*)', filename)
-            if not m:
-                return None
-            modulename = m.group(1)
-            self.print_trace("< %s:%s\n"
-                             % (modulename, code.co_name))
-            self.traceindent -= 1
-        elif event == 'exception':
-            self.print_trace("! Exception:\n")
-            (ex, val, tb) = arg
-            traceback.print_exception(ex, val, tb, 10, self.tracefile)
-            #del tb
-        return self.trace
+            if event == 'call':
+                code = frame.f_code
+                filename = code.co_filename
+                m = re.search('.*xend/(.*)', filename)
+                if not m:
+                    return None
+                modulename = m.group(1)
+                if modulename.endswith('.pyc'):
+                    modulename = modulename[:-1]
+                if modulename == 'sxp.py' or \
+                   modulename == 'XendLogging.py' or \
+                   modulename == 'XendMonitor.py' or \
+                   modulename == 'server/SrvServer.py':
+                    return None
+                self.traceindent += 1
+                self.print_trace("> %s:%s\n"
+                                 % (modulename, code.co_name))
+            elif event == 'line':
+                filename = frame.f_code.co_filename
+                lineno = frame.f_lineno
+                self.print_trace("%4d %s" %
+                                 (lineno, linecache.getline(filename, lineno)))
+            elif event == 'return':
+                code = frame.f_code
+                filename = code.co_filename
+                m = re.search('.*xend/(.*)', filename)
+                if not m:
+                    return None
+                modulename = m.group(1)
+                self.print_trace("< %s:%s\n"
+                                 % (modulename, code.co_name))
+                self.traceindent -= 1
+            elif event == 'exception':
+                self.print_trace("! Exception:\n")
+                (ex, val, tb) = arg
+                traceback.print_exception(ex, val, tb, 10, self.tracefile)
+                #del tb
+            return self.trace
+        finally:
+            self.traceLock.release()
 
     def set_user(self):
         # Set the UID.
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/server/SrvServer.py Fri Mar 30 17:18:42 2007 -0600
@@ -52,6 +52,7 @@ from xen.xend import Vifctl
 from xen.xend import Vifctl
 from xen.xend.XendLogging import log
 from xen.xend.XendClient import XEN_API_SOCKET
+from xen.xend.XendDomain import instance as xenddomain
 from xen.web.SrvDir import SrvDir
 
 from SrvRoot import SrvRoot
@@ -72,7 +73,7 @@ class XendServers:
     def add(self, server):
         self.servers.append(server)
 
-    def cleanup(self, signum = 0, frame = None):
+    def cleanup(self, signum = 0, frame = None, reloading = False):
         log.debug("SrvServer.cleanup()")
         self.cleaningUp = True
         for server in self.servers:
@@ -80,12 +81,18 @@ class XendServers:
                 server.shutdown()
             except:
                 pass
+
+        # clean up domains for those that have on_xend_stop
+        if not reloading:
+            xenddomain().cleanup_domains()
+        
         self.running = False
+        
 
     def reloadConfig(self, signum = 0, frame = None):
         log.debug("SrvServer.reloadConfig()")
         self.reloadingConfig = True
-        self.cleanup(signum, frame)
+        self.cleanup(signum, frame, reloading = True)
 
     def start(self, status):
         # Running the network script will spawn another process, which takes
@@ -144,6 +151,12 @@ class XendServers:
                 status.close()
                 status = None
 
+            # Reaching this point means we can auto start domains
+            try:
+                xenddomain().autostart_domains()
+            except Exception, e:
+                log.exception("Failed while autostarting domains")
+
             # loop to keep main thread alive until it receives a SIGTERM
             self.running = True
             while self.running:
@@ -172,33 +185,49 @@ def _loadConfig(servers, root, reload):
     api_cfg = xoptions.get_xen_api_server()
     if api_cfg:
         try:
-            addrs = [(str(x[0]).split(':'),
-                      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]
-            for addrport, auth, allowed in addrs:
-                if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
-                    log.error('Xen-API server configuration %s is invalid, ' +
-                              'as %s is not a valid authentication type.',
-                              api_cfg, auth)
-                    break
-
-                if len(addrport) == 1:
-                    if addrport[0] == 'unix':
-                        servers.add(XMLRPCServer(auth, True,
-                                                 path = XEN_API_SOCKET,
-                                                 hosts_allowed = allowed))
+            for server_cfg in api_cfg:
+                # Parse the xen-api-server config
+                
+                ssl_key_file = None
+                ssl_cert_file = None
+                auth_method = XendAPI.AUTH_NONE
+                hosts_allowed = None
+                
+                host_addr = server_cfg[0].split(':', 1)
+                if len(host_addr) == 1:
+                    if host_addr[0].lower() == 'unix':
+                        use_tcp = False
+                        host = 'localhost'
+                        port = 0
                     else:
-                        servers.add(
-                            XMLRPCServer(auth, True, True, '',
-                                         int(addrport[0]),
-                                         hosts_allowed = allowed))
+                        use_tcp = True
+                        host = ''
+                        port = int(host_addr[0])
                 else:
-                    addr, port = addrport
-                    servers.add(XMLRPCServer(auth, True, True, addr,
-                                             int(port),
-                                             hosts_allowed = allowed))
+                    use_tcp = True
+                    host = str(host_addr[0])
+                    port = int(host_addr[1])
+
+                if len(server_cfg) > 1:
+                    if server_cfg[1] in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
+                        auth_method = server_cfg[1]
+
+                if len(server_cfg) > 2:
+                    hosts_allowed = server_cfg[2] or None
+
+                if len(server_cfg) > 4:
+                    # SSL key and cert file
+                    ssl_key_file = server_cfg[3]
+                    ssl_cert_file = server_cfg[4]
+
+
+                servers.add(XMLRPCServer(auth_method, True, use_tcp = use_tcp,
+                                         ssl_key_file = ssl_key_file,
+                                         ssl_cert_file = ssl_cert_file,
+                                         host = host, port = port,
+                                         path = XEN_API_SOCKET,
+                                         hosts_allowed = hosts_allowed))
+
         except (ValueError, TypeError), exn:
             log.exception('Xen API Server init failed')
             log.error('Xen-API server configuration %s is invalid.', api_cfg)
@@ -206,8 +235,17 @@ def _loadConfig(servers, root, reload):
     if xoptions.get_xend_tcp_xmlrpc_server():
         addr = xoptions.get_xend_tcp_xmlrpc_server_address()
         port = xoptions.get_xend_tcp_xmlrpc_server_port()
-        servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
-                                 host = addr, port = port))
+        ssl_key_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_key_file()
+        ssl_cert_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_cert_file()
+
+        if ssl_key_file and ssl_cert_file:
+            servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
+                                     ssl_key_file = ssl_key_file,
+                                     ssl_cert_file = ssl_cert_file,
+                                     host = addr, port = port))
+        else:
+            servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
+                                     host = addr, port = port))
 
     if xoptions.get_xend_unix_xmlrpc_server():
         servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
tools/python/xen/xend/server/XMLRPCServer.py
--- a/tools/python/xen/xend/server/XMLRPCServer.py      Fri Mar 30 10:27:15 
2007 -0600
+++ b/tools/python/xen/xend/server/XMLRPCServer.py      Fri Mar 30 17:18:42 
2007 -0600
@@ -21,6 +21,11 @@ import types
 import types
 import xmlrpclib
 from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
+try:
+    from SSLXMLRPCServer import SSLXMLRPCServer
+    ssl_enabled = True
+except ImportError:
+    ssl_enabled = False
 
 from xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNode
 from xen.xend import XendLogging, XendDmesg
@@ -87,14 +92,20 @@ exclude = ['domain_create', 'domain_rest
 exclude = ['domain_create', 'domain_restore']
 
 class XMLRPCServer:
-    def __init__(self, auth, use_xenapi, use_tcp=False, host = "localhost",
-                 port = 8006, path = XML_RPC_SOCKET, hosts_allowed = None):
+    def __init__(self, auth, use_xenapi, use_tcp = False,
+                 ssl_key_file = None, ssl_cert_file = None,
+                 host = "localhost", port = 8006, path = XML_RPC_SOCKET,
+                 hosts_allowed = None):
+        
         self.use_tcp = use_tcp
         self.port = port
         self.host = host
         self.path = path
         self.hosts_allowed = hosts_allowed
         
+        self.ssl_key_file = ssl_key_file
+        self.ssl_cert_file = ssl_cert_file
+        
         self.ready = False        
         self.running = True
         self.auth = auth
@@ -107,14 +118,32 @@ class XMLRPCServer:
 
         try:
             if self.use_tcp:
-                log.info("Opening TCP XML-RPC server on %s%d%s",
+                using_ssl = self.ssl_key_file and self.ssl_cert_file
+
+                log.info("Opening %s XML-RPC server on %s%d%s",
+                         using_ssl and 'HTTPS' or 'TCP',
                          self.host and '%s:' % self.host or
                          'all interfaces, port ',
                          self.port, authmsg)
-                self.server = TCPXMLRPCServer((self.host, self.port),
-                                              self.hosts_allowed,
-                                              self.xenapi is not None,
-                                              logRequests = False)
+
+                if using_ssl:
+                    if not ssl_enabled:
+                        raise ValueError("pyOpenSSL not installed. "
+                                         "Unable to start HTTPS XML-RPC 
server")
+                    self.server = SSLXMLRPCServer(
+                        (self.host, self.port),
+                        self.hosts_allowed,
+                        self.xenapi is not None,
+                        logRequests = False,
+                        ssl_key_file = self.ssl_key_file,
+                        ssl_cert_file = self.ssl_cert_file)
+                else:
+                    self.server = TCPXMLRPCServer(
+                        (self.host, self.port),
+                        self.hosts_allowed,
+                        self.xenapi is not None,
+                        logRequests = False)
+
             else:
                 log.info("Opening Unix domain socket XML-RPC server on %s%s",
                          self.path, authmsg)
@@ -126,7 +155,12 @@ class XMLRPCServer:
             ready = True
             running = False
             return
-
+        except Exception, e:
+            log.exception('Cannot start server: %s!', e)
+            ready = True
+            running = False
+            return
+        
         # Register Xen API Functions
         # -------------------------------------------------------------------
         # exportable functions are ones that do not begin with '_'
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/XenAPI.py
--- a/tools/python/xen/xm/XenAPI.py     Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/XenAPI.py     Fri Mar 30 17:18:42 2007 -0600
@@ -12,7 +12,7 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
-# Copyright (C) 2006 XenSource Inc.
+# Copyright (C) 2006-2007 XenSource Inc.
 #============================================================================
 #
 # Parts of this file are based upon xmlrpclib.py, the XML-RPC client
@@ -47,7 +47,7 @@ import gettext
 import gettext
 import xmlrpclib
 
-import xen.util.xmlrpclib2
+import xen.util.xmlrpcclient as xmlrpcclient
 
 
 translation = gettext.translation('xen-xm', fallback = True)
@@ -85,7 +85,7 @@ _RECONNECT_AND_RETRY = (lambda _ : ())
 _RECONNECT_AND_RETRY = (lambda _ : ())
 
 
-class Session(xen.util.xmlrpclib2.ServerProxy):
+class Session(xmlrpcclient.ServerProxy):
     """A server proxy and session manager for communicating with Xend using
     the Xen-API.
 
@@ -104,13 +104,15 @@ class Session(xen.util.xmlrpclib2.Server
 
     def __init__(self, uri, transport=None, encoding=None, verbose=0,
                  allow_none=1):
-        xen.util.xmlrpclib2.ServerProxy.__init__(self, uri, transport,
-                                                 encoding, verbose,
-                                                 allow_none)
+        xmlrpcclient.ServerProxy.__init__(self, uri, transport, encoding,
+                                          verbose, allow_none)
         self._session = None
         self.last_login_method = None
         self.last_login_params = None
 
+
+    def getSession(self):
+        return self._session
 
     def xenapi_request(self, methodname, params):
         if methodname.startswith('login'):
@@ -150,7 +152,7 @@ class Session(xen.util.xmlrpclib2.Server
         elif name.startswith('login'):
             return lambda *params: self._login(name, params)
         else:
-            return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
+            return xmlrpcclient.ServerProxy.__getattr__(self, name)
 
 
 def _parse_result(result):
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/create.dtd
--- a/tools/python/xen/xm/create.dtd    Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/create.dtd    Fri Mar 30 17:18:42 2007 -0600
@@ -37,6 +37,8 @@
                  memory,
                  vbd*,
                  vif*,
+                 console*,
+                 platform*,
                  vcpu_param*,
                  other_config*)> 
 <!ATTLIST vm     is_a_template          CDATA #REQUIRED
@@ -46,11 +48,6 @@
                  actions_after_shutdown %NORMAL_EXIT; #REQUIRED 
                  actions_after_reboot   %NORMAL_EXIT; #REQUIRED
                  actions_after_crash    %CRASH_BEHAVIOUR; #REQUIRED
-                 platform_std_VGA       CDATA #REQUIRED
-                 platform_serial        CDATA #REQUIRED
-                 platform_localtime     CDATA #REQUIRED 
-                 platform_clock_offet   CDATA #REQUIRED
-                 platform_enable_audio  CDATA #REQUIRED
                  PCI_bus                CDATA #REQUIRED> 
 
 <!ELEMENT memory EMPTY> 
@@ -74,8 +71,10 @@
                  mtu             CDATA       #REQUIRED
                  device          CDATA       #REQUIRED
                  qos_algorithm_type CDATA    #REQUIRED
-                 bridge          CDATA       #IMPLIED
                  network         CDATA       #IMPLIED> 
+
+<!ELEMENT console (other_config*)>
+<!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
 
 <!ELEMENT pv     EMPTY>
 <!ATTLIST pv     kernel          CDATA #REQUIRED
@@ -105,13 +104,17 @@
 <!ELEMENT label  (#PCDATA)> 
 <!ELEMENT description (#PCDATA)>
 
+<!ELEMENT platform   EMPTY>
+<!ATTLIST platform   key   CDATA #REQUIRED
+                     value CDATA #REQUIRED>
+
 <!ELEMENT vcpu_param EMPTY>
 <!ATTLIST vcpu_param key   CDATA #REQUIRED
                      value CDATA #REQUIRED>
 
 <!ELEMENT other_config EMPTY>
 <!ATTLIST other_config key   CDATA #REQUIRED
-                      value CDATA #REQUIRED>
+                       value CDATA #REQUIRED>
 
 <!ELEMENT qos_algorithm_param EMPTY>
 <!ATTLIST qos_algorithm_param key   CDATA #REQUIRED
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/create.py     Fri Mar 30 17:18:42 2007 -0600
@@ -103,6 +103,11 @@ gopts.opt('xmldryrun', short='x',
           fn=set_true, default=0,
           use="XML dry run - prints the resulting configuration in XML but "
           "does not create the domain.")
+
+gopts.opt('skipdtd', short='s',
+          fn=set_true, default=0,
+          use="Skip DTD checking - skips checks on XML before creating. "
+          " Experimental.  Can decrease create time." )
 
 gopts.opt('paused', short='p',
           fn=set_true, default=0,
@@ -1098,6 +1103,8 @@ def parseCommandLine(argv):
     if not gopts.vals.xauthority:
         gopts.vals.xauthority = get_xauthority()
 
+    gopts.is_xml = False
+
     # Process remaining args as config variables.
     for arg in args:
         if '=' in arg:
@@ -1106,11 +1113,16 @@ def parseCommandLine(argv):
     if gopts.vals.config:
         config = gopts.vals.config
     else:
-        gopts.load_defconfig()
-        preprocess(gopts.vals)
-        if not gopts.getopt('name') and gopts.getopt('defconfig'):
-            gopts.setopt('name', os.path.basename(gopts.getopt('defconfig')))
-        config = make_config(gopts.vals)
+        try:
+            gopts.load_defconfig()
+            preprocess(gopts.vals)
+            if not gopts.getopt('name') and gopts.getopt('defconfig'):
+                gopts.setopt('name', 
os.path.basename(gopts.getopt('defconfig')))
+            config = make_config(gopts.vals)
+        except XMLFileError, ex:
+            XMLFile = ex.getFile()
+            gopts.is_xml = True
+            config = ex.getFile()
 
     return (gopts, config)
 
@@ -1233,6 +1245,8 @@ def help():
     return str(gopts)
 
 def main(argv):
+    is_xml = False
+    
     try:
         (opts, config) = parseCommandLine(argv)
     except StandardError, ex:
@@ -1241,23 +1255,24 @@ def main(argv):
     if not opts:
         return
 
-    if type(config) == str:
-        try:
-            config = sxp.parse(file(config))[0]
-        except IOError, exn:
-            raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
-
-    if serverType == SERVER_XEN_API:
-        from xen.xm.xenapi_create import sxp2xml
-        sxp2xml_inst = sxp2xml()
-        doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
-
-    if opts.vals.dryrun:
-        SXPPrettyPrint.prettyprint(config)
-
-    if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
-        from xml.dom.ext import PrettyPrint as XMLPrettyPrint
-        XMLPrettyPrint(doc)
+    if not opts.is_xml:
+        if type(config) == str:
+            try:
+                config = sxp.parse(file(config))[0]
+            except IOError, exn:
+                raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
+        
+        if serverType == SERVER_XEN_API:
+            from xen.xm.xenapi_create import sxp2xml
+            sxp2xml_inst = sxp2xml()
+            doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
+
+        if opts.vals.dryrun and not opts.is_xml:
+            SXPPrettyPrint.prettyprint(config)
+
+        if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
+            from xml.dom.ext import PrettyPrint as XMLPrettyPrint
+            XMLPrettyPrint(doc)
 
     if opts.vals.dryrun or opts.vals.xmldryrun:
         return                                               
@@ -1268,10 +1283,15 @@ def main(argv):
     if serverType == SERVER_XEN_API:        
         from xen.xm.xenapi_create import xenapi_create
         xenapi_create_inst = xenapi_create()
-        vm_refs = xenapi_create_inst.create(document = doc)
+        if opts.is_xml:
+            vm_refs = xenapi_create_inst.create(filename = config,
+                                                skipdtd = opts.vals.skipdtd)
+        else:
+            vm_refs = xenapi_create_inst.create(document = doc,
+                                                skipdtd = opts.vals.skipdtd)
 
         map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
-    else:
+    elif not opts.is_xml:
         if not create_security_check(config):
             raise security.ACMError(
                 'Security Configuration prevents domain from starting')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/main.py       Fri Mar 30 17:18:42 2007 -0600
@@ -49,7 +49,7 @@ from xen.xend.XendConstants import *
 
 from xen.xm.opts import OptionError, Opts, wrap, set_true
 from xen.xm import console
-from xen.util.xmlrpclib2 import ServerProxy
+from xen.util.xmlrpcclient import ServerProxy
 
 import XenAPI
 
@@ -345,7 +345,8 @@ acm_commands = [
     ]
 
 all_commands = (domain_commands + host_commands + scheduler_commands +
-                device_commands + vnet_commands + acm_commands + ['shell'])
+                device_commands + vnet_commands + acm_commands +
+                ['shell', 'event-monitor'])
 
 
 ##
@@ -559,11 +560,21 @@ def get_single_vm(dom):
 def get_single_vm(dom):
     if serverType == SERVER_XEN_API:
         uuids = server.xenapi.VM.get_by_name_label(dom)
-        n = len(uuids)
-        if n > 0:
+        if len(uuids) > 0:
             return uuids[0]
-        else:
-            raise OptionError("Domain '%s' not found." % dom)
+
+        try:
+            domid = int(dom)
+            uuids = [server.xenapi.VM.get_domid(vm_ref)
+                     for vm_ref in server.xenapi.VM.get_all()
+                     if int(server.xenapi.VM.get_domid(vm_ref)) == domid]
+        except:
+            pass
+            
+        if len(uuids) > 0:
+            return uuids[0]
+
+        raise OptionError("Domain '%s' not found." % dom)
     else:
         dominfo = server.xend.domain(dom, False)
         return dominfo['uuid']
@@ -633,6 +644,17 @@ def xm_shell(args):
     Shell().cmdloop('The Xen Master. Type "help" for a list of functions.')
 
 
+def xm_event_monitor(args):
+    if serverType == SERVER_XEN_API:
+        while True:
+            server.xenapi.event.register(args)
+            events = server.xenapi.event.next()
+            for e in events:
+                print e
+    else:
+        err("Event monitoring not supported unless using Xen-API.")
+
+
 #########################################################################
 #
 #  Main xm functions
@@ -722,7 +744,7 @@ def getDomains(domain_names, state, full
             states = ('running', 'blocked', 'paused', 'shutdown',
                       'crashed', 'dying')
             def state_on_off(state):
-                if dom_metrics['state'].find(state) > -1:
+                if state in dom_metrics['state']:
                     return state[0]
                 else:
                     return "-"
@@ -850,7 +872,8 @@ def parse_doms_info(info):
 
 def check_sched_type(sched):
     if serverType == SERVER_XEN_API:
-        current = 
server.xenapi.host.get_sched_policy(server.xenapi.session.get_this_host())
+        current = server.xenapi.host.get_sched_policy(
+            server.xenapi.session.get_this_host(server.getSession()))
     else:
         current = 'unknown'
         for x in server.xend.node.info()[1:]:
@@ -952,12 +975,10 @@ def xm_vcpu_list(args):
                     ['name',       vm_records[vm_ref]['name_label']],
                     ['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
 
-            
-
             for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
                 def chk_flag(flag):
-                    return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
-                           .find(flag) > -1 and 1 or 0
+                    return flag in vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
+                           and 1 or 0
                 
                 vcpu_info = ['vcpu',
                              ['number',
@@ -1044,7 +1065,7 @@ def xm_vcpu_list(args):
 
             if serverType == SERVER_XEN_API:
                 nr_cpus = len(server.xenapi.host.get_host_CPUs(
-                    server.xenapi.session.get_this_host()))
+                    server.xenapi.session.get_this_host(server.getSession())))
             else:
                 for x in server.xend.node.info()[1:]:
                     if len(x) > 1 and x[0] == 'nr_cpus':
@@ -1260,8 +1281,9 @@ def xm_vcpu_pin(args):
         cpumap = cpu_make_map(args[2])
 
     if serverType == SERVER_XEN_API:
+        cpumap = map(str, cpumap)        
         server.xenapi.VM.add_to_VCPUs_params_live(
-            get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
+            get_single_vm(dom), "cpumap%i" % int(vcpu), ",".join(cpumap))
     else:
         server.xend.domain.pincpu(dom, vcpu, cpumap)
 
@@ -1509,7 +1531,7 @@ def xm_info(args):
         # Need to fake out old style xm info as people rely on parsing it
         
         host_record = server.xenapi.host.get_record(
-            server.xenapi.session.get_this_host())        
+            server.xenapi.session.get_this_host(server.getSession()))
 
         host_cpu_records = map(server.xenapi.host_cpu.get_record, 
host_record["host_CPUs"])
 
@@ -1686,7 +1708,7 @@ def xm_debug_keys(args):
     
     if serverType == SERVER_XEN_API:
         server.xenapi.host.send_debug_keys(
-            server.xenapi.session.get_this_host(),
+            server.xenapi.session.get_this_host(server.getSession()),
             keys)
     else:
         server.xend.node.send_debug_keys(keys)
@@ -1715,7 +1737,7 @@ def xm_dmesg(args):
         usage('dmesg')
 
     if serverType == SERVER_XEN_API:
-        host = server.xenapi.session.get_this_host()
+        host = server.xenapi.session.get_this_host(server.getSession())
         if use_clear:
             print server.xenapi.host.dmesg_clear(host),
         else:
@@ -1731,7 +1753,7 @@ def xm_log(args):
 
     if serverType == SERVER_XEN_API:
         print server.xenapi.host.get_log(
-            server.xenapi.session.get_this_host())
+            server.xenapi.session.get_this_host(server.getSession()))
     else:
         print server.xend.node.log()
 
@@ -2169,6 +2191,7 @@ def xm_vnet_delete(args):
 
 commands = {
     "shell": xm_shell,
+    "event-monitor": xm_event_monitor,
     # console commands
     "console": xm_console,
     # xenstat commands
@@ -2371,11 +2394,10 @@ def _run_cmd(cmd, cmd_name, args):
            if isinstance(e, security.ACMError):
                err(str(e))
                return False, 1
-        else:
-            print "Unexpected error:", sys.exc_info()[0]
-            print
-            print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
-            raise
+        print "Unexpected error:", sys.exc_info()[0]
+        print
+        print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
+        raise
 
     return False, 1
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/messages/en/xen-xm.po
--- a/tools/python/xen/xm/messages/en/xen-xm.po Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/messages/en/xen-xm.po Fri Mar 30 17:18:42 2007 -0600
@@ -19,7 +19,7 @@ msgid ""
 msgid ""
 msgstr ""
 "Project-Id-Version: Xen-xm 3.0\n"
-"PO-Revision-Date: 2007-03-10 23:17+0000\n"
+"PO-Revision-Date: 2007-03-29 16:13+0100\n"
 "Last-Translator: Ewan Mellor <ewan@xxxxxxxxxxxxx>\n"
 "Language-Team: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>\n"
 "MIME-Version: 1.0\n"
@@ -64,3 +64,6 @@ msgstr "The VM must be %(2)s to perform 
 
 msgid "VM_HVM_REQUIRED"
 msgstr "HVM guest support is unavailable: is VT/AMD-V supported by your CPU 
and enabled in your BIOS?"
+
+msgid "SESSION_NOT_REGISTERED"
+msgstr "This session is not registered to receive events.  You must call 
event.register before event.next.  (Session handle is %(1)s.)"
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/opts.py
--- a/tools/python/xen/xm/opts.py       Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/opts.py       Fri Mar 30 17:18:42 2007 -0600
@@ -24,6 +24,8 @@ import sys
 import sys
 import types
 
+
+
 def _line_wrap(text, width = 70):
     lines = []
     current_line = ''
@@ -59,6 +61,15 @@ class OptionError(Exception):
         self.usage = usage
     def __str__(self):
         return self.message
+
+class XMLFileError(Exception):
+    """Thrown is input is an XML File"""
+    def __init__(self, XMLFile):
+        self.XMLFile = XMLFile
+    def __str__(self):
+        return "XMLFileError: %s" % self.XMLFile
+    def getFile(self):
+        return self.XMLFile
 
 class Opt:
     """An individual option.
@@ -492,6 +503,14 @@ class Opts:
                 p = os.path.join(os.path.curdir, p)
             if os.path.exists(p):
                 self.info('Using config file "%s".' % p)
+
+                f = open(p)
+                is_xml = (f.read(1) == '<')
+                f.close()
+
+                if is_xml:
+                    raise XMLFileError(p)
+
                 self.load(p, help)
                 break
         else:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/xenapi_create.py      Fri Mar 30 17:18:42 2007 -0600
@@ -25,7 +25,7 @@ from xen.xend import sxp
 from xen.xend import sxp
 from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
      XEN_API_ON_CRASH_BEHAVIOUR
-
+from xen.xm.opts import OptionError
 
 import sys
 import os
@@ -75,15 +75,20 @@ class xenapi_create:
 
         self.dtd = "/usr/lib/python/xen/xm/create.dtd"
 
-    def create(self, filename=None, document=None):
+    def create(self, filename=None, document=None, skipdtd=False):
         """
         Create a domain from an XML file or DOM tree
         """
+        if skipdtd:
+            print "Skipping DTD checks.  Dangerous!"
+        
         if filename is not None:
-            self.check_dtd(file)
-            document = parse(file)
+            if not skipdtd:
+                self.check_dtd(filename)
+            document = parse(filename)
         elif document is not None:
-            self.check_dom_against_dtd(document)
+            if not skipdtd:
+                self.check_dom_against_dtd(document)
 
         self.check_doc(document)
 
@@ -179,15 +184,7 @@ class xenapi_create:
         map(self.check_vif, vifs)
 
     def check_vif(self, vif):
-        """
-        Check that the vif has
-        either a bridge or network
-        name but not both
-        """
-        if "bridge" in vif.attributes.keys() \
-               and "network" in vif.attributes.keys():
-            raise "You cannot specify both a bridge and\
-                   a network name."
+        pass
 
     # Cleanup methods here
     def cleanup_vdis(self, vdi_refs_dict):
@@ -265,18 +262,8 @@ class xenapi_create:
                 vm.attributes["actions_after_reboot"].value,
             "actions_after_crash":
                 vm.attributes["actions_after_crash"].value,
-            "platform_std_VGA":
-                vm.attributes["platform_std_VGA"].value,
-            "platform_serial":
-                vm.attributes["platform_serial"].value,
-            "platform_localtime":
-                vm.attributes["platform_localtime"].value,
-            "platform_clock_offet":
-                vm.attributes["platform_clock_offet"].value,
-            "platform_enable_audio":
-                vm.attributes["platform_enable_audio"].value,
-            "PCI_bus":
-                vm.attributes["platform_enable_audio"].value,
+            "platform":
+                get_child_nodes_as_dict(vm, "platform", "key", "value"),
             "other_config":
                 get_child_nodes_as_dict(vm, "other_config", "key", "value")
             }
@@ -300,7 +287,7 @@ class xenapi_create:
                 "HVM_boot_policy":
                     get_child_node_attribute(vm, "hvm", "boot_policy"),
                 "HVM_boot_params":
-                    get_child_nodes_as_dict(hvm, "boot_params", "key", "value")
+                    get_child_nodes_as_dict(hvm, "boot_param", "key", "value")
                 })
         try:
             vm_ref = server.xenapi.VM.create(vm_record)
@@ -308,19 +295,29 @@ class xenapi_create:
             traceback.print_exc()
             sys.exit(-1)
 
-        # Now create vbds
-
-        vbds = vm.getElementsByTagName("vbd")
-
-        self.create_vbds(vm_ref, vbds, vdis)
-
-        # Now create vifs
-
-        vifs = vm.getElementsByTagName("vif")
-
-        self.create_vifs(vm_ref, vifs)
-
-        return vm_ref
+        try:
+            # Now create vbds
+
+            vbds = vm.getElementsByTagName("vbd")
+
+            self.create_vbds(vm_ref, vbds, vdis)
+
+            # Now create vifs
+
+            vifs = vm.getElementsByTagName("vif")
+
+            self.create_vifs(vm_ref, vifs)
+
+            # Now create consoles
+
+            consoles = vm.getElementsByTagName("console")
+
+            self.create_consoles(vm_ref, consoles)
+
+            return vm_ref
+        except:
+            server.xenapi.VM.destroy(vm_ref)
+            raise
         
     def create_vbds(self, vm_ref, vbds, vdis):
         log(DEBUG, "create_vbds")
@@ -358,13 +355,16 @@ class xenapi_create:
     def create_vif(self, vm_ref, vif):
         log(DEBUG, "create_vif")
 
-        if "bridge" in vif.attributes.keys():
-            raise "Not allowed to add by bridge just yet"
-        elif "network" in vif.attributes.keys():
-            network = [network_ref
+        if "network" in vif.attributes.keys():
+            networks = [network_ref
                 for network_ref in server.xenapi.network.get_all()
                 if server.xenapi.network.get_name_label(network_ref)
-                       == vif.attributes["network"].value][0]
+                       == vif.attributes["network"].value]
+            if len(networks) > 0:
+                network = networks[0]
+            else:
+                raise OptionError("Network %s doesn't exist"
+                                  % vif.attributes["network"].value)
         else:
             network = self._get_network_ref()
 
@@ -397,6 +397,26 @@ class xenapi_create:
             self._network_refs = server.xenapi.network.get_all()
             return self._network_refs.pop(0)
 
+    def create_consoles(self, vm_ref, consoles):
+        log(DEBUG, "create_consoles")
+        return map(lambda console: self.create_console(vm_ref, console),
+                   consoles)
+
+    def create_console(self, vm_ref, console):
+        log(DEBUG, "create_consoles")
+
+        console_record = {
+            "VM":
+                vm_ref,
+            "protocol":
+                console.attributes["protocol"].value,
+            "other_params":
+                get_child_nodes_as_dict(console,
+                  "other_param", "key", "value")
+            }
+
+        return server.xenapi.console.create(console_record)
+
 def get_child_by_name(exp, childname, default = None):
     try:
         return [child for child in sxp.children(exp)
@@ -460,11 +480,6 @@ class sxp2xml:
             = actions_after_reboot
         vm.attributes["actions_after_crash"] \
             = actions_after_crash
-        vm.attributes["platform_std_VGA"] = "false"
-        vm.attributes["platform_serial"] = ""
-        vm.attributes["platform_localtime"] = ""
-        vm.attributes["platform_clock_offet"] = ""
-        vm.attributes["platform_enable_audio"] = ""
         vm.attributes["PCI_bus"] = ""
 
         vm.attributes["vcpus_max"] \
@@ -502,7 +517,13 @@ class sxp2xml:
             vm.appendChild(pv)
         elif image[0] == "hvm":
             hvm = document.createElement("hvm")
-            hvm.attributes["boot_policy"] = ""
+            hvm.attributes["boot_policy"] = "BIOS order"
+
+            boot_order = document.createElement("boot_param")
+            boot_order.attributes["key"] = "order"
+            boot_order.attributes["value"] \
+                = get_child_by_name(image, "boot", "abcd")
+            hvm.appendChild
 
             vm.appendChild(hvm)
 
@@ -535,6 +556,18 @@ class sxp2xml:
         vifs = map(lambda vif: self.extract_vif(vif, document), vifs_sxp)
 
         map(vm.appendChild, vifs)
+
+        # Last but not least the consoles...
+
+        consoles = self.extract_consoles(image, document)
+
+        map(vm.appendChild, consoles)
+
+        # Platform variables...
+
+        platform = self.extract_platform(image, document)
+
+        map(vm.appendChild, platform)
 
         # transient?
 
@@ -626,13 +659,69 @@ class sxp2xml:
         vif.attributes["qos_algorithm_type"] = ""
 
         if get_child_by_name(vif_sxp, "bridge") is not None:
-            vif.attributes["bridge"] \
+            vif.attributes["network"] \
                 = get_child_by_name(vif_sxp, "bridge")
         
         return vif
 
     _eths = -1
 
+    def mk_other_config(self, key, value, document):
+        other_config = document.createElement("other_config")
+        other_config.attributes["key"] = key
+        other_config.attributes["value"] = value
+        return other_config
+
+    def extract_consoles(self, image, document):
+        consoles = []
+
+        if int(get_child_by_name(image, "nographic", "1")) == 1:
+            return consoles
+        
+        if int(get_child_by_name(image, "vnc", "0")) == 1:
+            console = document.createElement("console")
+            console.attributes["protocol"] = "rfb"
+            console.appendChild(self.mk_other_config(
+                "vncunused", str(get_child_by_name(image, "vncunused", "0")),
+                document))
+            console.appendChild(self.mk_other_config(
+                "vnclisten",
+                get_child_by_name(image, "vnclisten", "127.0.0.1"),
+                document))
+            console.appendChild(self.mk_other_config(
+                "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
+                document))
+            consoles.append(console)          
+        if int(get_child_by_name(image, "sdl", "0")) == 1:
+            console = document.createElement("console")
+            console.attributes["protocol"] = "sdl"
+            console.appendChild(self.mk_other_config(
+                "display", get_child_by_name(image, "display", ""),
+                document))
+            console.appendChild(self.mk_other_config(
+                "xauthority",
+                get_child_by_name(image, "vxauthority", "127.0.0.1"),
+                document))
+            console.appendChild(self.mk_other_config(
+                "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
+                document))
+            consoles.append(console)
+            
+        return consoles
+
+
+    def extract_platform(self, image, document):
+        platform_keys = ['acpi', 'apic', 'pae']
+
+        def extract_platform_key(key):
+            platform = document.createElement("platform")
+            platform.attributes["key"] = key
+            platform.attributes["value"] \
+                = str(get_child_by_name(image, key, "1"))
+            return platform
+        
+        return map(extract_platform_key, platform_keys)
+    
     def getFreshEthDevice(self):
         self._eths += 1
         return "eth%i" % self._eths
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/policies/security_policy.xsd
--- a/tools/security/policies/security_policy.xsd       Fri Mar 30 10:27:15 
2007 -0600
+++ b/tools/security/policies/security_policy.xsd       Fri Mar 30 17:18:42 
2007 -0600
@@ -22,6 +22,8 @@
                                <xsd:element name="Reference" type="xsd:string" 
minOccurs="0" maxOccurs="1" />
                                <xsd:element name="Date" minOccurs="0" 
maxOccurs="1" type="xsd:string"></xsd:element>
                                <xsd:element name="NameSpaceUrl" minOccurs="0" 
maxOccurs="1" type="xsd:string"></xsd:element>
+                               <xsd:element name="Version" minOccurs="0" 
maxOccurs="1" type="VersionFormat"/>
+                               <xsd:element ref="FromPolicy" minOccurs="0" 
maxOccurs="1"/>
                        </xsd:sequence>
                </xsd:complexType>
        </xsd:element>
@@ -116,4 +118,17 @@
                        <xsd:enumeration 
value="PrimaryPolicyComponent"></xsd:enumeration>
                </xsd:restriction>
        </xsd:simpleType>
+       <xsd:element name="FromPolicy">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element name="PolicyName" minOccurs="1" 
maxOccurs="1" type="xsd:string"/>
+                               <xsd:element name="Version" minOccurs="1" 
maxOccurs="1" type="VersionFormat"/>
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+       <xsd:simpleType name="VersionFormat">
+               <xsd:restriction base="xsd:string">
+                       <xsd:pattern 
value="[0-9]{1,8}.[0-9]{1,8}"></xsd:pattern>
+               </xsd:restriction>
+       </xsd:simpleType>
 </xsd:schema>
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c      Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/security/secpol_tool.c      Fri Mar 30 17:18:42 2007 -0600
@@ -57,7 +57,7 @@ void usage(char *progname)
 
 /*************************** DUMPS *******************************/
 
-void acm_dump_chinesewall_buffer(void *buf, int buflen)
+void acm_dump_chinesewall_buffer(void *buf, int buflen, uint16_t chwall_ref)
 {
 
     struct acm_chwall_policy_buffer *cwbuf =
@@ -91,6 +91,8 @@ void acm_dump_chinesewall_buffer(void *b
         for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
             printf("%02x ",
                    ntohs(ssids[i * ntohl(cwbuf->chwall_max_types) + j]));
+        if (i == chwall_ref)
+            printf(" <-- Domain-0");
     }
     printf("\n\nConfict Sets:\n");
     conflicts =
@@ -131,7 +133,7 @@ void acm_dump_chinesewall_buffer(void *b
     }
 }
 
-void acm_dump_ste_buffer(void *buf, int buflen)
+void acm_dump_ste_buffer(void *buf, int buflen, uint16_t ste_ref)
 {
 
     struct acm_ste_policy_buffer *stebuf =
@@ -158,11 +160,14 @@ void acm_dump_ste_buffer(void *buf, int 
         for (j = 0; j < ntohl(stebuf->ste_max_types); j++)
             printf("%02x ",
                    ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j]));
+        if (i == ste_ref)
+            printf(" <-- Domain-0");
     }
     printf("\n\n");
 }
 
-void acm_dump_policy_buffer(void *buf, int buflen)
+void acm_dump_policy_buffer(void *buf, int buflen,
+                            uint16_t chwall_ref, uint16_t ste_ref)
 {
     struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf;
     char *policy_reference_name =
@@ -172,6 +177,9 @@ void acm_dump_policy_buffer(void *buf, i
     printf("============\n");
     printf("POLICY REFERENCE = %s.\n", policy_reference_name);
     printf("PolicyVer = %x.\n", ntohl(pol->policy_version));
+    printf("XML Vers. = %d.%d\n",
+           ntohl(pol->xml_pol_version.major),
+           ntohl(pol->xml_pol_version.minor));
     printf("Magic     = %x.\n", ntohl(pol->magic));
     printf("Len       = %x.\n", ntohl(pol->len));
     printf("Primary   = %s (c=%x, off=%x).\n",
@@ -187,13 +195,15 @@ void acm_dump_policy_buffer(void *buf, i
         acm_dump_chinesewall_buffer(ALIGN8(buf +
                                      ntohl(pol->primary_buffer_offset)),
                                     ntohl(pol->len) -
-                                    ntohl(pol->primary_buffer_offset));
+                                    ntohl(pol->primary_buffer_offset),
+                                    chwall_ref);
         break;
 
     case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
         acm_dump_ste_buffer(ALIGN8(buf + ntohl(pol->primary_buffer_offset)),
                             ntohl(pol->len) -
-                            ntohl(pol->primary_buffer_offset));
+                            ntohl(pol->primary_buffer_offset),
+                            ste_ref);
         break;
 
     case ACM_NULL_POLICY:
@@ -209,13 +219,15 @@ void acm_dump_policy_buffer(void *buf, i
         acm_dump_chinesewall_buffer(ALIGN8(buf +
                                      ntohl(pol->secondary_buffer_offset)),
                                     ntohl(pol->len) -
-                                    ntohl(pol->secondary_buffer_offset));
+                                    ntohl(pol->secondary_buffer_offset),
+                                    chwall_ref);
         break;
 
     case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
         acm_dump_ste_buffer(ALIGN8(buf + ntohl(pol->secondary_buffer_offset)),
                             ntohl(pol->len) -
-                            ntohl(pol->secondary_buffer_offset));
+                            ntohl(pol->secondary_buffer_offset),
+                            ste_ref);
         break;
 
     case ACM_NULL_POLICY:
@@ -227,6 +239,27 @@ void acm_dump_policy_buffer(void *buf, i
     }
 }
 
+/************************** get dom0 ssidref *****************************/
+int acm_get_ssidref(int xc_handle, int domid, uint16_t *chwall_ref,
+                    uint16_t *ste_ref)
+{
+    int ret;
+    struct acm_getssid getssid;
+    char buf[4096];
+    struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *)buf;
+    getssid.interface_version = ACM_INTERFACE_VERSION;
+    set_xen_guest_handle(getssid.ssidbuf, buf);
+    getssid.ssidbuf_size = sizeof(buf);
+    getssid.get_ssid_by = ACM_GETBY_domainid;
+    getssid.id.domainid = domid;
+    ret = xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid));
+    if (ret == 0) {
+        *chwall_ref = ssid->ssidref  & 0xffff;
+        *ste_ref    = ssid->ssidref >> 16;
+    }
+    return ret;
+}
+
 /******************************* get policy ******************************/
 
 #define PULL_CACHE_SIZE                8192
@@ -236,12 +269,16 @@ int acm_domain_getpolicy(int xc_handle)
 {
     struct acm_getpolicy getpolicy;
     int ret;
+    uint16_t chwall_ref, ste_ref;
 
     memset(pull_buffer, 0x00, sizeof(pull_buffer));
     getpolicy.interface_version = ACM_INTERFACE_VERSION;
     set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
     getpolicy.pullcache_size = sizeof(pull_buffer);
     ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
+    if (ret >= 0) {
+        ret = acm_get_ssidref(xc_handle, 0, &chwall_ref, &ste_ref);
+    }
 
     if (ret < 0) {
         printf("ACM operation failed: errno=%d\n", errno);
@@ -251,7 +288,9 @@ int acm_domain_getpolicy(int xc_handle)
     }
 
     /* dump policy  */
-    acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
+    acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer),
+                           chwall_ref, ste_ref);
+
     return ret;
 }
 
@@ -263,6 +302,7 @@ int acm_domain_loadpolicy(int xc_handle,
     int ret, fd;
     off_t len;
     uint8_t *buffer;
+    uint16_t chwall_ssidref, ste_ssidref;
 
     if ((ret = stat(filename, &mystat))) {
         printf("File %s not found.\n", filename);
@@ -279,10 +319,14 @@ int acm_domain_loadpolicy(int xc_handle,
         printf("File %s not found.\n", filename);
         goto free_out;
     }
+    ret =acm_get_ssidref(xc_handle, 0, &chwall_ssidref, &ste_ssidref);
+    if (ret < 0) {
+        goto free_out;
+    }
     if (len == read(fd, buffer, len)) {
         struct acm_setpolicy setpolicy;
         /* dump it and then push it down into xen/acm */
-        acm_dump_policy_buffer(buffer, len);
+        acm_dump_policy_buffer(buffer, len, chwall_ssidref, ste_ssidref);
         setpolicy.interface_version = ACM_INTERFACE_VERSION;
         set_xen_guest_handle(setpolicy.pushcache, buffer);
         setpolicy.pushcache_size = len;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/secpol_xml2bin.c
--- a/tools/security/secpol_xml2bin.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/security/secpol_xml2bin.c   Fri Mar 30 17:18:42 2007 -0600
@@ -108,26 +108,25 @@ char *policy_filename = NULL,
 
 char *policy_reference_name = NULL;
 
+char *policy_version_string = NULL;
+
 void walk_labels(xmlNode * start, xmlDocPtr doc, unsigned long state);
 
 void usage(char *prg)
 {
-    printf("Usage: %s [OPTIONS] POLICYNAME\n", prg);
-    printf
-        ("POLICYNAME is the directory name within the policy directory\n");
-    printf
-        ("that contains the policy files.  The default policy directory\n");
-    printf("is '%s' (see the '-d' option below to change it)\n",
-           POLICY_DIR);
-    printf
-        ("The policy files contained in the POLICYNAME directory must be 
named:\n");
-    printf("\tPOLICYNAME-security_policy.xml\n");
-    printf("\tPOLICYNAME-security_label_template.xml\n\n");
-    printf("OPTIONS:\n");
-    printf("\t-d POLICYDIR\n");
-    printf
-        ("\t\tUse POLICYDIR as the policy directory. This directory must 
contain\n");
-    printf("\t\tthe policy schema file 'security_policy.xsd'\n");
+    printf(
+    "Usage: %s [OPTIONS] POLICYNAME\n"
+    "POLICYNAME is the directory name within the policy directory\n"
+    "that contains the policy files.  The default policy directory\n"
+    "is '%s' (see the '-d' option below to change it)\n"
+    "The policy files contained in the POLICYNAME directory must be named:\n"
+    "\tPOLICYNAME-security_policy.xml\n"
+    "\tPOLICYNAME-security_label_template.xml\n\n"
+    "OPTIONS:\n"
+    "\t-d POLICYDIR\n"
+    "\t\tUse POLICYDIR as the policy directory. This directory must \n"
+    "\t\tcontain the policy schema file 'security_policy.xsd'\n",
+    prg, POLICY_DIR);
     exit(EXIT_FAILURE);
 }
 
@@ -300,25 +299,50 @@ void walk_policy(xmlNode * start, xmlDoc
         case XML2BIN_CHWALLTYPES:
         case XML2BIN_CONFLICTSETS:
         case XML2BIN_POLICYHEADER:
+        case XML2BIN_FROMPOLICY:
             walk_policy(cur_node->children, doc, state | (1 << code));
             break;
 
         case XML2BIN_POLICYNAME:       /* get policy reference name .... */
-            if (state != XML2BIN_PN_S) {
+            if (state != XML2BIN_PN_S &&
+                state != XML2BIN_PN_frompolicy_S) {
                 printf("ERROR: >Url< >%s< out of context.\n",
                        (char *) xmlNodeListGetString(doc,
                                                      cur_node->
                                                      xmlChildrenNode, 1));
                 exit(EXIT_FAILURE);
             }
-            policy_reference_name = (char *)
-                xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
-            if (!policy_reference_name) {
-                printf("ERROR: empty >policy reference name (Url)<!\n");
+            if (state == XML2BIN_PN_S) {
+                policy_reference_name = (char *)
+                    xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+                if (!policy_reference_name) {
+                    printf("ERROR: empty >policy reference name (Url)<!\n");
+                    exit(EXIT_FAILURE);
+                } else
+                    printf("Policy Reference name (Url): %s\n",
+                           policy_reference_name);
+            }
+            break;
+
+        case XML2BIN_VERSION:         /* get policy version number .... */
+            if (state != XML2BIN_PN_S &&
+                state != XML2BIN_PN_frompolicy_S) {
+                printf("ERROR: >Url< >%s< out of context.\n",
+                       (char *) xmlNodeListGetString(doc,
+                                                     cur_node->
+                                                     xmlChildrenNode, 1));
                 exit(EXIT_FAILURE);
-            } else
-                printf("Policy Reference name (Url): %s\n",
-                       policy_reference_name);
+            }
+            if (state == XML2BIN_PN_S) {
+                policy_version_string = (char *)
+                    xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+                if (!policy_version_string) {
+                    printf("ERROR: empty >policy version string <!\n");
+                    exit(EXIT_FAILURE);
+                } else
+                    printf("Policy version string: %s\n",
+                           policy_version_string);
+            }
             break;
 
         case XML2BIN_STE:
@@ -1135,8 +1159,12 @@ int write_binary(char *filename)
         NULL, *policy_reference_buffer = NULL;
     u_int32_t len;
     int fd, ret = 0;
+    uint32_t major = 0, minor = 0;
 
     u_int32_t len_ste = 0, len_chwall = 0, len_pr = 0;  /* length of policy 
components */
+
+    if (policy_version_string)
+        sscanf(policy_version_string,"%d.%d", &major, &minor);
 
     /* open binary file */
     if ((fd =
@@ -1152,6 +1180,8 @@ int write_binary(char *filename)
     /* determine primary component (default chwall) */
     header.policy_version = htonl(ACM_POLICY_VERSION);
     header.magic = htonl(ACM_MAGIC);
+    header.xml_pol_version.major = htonl(major);
+    header.xml_pol_version.minor = htonl(minor);
 
     len = sizeof(struct acm_policy_buffer);
     if (have_chwall)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/secpol_xml2bin.h
--- a/tools/security/secpol_xml2bin.h   Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/security/secpol_xml2bin.h   Fri Mar 30 17:18:42 2007 -0600
@@ -22,31 +22,35 @@
 #define SCHEMA_FILENAME                        "security_policy.xsd"
 
 /* basic states (used as 1 << X) */
-#define ENDOFLIST_POS           22  /* ADAPT!! this position will be NULL; 
stay below 32 (bit) */
-#define XML2BIN_SECPOL          0   /* policy tokens */
-#define XML2BIN_STE             1
-#define XML2BIN_CHWALL          2
-#define XML2BIN_CONFLICTSETS    3
-#define XML2BIN_CSTYPE          4
-#define XML2BIN_POLICYHEADER    5
-#define XML2BIN_NSURL           6
-#define XML2BIN_POLICYNAME      7
-#define XML2BIN_URL             8
-#define XML2BIN_REFERENCE       9
-#define XML2BIN_DATE            10
+enum {
+    XML2BIN_SECPOL = 0,   /* policy tokens */
+    XML2BIN_STE,
+    XML2BIN_CHWALL,
+    XML2BIN_CONFLICTSETS,
+    XML2BIN_CSTYPE,
+    XML2BIN_POLICYHEADER,
+    XML2BIN_NSURL,
+    XML2BIN_POLICYNAME,
+    XML2BIN_URL,
+    XML2BIN_REFERENCE,
+    XML2BIN_DATE,
+    XML2BIN_VERSION,
+    XML2BIN_FROMPOLICY,
 
-#define XML2BIN_LABELTEMPLATE   11  /* label tokens */
-#define XML2BIN_SUBJECTS        12
-#define XML2BIN_OBJECTS         13
-#define XML2BIN_VM              14
-#define XML2BIN_RES             15
-#define XML2BIN_NAME            16
+    XML2BIN_LABELTEMPLATE,  /* label tokens */
+    XML2BIN_SUBJECTS,
+    XML2BIN_OBJECTS,
+    XML2BIN_VM,
+    XML2BIN_RES,
+    XML2BIN_NAME,
 
-#define XML2BIN_STETYPES        17  /* shared tokens */
-#define XML2BIN_CHWALLTYPES     18
-#define XML2BIN_TYPE            19
-#define XML2BIN_TEXT            20
-#define XML2BIN_COMMENT         21
+    XML2BIN_STETYPES,
+    XML2BIN_CHWALLTYPES,
+    XML2BIN_TYPE,
+    XML2BIN_TEXT,
+    XML2BIN_COMMENT,
+    ENDOFLIST_POS /* keep last ! */
+};
 
 /* type "data type" (currently 16bit) */
 typedef u_int16_t type_t;
@@ -68,6 +72,8 @@ char *token[32] =                       
     [XML2BIN_URL]           = "PolicyUrl",
     [XML2BIN_REFERENCE]     = "Reference",
     [XML2BIN_DATE]          = "Date",
+    [XML2BIN_VERSION]       = "Version",
+    [XML2BIN_FROMPOLICY]    = "FromPolicy",
 
     [XML2BIN_LABELTEMPLATE] = "SecurityLabelTemplate", /* label-template xml */
     [XML2BIN_SUBJECTS]      = "SubjectLabels",
@@ -79,7 +85,7 @@ char *token[32] =                       
     [XML2BIN_STETYPES]      = "SimpleTypeEnforcementTypes", /* common tags */
     [XML2BIN_CHWALLTYPES]   = "ChineseWallTypes",
     [XML2BIN_TYPE]          = "Type",
-       [XML2BIN_TEXT]          = "text",
+    [XML2BIN_TEXT]          = "text",
     [XML2BIN_COMMENT]       = "comment",
     [ENDOFLIST_POS]         = NULL  /* End of LIST, adapt ENDOFLIST_POS
                                        when adding entries */
@@ -112,6 +118,10 @@ char *token[32] =                       
 #define XML2BIN_PN_S ((1 << XML2BIN_SECPOL) | \
                  (1 << XML2BIN_POLICYHEADER))
 
+#define XML2BIN_PN_frompolicy_S ((1 << XML2BIN_SECPOL) | \
+                 (1 << XML2BIN_POLICYHEADER) | \
+                 (1 << XML2BIN_FROMPOLICY))
+
 /* label xml states */
 #define XML2BIN_VM_S ((1 << XML2BIN_SECPOL) | \
                  (1 << XML2BIN_LABELTEMPLATE) |        \
@@ -147,7 +157,7 @@ char *token[32] =                       
  */
 
 /* protects from unnoticed changes in struct acm_policy_buffer */
-#define WRITTEN_AGAINST_ACM_POLICY_VERSION  2
+#define WRITTEN_AGAINST_ACM_POLICY_VERSION  3
 
 /* protects from unnoticed changes in struct acm_chwall_policy_buffer */
 #define WRITTEN_AGAINST_ACM_CHWALL_VERSION  1
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/xcutils/xc_restore.c        Fri Mar 30 17:18:42 2007 -0600
@@ -42,8 +42,6 @@ main(int argc, char **argv)
     apic = atoi(argv[8]);
 
     if (hvm) {
-         /* pass the memsize to xc_hvm_restore to find the store_mfn */
-        store_mfn = hvm;
         ret = xc_hvm_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn,
                 &store_mfn, pae, apic);
     } else 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/xm-test/lib/XmTestLib/XenAPIDomain.py
--- a/tools/xm-test/lib/XmTestLib/XenAPIDomain.py       Fri Mar 30 10:27:15 
2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py       Fri Mar 30 17:18:42 
2007 -0600
@@ -22,7 +22,6 @@ import os
 import os
 import sys
 from XmTestLib import *
-from xen.util.xmlrpclib2 import ServerProxy
 from types import DictType
 
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
tools/xm-test/tests/destroy/06_destroy_dom0_neg.py
--- a/tools/xm-test/tests/destroy/06_destroy_dom0_neg.py        Fri Mar 30 
10:27:15 2007 -0600
+++ b/tools/xm-test/tests/destroy/06_destroy_dom0_neg.py        Fri Mar 30 
17:18:42 2007 -0600
@@ -10,5 +10,5 @@ status, output = traceCommand("xm destro
 status, output = traceCommand("xm destroy 0")
 if status == 0:
     FAIL("xm destroy returned bad status, expected non 0, status is: %i" % 
status)
-elif not re.search("Error", output):
+elif not re.search("Error", output, re.I):
     FAIL("xm destroy returned bad output, expected Error:, output is: %s" % 
output)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Fri Mar 30 
10:27:15 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Fri Mar 30 
17:18:42 2007 -0600
@@ -36,6 +36,7 @@
 #include <asm/pgtable.h>
 #include <xen/interface/memory.h>
 #include <xen/features.h>
+#include <xen/gnttab.h>
 #ifdef __ia64__
 #include <asm/xen/xencomm.h>
 #endif
@@ -61,9 +62,11 @@ unsigned long *phys_to_machine_mapping;
 unsigned long *phys_to_machine_mapping;
 EXPORT_SYMBOL(phys_to_machine_mapping);
 
+static unsigned long shared_info_frame;
+static uint64_t callback_via;
+
 static int __devinit init_xen_info(void)
 {
-       unsigned long shared_info_frame;
        struct xen_add_to_physmap xatp;
        extern void *shared_info_area;
 
@@ -219,7 +222,6 @@ static int __devinit platform_pci_init(s
        int i, ret;
        long ioaddr, iolen;
        long mmio_addr, mmio_len;
-       uint64_t callback_via;
 
        i = pci_enable_device(pdev);
        if (i)
@@ -303,6 +305,35 @@ static struct pci_driver platform_driver
 
 static int pci_device_registered;
 
+void platform_pci_suspend(void)
+{
+       gnttab_suspend();
+}
+EXPORT_SYMBOL_GPL(platform_pci_suspend);
+
+void platform_pci_resume(void)
+{
+       struct xen_add_to_physmap xatp;
+       phys_to_machine_mapping = NULL;
+
+       /* do 2 things for PV driver restore on HVM
+        * 1: rebuild share info
+        * 2: set callback irq again
+        */
+       xatp.domid = DOMID_SELF;
+       xatp.idx = 0;
+       xatp.space = XENMAPSPACE_shared_info;
+       xatp.gpfn = shared_info_frame;
+       if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+               BUG();
+
+       if (( set_callback_via(callback_via)))
+               printk("platform_pci_resume failure!\n");
+
+       gnttab_resume();
+}
+EXPORT_SYMBOL_GPL(platform_pci_resume);
+
 static int __init platform_pci_module_init(void)
 {
        int rc;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_chinesewall_hooks.c   Fri Mar 30 17:18:42 2007 -0600
@@ -41,6 +41,9 @@
 #include <acm/acm_core.h>
 #include <acm/acm_hooks.h>
 #include <acm/acm_endian.h>
+#include <acm/acm_core.h>
+
+ssidref_t dom0_chwall_ssidref = 0x0001;
 
 /* local cache structures for chinese wall policy */
 struct chwall_binary_policy chwall_bin_pol;
@@ -53,7 +56,7 @@ int acm_init_chwall_policy(void)
 {
     /* minimal startup policy; policy write-locked already */
     chwall_bin_pol.max_types = 1;
-    chwall_bin_pol.max_ssidrefs = 2;
+    chwall_bin_pol.max_ssidrefs = 1 + dom0_chwall_ssidref;
     chwall_bin_pol.max_conflictsets = 1;
     chwall_bin_pol.ssidrefs =
         (domaintype_t *) xmalloc_array(domaintype_t,
@@ -254,7 +257,7 @@ chwall_init_state(struct acm_chwall_poli
      * more than one type is currently running */
 }
 
-static int chwall_set_policy(u8 * buf, u32 buf_size)
+static int chwall_set_policy(u8 * buf, u32 buf_size, int is_bootpolicy)
 {
     /* policy write-locked already */
     struct acm_chwall_policy_buffer *chwall_buf =
@@ -285,6 +288,12 @@ static int chwall_set_policy(u8 * buf, u
     if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
         (chwall_buf->policy_version != ACM_CHWALL_VERSION))
         return -EINVAL;
+
+    /* during boot dom0_chwall_ssidref is set */
+    if (is_bootpolicy &&
+        (dom0_chwall_ssidref >= chwall_buf->chwall_max_ssidrefs)) {
+        goto error_free;
+    }
 
     /* 1. allocate new buffers */
     ssids =
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_core.c
--- a/xen/acm/acm_core.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_core.c        Fri Mar 30 17:18:42 2007 -0600
@@ -62,18 +62,63 @@ struct acm_binary_policy acm_bin_pol;
 /* acm binary policy lock */
 DEFINE_RWLOCK(acm_bin_pol_rwlock);
 
+/* ACM's only accepted policy name */
+char polname[80];
+char *acm_accepted_boot_policy_name = NULL;
+
+static void __init set_dom0_ssidref(const char *val)
+{
+    /* expected format:
+         ssidref=<hex number>:<policy name>
+         Policy name must not have a 'space'.
+     */
+    const char *c;
+    int lo, hi;
+    int i;
+    int dom0_ssidref = simple_strtoull(val, &c, 0);
+
+    if (!strncmp(&c[0],":sHype:", 7)) {
+        lo = dom0_ssidref & 0xffff;
+        if (lo < ACM_MAX_NUM_TYPES && lo >= 1)
+            dom0_chwall_ssidref = lo;
+        hi = dom0_ssidref >> 16;
+        if (hi < ACM_MAX_NUM_TYPES && hi >= 1)
+            dom0_ste_ssidref = hi;
+        for (i = 0; i < sizeof(polname); i++) {
+            polname[i] = c[7+i];
+            if (polname[i] == '\0' || polname[i] == '\t' ||
+                polname[i] == '\n' || polname[i] == ' '  ||
+                polname[i] == ':') {
+                break;
+            }
+        }
+        polname[i] = 0;
+        acm_accepted_boot_policy_name = polname;
+    }
+}
+
+custom_param("ssidref", set_dom0_ssidref);
+
 int
 acm_set_policy_reference(u8 *buf, u32 buf_size)
 {
+    char *name = (char *)(buf + sizeof(struct acm_policy_reference_buffer));
     struct acm_policy_reference_buffer *pr = (struct 
acm_policy_reference_buffer *)buf;
+
+    if (acm_accepted_boot_policy_name != NULL) {
+        if (strcmp(acm_accepted_boot_policy_name, name)) {
+            printk("Policy's name '%s' is not the expected one '%s'.\n",
+                   name, acm_accepted_boot_policy_name);
+            return ACM_ERROR;
+        }
+    }
+
     acm_bin_pol.policy_reference_name = (char *)xmalloc_array(u8, 
be32_to_cpu(pr->len));
 
     if (!acm_bin_pol.policy_reference_name)
         return -ENOMEM;
-
-    strlcpy(acm_bin_pol.policy_reference_name,
-            (char *)(buf + sizeof(struct acm_policy_reference_buffer)),
-            be32_to_cpu(pr->len));
+    strlcpy(acm_bin_pol.policy_reference_name, name, be32_to_cpu(pr->len));
+
     printk("%s: Activating policy %s\n", __func__,
            acm_bin_pol.policy_reference_name);
     return 0;
@@ -190,7 +235,8 @@ acm_is_policy(char *buf, unsigned long l
 
 static int
 acm_setup(char *policy_start,
-          unsigned long policy_len)
+          unsigned long policy_len,
+          int is_bootpolicy)
 {
     int rc = ACM_OK;
     struct acm_policy_buffer *pol;
@@ -202,7 +248,8 @@ acm_setup(char *policy_start,
     if (be32_to_cpu(pol->magic) != ACM_MAGIC)
         return rc;
 
-    rc = do_acm_set_policy((void *)policy_start, (u32)policy_len);
+    rc = do_acm_set_policy((void *)policy_start, (u32)policy_len,
+                           is_bootpolicy);
     if (rc == ACM_OK)
     {
         printkd("Policy len  0x%lx, start at %p.\n",policy_len,policy_start);
@@ -224,7 +271,10 @@ acm_init(char *policy_start,
     int ret = ACM_OK;
 
     /* first try to load the boot policy (uses its own locks) */
-    acm_setup(policy_start, policy_len);
+    acm_setup(policy_start, policy_len, 1);
+
+    /* a user-provided policy may have any name; only matched during boot */
+    acm_accepted_boot_policy_name = NULL;
 
     if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
     {
@@ -235,6 +285,9 @@ acm_init(char *policy_start,
     /* else continue with the minimal hardcoded default startup policy */
     printk("%s: Loading default policy (%s).\n",
            __func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY));
+
+    /* (re-)set dom-0 ssidref to default */
+    dom0_ste_ssidref = dom0_chwall_ssidref = 0x0001;
 
     if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) {
         ret = -EINVAL;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_null_hooks.c
--- a/xen/acm/acm_null_hooks.c  Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_null_hooks.c  Fri Mar 30 17:18:42 2007 -0600
@@ -33,7 +33,7 @@ null_dump_binary_policy(u8 *buf, u32 buf
 }
 
 static int
-null_set_binary_policy(u8 *buf, u32 buf_size)
+null_set_binary_policy(u8 *buf, u32 buf_size, int is_bootpolicy)
 { 
     return ACM_OK;
 }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_policy.c      Fri Mar 30 17:18:42 2007 -0600
@@ -50,7 +50,7 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
         printk("%s: Error copying!\n",__func__);
         goto error_free;
     }
-    ret = do_acm_set_policy(policy_buffer, buf_size);
+    ret = do_acm_set_policy(policy_buffer, buf_size, 0);
 
  error_free:
     xfree(policy_buffer);
@@ -59,9 +59,10 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
 
 
 int
-do_acm_set_policy(void *buf, u32 buf_size)
+do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy)
 {
     struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
+    uint32_t offset, length;
     /* some sanity checking */
     if ((be32_to_cpu(pol->magic) != ACM_MAGIC) ||
         (buf_size != be32_to_cpu(pol->len)) ||
@@ -92,23 +93,34 @@ do_acm_set_policy(void *buf, u32 buf_siz
     /* get bin_policy lock and rewrite policy (release old one) */
     write_lock(&acm_bin_pol_rwlock);
 
+    offset = be32_to_cpu(pol->policy_reference_offset);
+    length = be32_to_cpu(pol->primary_buffer_offset) - offset;
+
     /* set label reference name */
-    if (acm_set_policy_reference(buf + 
be32_to_cpu(pol->policy_reference_offset),
-                                 be32_to_cpu(pol->primary_buffer_offset) -
-                                 be32_to_cpu(pol->policy_reference_offset)))
+    if ( (offset + length) > buf_size ||
+         acm_set_policy_reference(buf + offset, length))
         goto error_lock_free;
 
     /* set primary policy data */
-    if (acm_primary_ops->set_binary_policy(buf + 
be32_to_cpu(pol->primary_buffer_offset),
-                                           
be32_to_cpu(pol->secondary_buffer_offset) -
-                                           
be32_to_cpu(pol->primary_buffer_offset)))
+    offset = be32_to_cpu(pol->primary_buffer_offset);
+    length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
+
+    if ( (offset + length) > buf_size ||
+         acm_primary_ops->set_binary_policy(buf + offset, length,
+                                            is_bootpolicy))
         goto error_lock_free;
 
     /* set secondary policy data */
-    if (acm_secondary_ops->set_binary_policy(buf + 
be32_to_cpu(pol->secondary_buffer_offset),
-                                             be32_to_cpu(pol->len) - 
-                                             
be32_to_cpu(pol->secondary_buffer_offset)))
-        goto error_lock_free;
+    offset = be32_to_cpu(pol->secondary_buffer_offset);
+    length = be32_to_cpu(pol->len) - offset;
+    if ( (offset + length) > buf_size ||
+         acm_secondary_ops->set_binary_policy(buf + offset, length,
+                                              is_bootpolicy))
+        goto error_lock_free;
+
+    memcpy(&acm_bin_pol.xml_pol_version,
+           &pol->xml_pol_version,
+           sizeof(acm_bin_pol.xml_pol_version));
 
     write_unlock(&acm_bin_pol_rwlock);
     return ACM_OK;
@@ -126,7 +138,7 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu
     u8 *policy_buffer;
     int ret;
     struct acm_policy_buffer *bin_pol;
- 
+
     if (buf_size < sizeof(struct acm_policy_buffer))
         return -EFAULT;
 
@@ -145,6 +157,10 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu
     bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
     bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
      
+    memcpy(&bin_pol->xml_pol_version,
+           &acm_bin_pol.xml_pol_version,
+           sizeof(struct acm_policy_version));
+
     ret = acm_dump_policy_reference(policy_buffer + 
be32_to_cpu(bin_pol->policy_reference_offset),
                                     buf_size - 
be32_to_cpu(bin_pol->policy_reference_offset));
     if (ret < 0)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c       Fri Mar 30 10:27:15 
2007 -0600
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c       Fri Mar 30 17:18:42 
2007 -0600
@@ -31,6 +31,9 @@
 #include <acm/acm_hooks.h>
 #include <asm/atomic.h>
 #include <acm/acm_endian.h>
+#include <acm/acm_core.h>
+
+ssidref_t dom0_ste_ssidref = 0x0001;
 
 /* local cache structures for STE policy */
 struct ste_binary_policy ste_bin_pol;
@@ -74,15 +77,21 @@ int acm_init_ste_policy(void)
 {
     /* minimal startup policy; policy write-locked already */
     ste_bin_pol.max_types = 1;
-    ste_bin_pol.max_ssidrefs = 2;
-    ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2);
-    memset(ste_bin_pol.ssidrefs, 0, 2);
+    ste_bin_pol.max_ssidrefs = 1 + dom0_ste_ssidref;
+    ste_bin_pol.ssidrefs =
+            (domaintype_t *)xmalloc_array(domaintype_t,
+                                          ste_bin_pol.max_types *
+                                          ste_bin_pol.max_ssidrefs);
 
     if (ste_bin_pol.ssidrefs == NULL)
         return ACM_INIT_SSID_ERROR;
 
- /* initialize state so that dom0 can start up and communicate with itself */
-    ste_bin_pol.ssidrefs[1] = 1;
+    memset(ste_bin_pol.ssidrefs, 0, sizeof(domaintype_t) *
+                                    ste_bin_pol.max_types *
+                                    ste_bin_pol.max_ssidrefs);
+
+    /* initialize state so that dom0 can start up and communicate with itself 
*/
+    ste_bin_pol.ssidrefs[ste_bin_pol.max_types * dom0_ste_ssidref] = 1;
 
     /* init stats */
     atomic_set(&(ste_bin_pol.ec_eval_count), 0);
@@ -274,7 +283,7 @@ ste_init_state(struct acm_ste_policy_buf
 
 /* set new policy; policy write-locked already */
 static int
-ste_set_policy(u8 *buf, u32 buf_size)
+ste_set_policy(u8 *buf, u32 buf_size, int is_bootpolicy)
 {
     struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer 
*)buf;
     void *ssidrefsbuf;
@@ -304,6 +313,11 @@ ste_set_policy(u8 *buf, u32 buf_size)
     }
     if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * 
ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size)
         goto error_free;
+
+    /* during boot dom0_chwall_ssidref is set */
+    if (is_bootpolicy && (dom0_ste_ssidref >= ste_buf->ste_max_ssidrefs)) {
+        goto error_free;
+    }
 
     arrcpy(ssidrefsbuf, 
            buf + ste_buf->ste_ssid_offset,
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c       Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/asm-offsets.c       Fri Mar 30 17:18:42 2007 -0600
@@ -223,10 +223,11 @@ void foo(void)
 
 #ifdef PERF_COUNTERS
        BLANK();
-       DEFINE(RECOVER_TO_PAGE_FAULT_PERFC_OFS, offsetof (struct perfcounter, 
recover_to_page_fault));
-       DEFINE(RECOVER_TO_BREAK_FAULT_PERFC_OFS, offsetof (struct perfcounter, 
recover_to_break_fault));
-       DEFINE(FAST_HYPERPRIVOP_PERFC_OFS, offsetof (struct perfcounter, 
fast_hyperprivop));
-       DEFINE(FAST_REFLECT_PERFC_OFS, offsetof (struct perfcounter, 
fast_reflect));
+       DEFINE(IA64_PERFC_recover_to_page_fault, PERFC_recover_to_page_fault);
+       DEFINE(IA64_PERFC_recover_to_break_fault, PERFC_recover_to_break_fault);
+       DEFINE(IA64_PERFC_fast_vhpt_translate, PERFC_fast_vhpt_translate);
+       DEFINE(IA64_PERFC_fast_hyperprivop, PERFC_fast_hyperprivop);
+       DEFINE(IA64_PERFC_fast_reflect, PERFC_fast_reflect);
 #endif
 
        BLANK();
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/linux-xen/irq_ia64.c
--- a/xen/arch/ia64/linux-xen/irq_ia64.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/linux-xen/irq_ia64.c        Fri Mar 30 17:18:42 2007 -0600
@@ -113,7 +113,7 @@ ia64_handle_irq (ia64_vector vector, str
        unsigned long saved_tpr;
 
 #ifdef XEN
-       perfc_incrc(irqs);
+       perfc_incr(irqs);
 #endif
 #if IRQ_DEBUG
 #ifdef XEN
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/linux-xen/mca.c     Fri Mar 30 17:18:42 2007 -0600
@@ -396,16 +396,6 @@ ia64_log_queue(int sal_info_type, int vi
 #ifdef CONFIG_ACPI
 
 #ifdef XEN
-/**
- *     Copy from linux/include/asm-generic/bug.h
- */
-#define WARN_ON(condition) do { \
-       if (unlikely((condition)!=0)) { \
-               printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, 
__LINE__); \
-               dump_stack(); \
-       } \
-} while (0)
-
 /**
  *     Copy from linux/kernel/irq/manage.c
  *
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/linux-xen/smp.c     Fri Mar 30 17:18:42 2007 -0600
@@ -148,7 +148,7 @@ handle_IPI (int irq, void *dev_id, struc
        unsigned long ops;
 
 #ifdef XEN
-       perfc_incrc(ipis);
+       perfc_incr(ipis);
 #endif
        mb();   /* Order interrupt and bit testing. */
        while ((ops = xchg(pending_ipis, 0)) != 0) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/pal_emul.c
--- a/xen/arch/ia64/vmx/pal_emul.c      Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/pal_emul.c      Fri Mar 30 17:18:42 2007 -0600
@@ -37,7 +37,7 @@ pal_emul(struct vcpu *vcpu)
        vcpu_get_gr_nat(vcpu, 30, &gr30); 
        vcpu_get_gr_nat(vcpu, 31, &gr31);
 
-       perfc_incrc(vmx_pal_emul);
+       perfc_incr(vmx_pal_emul);
        result = xen_pal_emulator(gr28, gr29, gr30, gr31);
 
        vcpu_set_gr(vcpu, 8, result.status, 0);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vlsapic.c       Fri Mar 30 17:18:42 2007 -0600
@@ -692,8 +692,8 @@ static void vlsapic_write_ipi(VCPU *vcpu
     if (targ == NULL)
         panic_domain(NULL, "Unknown IPI cpu\n");
 
-    if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags) ||
-        test_bit(_VCPUF_down, &targ->vcpu_flags)) {
+    if (!targ->is_initialised ||
+        test_bit(_VPF_down, &targ->pause_flags)) {
 
         struct pt_regs *targ_regs = vcpu_regs(targ);
         struct vcpu_guest_context c;
@@ -709,7 +709,7 @@ static void vlsapic_write_ipi(VCPU *vcpu
         targ_regs->cr_iip = d->arch.sal_data->boot_rdv_ip;
         targ_regs->r1 = d->arch.sal_data->boot_rdv_r1;
 
-        if (test_and_clear_bit(_VCPUF_down,&targ->vcpu_flags)) {
+        if (test_and_clear_bit(_VPF_down,&targ->pause_flags)) {
             vcpu_wake(targ);
             printk(XENLOG_DEBUG "arch_boot_vcpu: vcpu %d awaken %016lx!\n",
                    targ->vcpu_id, targ_regs->cr_iip);
@@ -717,7 +717,7 @@ static void vlsapic_write_ipi(VCPU *vcpu
             printk("arch_boot_vcpu: huh, already awake!");
         }
     } else {
-        int running = test_bit(_VCPUF_running, &targ->vcpu_flags);
+        int running = targ->is_running;
         vlsapic_deliver_ipi(targ, ((ipi_d_t)value).dm, 
                             ((ipi_d_t)value).vector);
         vcpu_unblock(targ);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c  Fri Mar 30 17:18:42 2007 -0600
@@ -598,7 +598,7 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u6
     vcpu_get_rr(vcpu, va, &args.rid);
     args.ps = ps;
     for_each_vcpu (d, v) {
-        if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+        if (!v->is_initialised)
             continue;
 
         args.vcpu = v;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_process.c   Fri Mar 30 17:18:42 2007 -0600
@@ -151,7 +151,7 @@ vmx_ia64_handle_break (unsigned long ifa
     struct domain *d = current->domain;
     struct vcpu *v = current;
 
-    perfc_incrc(vmx_ia64_handle_break);
+    perfc_incr(vmx_ia64_handle_break);
 #ifdef CRASH_DEBUG
     if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
         IS_VMM_ADDRESS(regs->cr_iip)) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmx_support.c
--- a/xen/arch/ia64/vmx/vmx_support.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_support.c   Fri Mar 30 17:18:42 2007 -0600
@@ -82,12 +82,12 @@ void vmx_send_assist_req(struct vcpu *v)
             p->state != STATE_IOREQ_INPROCESS)
             break;
 
-        set_bit(_VCPUF_blocked_in_xen, &current->vcpu_flags);
+        set_bit(_VPF_blocked_in_xen, &current->pause_flags);
         mb(); /* set blocked status /then/ re-evaluate condition */
         if (p->state != STATE_IOREQ_READY &&
             p->state != STATE_IOREQ_INPROCESS)
         {
-            clear_bit(_VCPUF_blocked_in_xen, &current->vcpu_flags);
+            clear_bit(_VPF_blocked_in_xen, &current->pause_flags);
             break;
         }
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmx_virt.c
--- a/xen/arch/ia64/vmx/vmx_virt.c      Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_virt.c      Fri Mar 30 17:18:42 2007 -0600
@@ -1401,159 +1401,159 @@ if ( (cause == 0xff && opcode == 0x1e000
 
     switch(cause) {
     case EVENT_RSM:
-        perfc_incrc(vmx_rsm);
+        perfc_incr(vmx_rsm);
         status=vmx_emul_rsm(vcpu, inst);
         break;
     case EVENT_SSM:
-        perfc_incrc(vmx_ssm);
+        perfc_incr(vmx_ssm);
         status=vmx_emul_ssm(vcpu, inst);
         break;
     case EVENT_MOV_TO_PSR:
-        perfc_incrc(vmx_mov_to_psr);
+        perfc_incr(vmx_mov_to_psr);
         status=vmx_emul_mov_to_psr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_PSR:
-        perfc_incrc(vmx_mov_from_psr);
+        perfc_incr(vmx_mov_from_psr);
         status=vmx_emul_mov_from_psr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_CR:
-        perfc_incrc(vmx_mov_from_cr);
+        perfc_incr(vmx_mov_from_cr);
         status=vmx_emul_mov_from_cr(vcpu, inst);
         break;
     case EVENT_MOV_TO_CR:
-        perfc_incrc(vmx_mov_to_cr);
+        perfc_incr(vmx_mov_to_cr);
         status=vmx_emul_mov_to_cr(vcpu, inst);
         break;
     case EVENT_BSW_0:
-        perfc_incrc(vmx_bsw0);
+        perfc_incr(vmx_bsw0);
         status=vmx_emul_bsw0(vcpu, inst);
         break;
     case EVENT_BSW_1:
-        perfc_incrc(vmx_bsw1);
+        perfc_incr(vmx_bsw1);
         status=vmx_emul_bsw1(vcpu, inst);
         break;
     case EVENT_COVER:
-        perfc_incrc(vmx_cover);
+        perfc_incr(vmx_cover);
         status=vmx_emul_cover(vcpu, inst);
         break;
     case EVENT_RFI:
-        perfc_incrc(vmx_rfi);
+        perfc_incr(vmx_rfi);
         status=vmx_emul_rfi(vcpu, inst);
         break;
     case EVENT_ITR_D:
-        perfc_incrc(vmx_itr_d);
+        perfc_incr(vmx_itr_d);
         status=vmx_emul_itr_d(vcpu, inst);
         break;
     case EVENT_ITR_I:
-        perfc_incrc(vmx_itr_i);
+        perfc_incr(vmx_itr_i);
         status=vmx_emul_itr_i(vcpu, inst);
         break;
     case EVENT_PTR_D:
-        perfc_incrc(vmx_ptr_d);
+        perfc_incr(vmx_ptr_d);
         status=vmx_emul_ptr_d(vcpu, inst);
         break;
     case EVENT_PTR_I:
-        perfc_incrc(vmx_ptr_i);
+        perfc_incr(vmx_ptr_i);
         status=vmx_emul_ptr_i(vcpu, inst);
         break;
     case EVENT_ITC_D:
-        perfc_incrc(vmx_itc_d);
+        perfc_incr(vmx_itc_d);
         status=vmx_emul_itc_d(vcpu, inst);
         break;
     case EVENT_ITC_I:
-        perfc_incrc(vmx_itc_i);
+        perfc_incr(vmx_itc_i);
         status=vmx_emul_itc_i(vcpu, inst);
         break;
     case EVENT_PTC_L:
-        perfc_incrc(vmx_ptc_l);
+        perfc_incr(vmx_ptc_l);
         status=vmx_emul_ptc_l(vcpu, inst);
         break;
     case EVENT_PTC_G:
-        perfc_incrc(vmx_ptc_g);
+        perfc_incr(vmx_ptc_g);
         status=vmx_emul_ptc_g(vcpu, inst);
         break;
     case EVENT_PTC_GA:
-        perfc_incrc(vmx_ptc_ga);
+        perfc_incr(vmx_ptc_ga);
         status=vmx_emul_ptc_ga(vcpu, inst);
         break;
     case EVENT_PTC_E:
-        perfc_incrc(vmx_ptc_e);
+        perfc_incr(vmx_ptc_e);
         status=vmx_emul_ptc_e(vcpu, inst);
         break;
     case EVENT_MOV_TO_RR:
-        perfc_incrc(vmx_mov_to_rr);
+        perfc_incr(vmx_mov_to_rr);
         status=vmx_emul_mov_to_rr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_RR:
-        perfc_incrc(vmx_mov_from_rr);
+        perfc_incr(vmx_mov_from_rr);
         status=vmx_emul_mov_from_rr(vcpu, inst);
         break;
     case EVENT_THASH:
-        perfc_incrc(vmx_thash);
+        perfc_incr(vmx_thash);
         status=vmx_emul_thash(vcpu, inst);
         break;
     case EVENT_TTAG:
-        perfc_incrc(vmx_ttag);
+        perfc_incr(vmx_ttag);
         status=vmx_emul_ttag(vcpu, inst);
         break;
     case EVENT_TPA:
-        perfc_incrc(vmx_tpa);
+        perfc_incr(vmx_tpa);
         status=vmx_emul_tpa(vcpu, inst);
         break;
     case EVENT_TAK:
-        perfc_incrc(vmx_tak);
+        perfc_incr(vmx_tak);
         status=vmx_emul_tak(vcpu, inst);
         break;
     case EVENT_MOV_TO_AR_IMM:
-        perfc_incrc(vmx_mov_to_ar_imm);
+        perfc_incr(vmx_mov_to_ar_imm);
         status=vmx_emul_mov_to_ar_imm(vcpu, inst);
         break;
     case EVENT_MOV_TO_AR:
-        perfc_incrc(vmx_mov_to_ar_reg);
+        perfc_incr(vmx_mov_to_ar_reg);
         status=vmx_emul_mov_to_ar_reg(vcpu, inst);
         break;
     case EVENT_MOV_FROM_AR:
-        perfc_incrc(vmx_mov_from_ar_reg);
+        perfc_incr(vmx_mov_from_ar_reg);
         status=vmx_emul_mov_from_ar_reg(vcpu, inst);
         break;
     case EVENT_MOV_TO_DBR:
-        perfc_incrc(vmx_mov_to_dbr);
+        perfc_incr(vmx_mov_to_dbr);
         status=vmx_emul_mov_to_dbr(vcpu, inst);
         break;
     case EVENT_MOV_TO_IBR:
-        perfc_incrc(vmx_mov_to_ibr);
+        perfc_incr(vmx_mov_to_ibr);
         status=vmx_emul_mov_to_ibr(vcpu, inst);
         break;
     case EVENT_MOV_TO_PMC:
-        perfc_incrc(vmx_mov_to_pmc);
+        perfc_incr(vmx_mov_to_pmc);
         status=vmx_emul_mov_to_pmc(vcpu, inst);
         break;
     case EVENT_MOV_TO_PMD:
-        perfc_incrc(vmx_mov_to_pmd);
+        perfc_incr(vmx_mov_to_pmd);
         status=vmx_emul_mov_to_pmd(vcpu, inst);
         break;
     case EVENT_MOV_TO_PKR:
-        perfc_incrc(vmx_mov_to_pkr);
+        perfc_incr(vmx_mov_to_pkr);
         status=vmx_emul_mov_to_pkr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_DBR:
-        perfc_incrc(vmx_mov_from_dbr);
+        perfc_incr(vmx_mov_from_dbr);
         status=vmx_emul_mov_from_dbr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_IBR:
-        perfc_incrc(vmx_mov_from_ibr);
+        perfc_incr(vmx_mov_from_ibr);
         status=vmx_emul_mov_from_ibr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_PMC:
-        perfc_incrc(vmx_mov_from_pmc);
+        perfc_incr(vmx_mov_from_pmc);
         status=vmx_emul_mov_from_pmc(vcpu, inst);
         break;
     case EVENT_MOV_FROM_PKR:
-        perfc_incrc(vmx_mov_from_pkr);
+        perfc_incr(vmx_mov_from_pkr);
         status=vmx_emul_mov_from_pkr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_CPUID:
-        perfc_incrc(vmx_mov_from_cpuid);
+        perfc_incr(vmx_mov_from_cpuid);
         status=vmx_emul_mov_from_cpuid(vcpu, inst);
         break;
     case EVENT_VMSW:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c      Fri Mar 30 17:18:42 2007 -0600
@@ -372,7 +372,7 @@ do_dom0vp_op(unsigned long cmd,
         } else {
             ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
         }
-        perfc_incrc(dom0vp_phystomach);
+        perfc_incr(dom0vp_phystomach);
         break;
     case IA64_DOM0VP_machtophys:
         if (!mfn_valid(arg0)) {
@@ -380,7 +380,7 @@ do_dom0vp_op(unsigned long cmd,
             break;
         }
         ret = get_gpfn_from_mfn(arg0);
-        perfc_incrc(dom0vp_machtophys);
+        perfc_incr(dom0vp_machtophys);
         break;
     case IA64_DOM0VP_zap_physmap:
         ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/domain.c        Fri Mar 30 17:18:42 2007 -0600
@@ -131,11 +131,11 @@ static void flush_vtlb_for_context_switc
                if (vhpt_is_flushed || NEED_FLUSH(__get_cpu_var(tlbflush_time),
                                                  last_tlbflush_timestamp)) {
                        local_flush_tlb_all();
-                       perfc_incrc(tlbflush_clock_cswitch_purge);
+                       perfc_incr(tlbflush_clock_cswitch_purge);
                } else {
-                       perfc_incrc(tlbflush_clock_cswitch_skip);
-               }
-               perfc_incrc(flush_vtlb_for_context_switch);
+                       perfc_incr(tlbflush_clock_cswitch_skip);
+               }
+               perfc_incr(flush_vtlb_for_context_switch);
        }
 }
 
@@ -658,7 +658,7 @@ int arch_set_info_guest(struct vcpu *v, 
                v->arch.iva = er->iva;
        }
 
-       if (test_bit(_VCPUF_initialised, &v->vcpu_flags))
+       if (v->is_initialised)
                return 0;
 
        if (d->arch.is_vti) {
@@ -677,10 +677,12 @@ int arch_set_info_guest(struct vcpu *v, 
        /* This overrides some registers. */
        vcpu_init_regs(v);
 
-       /* Don't redo final setup. Auto-online VCPU0. */
-       if (!test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
-           (v->vcpu_id == 0))
-               clear_bit(_VCPUF_down, &v->vcpu_flags);
+       if (!v->is_initialised) {
+               v->is_initialised = 1;
+               /* Auto-online VCPU0 when it is initialised. */
+               if (v->vcpu_id == 0)
+                       clear_bit(_VPF_down, &v->pause_flags);
+       }
 
        return 0;
 }
@@ -1068,7 +1070,7 @@ int construct_dom0(struct domain *d,
        /* Sanity! */
        BUG_ON(d != dom0);
        BUG_ON(d->vcpu[0] == NULL);
-       BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
+       BUG_ON(v->is_initialised);
 
        printk("*** LOADING DOMAIN 0 ***\n");
 
@@ -1189,8 +1191,8 @@ int construct_dom0(struct domain *d,
 
        printk("Dom0: 0x%lx\n", (u64)dom0);
 
-       set_bit(_VCPUF_initialised, &v->vcpu_flags);
-       clear_bit(_VCPUF_down, &v->vcpu_flags);
+       v->is_initialised = 1;
+       clear_bit(_VPF_down, &v->pause_flags);
 
        /* Build firmware.
           Note: Linux kernel reserve memory used by start_info, so there is
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/faults.c        Fri Mar 30 17:18:42 2007 -0600
@@ -187,7 +187,7 @@ static int handle_lazy_cover(struct vcpu
        if (!PSCB(v, interrupt_collection_enabled)) {
                PSCB(v, ifs) = regs->cr_ifs;
                regs->cr_ifs = 0;
-               perfc_incrc(lazy_cover);
+               perfc_incr(lazy_cover);
                return 1;       // retry same instruction with cr.ifs off
        }
        return 0;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c       Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/fw_emul.c       Fri Mar 30 17:18:42 2007 -0600
@@ -374,7 +374,7 @@ sal_emulator (long index, unsigned long 
                printk("*** CALLED SAL_UPDATE_PAL.  IGNORED...\n");
                break;
            case SAL_XEN_SAL_RETURN:
-               if (!test_and_set_bit(_VCPUF_down, &current->vcpu_flags))
+               if (!test_and_set_bit(_VPF_down, &current->pause_flags))
                        vcpu_sleep_nosync(current);
                break;
            case SN_SAL_GET_MASTER_NASID:
@@ -725,7 +725,7 @@ xen_pal_emulator(unsigned long index, u6
                        console_start_sync();
                        (*efi.reset_system)(EFI_RESET_SHUTDOWN,0,0,NULL);
                } else {
-                       set_bit(_VCPUF_down, &current->vcpu_flags);
+                       set_bit(_VPF_down, &current->pause_flags);
                        vcpu_sleep_nosync(current);
                        status = PAL_STATUS_SUCCESS;
                }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/hypercall.c     Fri Mar 30 17:18:42 2007 -0600
@@ -81,11 +81,11 @@ fw_hypercall_ipi (struct pt_regs *regs)
                return;
 
        if (vector == XEN_SAL_BOOT_RENDEZ_VEC
-           && (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)
-               || test_bit(_VCPUF_down, &targ->vcpu_flags))) {
+           && (!targ->is_initialised
+               || test_bit(_VPF_down, &targ->pause_flags))) {
 
                /* First start: initialize vpcu.  */
-               if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
+               if (!targ->is_initialised) {
                        struct vcpu_guest_context c;
                
                        memset (&c, 0, sizeof (c));
@@ -102,8 +102,8 @@ fw_hypercall_ipi (struct pt_regs *regs)
                vcpu_regs (targ)->r1 = d->arch.sal_data->boot_rdv_r1;
                vcpu_regs (targ)->b0 = FW_HYPERCALL_SAL_RETURN_PADDR;
 
-               if (test_and_clear_bit(_VCPUF_down,
-                                      &targ->vcpu_flags)) {
+               if (test_and_clear_bit(_VPF_down,
+                                      &targ->pause_flags)) {
                        vcpu_wake(targ);
                        printk(XENLOG_INFO "arch_boot_vcpu: vcpu %d awaken\n",
                               targ->vcpu_id);
@@ -112,9 +112,7 @@ fw_hypercall_ipi (struct pt_regs *regs)
                        printk ("arch_boot_vcpu: huu, already awaken!\n");
        }
        else {
-               int running = test_bit(_VCPUF_running,
-                                      &targ->vcpu_flags);
-               
+               int running = targ->is_running;
                vcpu_pend_interrupt(targ, vector);
                vcpu_unblock(targ);
                if (running)
@@ -161,7 +159,7 @@ ia64_hypercall(struct pt_regs *regs)
                if (regs->r28 == PAL_HALT_LIGHT) {
                        if (vcpu_deliverable_interrupts(v) ||
                                event_pending(v)) {
-                               perfc_incrc(idle_when_pending);
+                               perfc_incr(idle_when_pending);
                                vcpu_pend_unspecified_interrupt(v);
 //printk("idle w/int#%d pending!\n",pi);
 //this shouldn't happen, but it apparently does quite a bit!  so don't
@@ -170,7 +168,7 @@ ia64_hypercall(struct pt_regs *regs)
 //as deliver_pending_interrupt is called on the way out and will deliver it
                        }
                        else {
-                               perfc_incrc(pal_halt_light);
+                               perfc_incr(pal_halt_light);
                                migrate_timer(&v->arch.hlt_timer,
                                              v->processor);
                                set_timer(&v->arch.hlt_timer,
@@ -209,7 +207,7 @@ ia64_hypercall(struct pt_regs *regs)
                regs->r10 = x.r10; regs->r11 = x.r11;
                break;
        case FW_HYPERCALL_SAL_RETURN:
-               if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+               if ( !test_and_set_bit(_VPF_down, &v->pause_flags) )
                        vcpu_sleep_nosync(v);
                break;
        case FW_HYPERCALL_EFI_CALL:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S   Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/hyperprivop.S   Fri Mar 30 17:18:42 2007 -0600
@@ -26,8 +26,7 @@
 # define FAST_HYPERPRIVOPS
 # ifdef PERF_COUNTERS
 #  define FAST_HYPERPRIVOP_CNT
-#  define FAST_HYPERPRIVOP_PERFC(N) \
-       (perfcounters + FAST_HYPERPRIVOP_PERFC_OFS + (4 * N))
+#  define FAST_HYPERPRIVOP_PERFC(N) PERFC(fast_hyperprivop + N)
 #  define FAST_REFLECT_CNT
 # endif
        
@@ -364,7 +363,7 @@ GLOBAL_ENTRY(fast_tick_reflect)
        mov rp=r29;;
        mov cr.itm=r26;;        // ensure next tick
 #ifdef FAST_REFLECT_CNT
-       movl r20=perfcounters+FAST_REFLECT_PERFC_OFS+((0x3000>>8)*4);;
+       movl r20=PERFC(fast_reflect + (0x3000>>8));;
        ld4 r21=[r20];;
        adds r21=1,r21;;
        st4 [r20]=r21;;
@@ -597,7 +596,7 @@ END(fast_break_reflect)
 //     r31 == pr
 ENTRY(fast_reflect)
 #ifdef FAST_REFLECT_CNT
-       movl r22=perfcounters+FAST_REFLECT_PERFC_OFS;
+       movl r22=PERFC(fast_reflect);
        shr r23=r20,8-2;;
        add r22=r22,r23;;
        ld4 r21=[r22];;
@@ -938,7 +937,7 @@ 1:  // check the guest VHPT
 (p7)   br.cond.spnt.few page_not_present;;
 
 #ifdef FAST_REFLECT_CNT
-       movl r21=perfcounter+FAST_VHPT_TRANSLATE_PERFC_OFS;;
+       movl r21=PERFC(fast_vhpt_translate);;
        ld4 r22=[r21];;
        adds r22=1,r22;;
        st4 [r21]=r22;;
@@ -968,7 +967,7 @@ END(fast_tlb_miss_reflect)
 // we get here if fast_insert fails (e.g. due to metaphysical lookup)
 ENTRY(recover_and_page_fault)
 #ifdef PERF_COUNTERS
-       movl r21=perfcounters + RECOVER_TO_PAGE_FAULT_PERFC_OFS;;
+       movl r21=PERFC(recover_to_page_fault);;
        ld4 r22=[r21];;
        adds r22=1,r22;;
        st4 [r21]=r22;;
@@ -1832,7 +1831,7 @@ END(hyper_ptc_ga)
 // recovery block for hyper_itc metaphysical memory lookup
 ENTRY(recover_and_dispatch_break_fault)
 #ifdef PERF_COUNTERS
-       movl r21=perfcounters + RECOVER_TO_BREAK_FAULT_PERFC_OFS;;
+       movl r21=PERFC(recover_to_break_fault);;
        ld4 r22=[r21];;
        adds r22=1,r22;;
        st4 [r21]=r22;;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/mm.c    Fri Mar 30 17:18:42 2007 -0600
@@ -400,7 +400,7 @@ share_xen_page_with_guest(struct page_in
     ASSERT(page->count_info == 0);
 
     /* Only add to the allocation list if the domain isn't dying. */
-    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
+    if ( !d->is_dying )
     {
         page->count_info |= PGC_allocated | 1;
         if ( unlikely(d->xenheap_pages++ == 0) )
@@ -1131,7 +1131,7 @@ assign_domain_page_replace(struct domain
             domain_put_page(d, mpaddr, pte, old_pte, 1);
         }
     }
-    perfc_incrc(assign_domain_page_replace);
+    perfc_incr(assign_domain_page_replace);
 }
 
 // caller must get_page(new_page) before
@@ -1207,7 +1207,7 @@ assign_domain_page_cmpxchg_rel(struct do
     }
 
     domain_page_flush_and_put(d, mpaddr, pte, old_pte, old_page);
-    perfc_incrc(assign_domain_pge_cmpxchg_rel);
+    perfc_incr(assign_domain_pge_cmpxchg_rel);
     return 0;
 }
 
@@ -1266,7 +1266,7 @@ zap_domain_page_one(struct domain *d, un
 
     BUG_ON(clear_PGC_allocate && (page_get_owner(page) == NULL));
     domain_put_page(d, mpaddr, pte, old_pte, clear_PGC_allocate);
-    perfc_incrc(zap_dcomain_page_one);
+    perfc_incr(zap_dcomain_page_one);
 }
 
 unsigned long
@@ -1279,7 +1279,7 @@ dom0vp_zap_physmap(struct domain *d, uns
     }
 
     zap_domain_page_one(d, gpfn << PAGE_SHIFT, 1, INVALID_MFN);
-    perfc_incrc(dom0vp_zap_physmap);
+    perfc_incr(dom0vp_zap_physmap);
     return 0;
 }
 
@@ -1333,7 +1333,7 @@ __dom0vp_add_physmap(struct domain* d, u
            get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
     assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags);
     //don't update p2m table because this page belongs to rd, not d.
-    perfc_incrc(dom0vp_add_physmap);
+    perfc_incr(dom0vp_add_physmap);
 out1:
     put_domain(rd);
     return error;
@@ -1503,7 +1503,7 @@ create_grant_host_mapping(unsigned long 
 #endif
                                ((flags & GNTMAP_readonly) ?
                                 ASSIGN_readonly : ASSIGN_writable));
-    perfc_incrc(create_grant_host_mapping);
+    perfc_incr(create_grant_host_mapping);
     return GNTST_okay;
 }
 
@@ -1568,7 +1568,7 @@ destroy_grant_host_mapping(unsigned long
     BUG_ON(pte_pgc_allocated(old_pte));
     domain_page_flush_and_put(d, gpaddr, pte, old_pte, page);
 
-    perfc_incrc(destroy_grant_host_mapping);
+    perfc_incr(destroy_grant_host_mapping);
     return GNTST_okay;
 }
 
@@ -1629,7 +1629,7 @@ steal_page(struct domain *d, struct page
             free_domheap_page(new);
             return -1;
         }
-        perfc_incrc(steal_page_refcount);
+        perfc_incr(steal_page_refcount);
     }
 
     spin_lock(&d->page_alloc_lock);
@@ -1693,7 +1693,7 @@ steal_page(struct domain *d, struct page
     list_del(&page->list);
 
     spin_unlock(&d->page_alloc_lock);
-    perfc_incrc(steal_page);
+    perfc_incr(steal_page);
     return 0;
 }
 
@@ -1710,7 +1710,7 @@ guest_physmap_add_page(struct domain *d,
 
     //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> 
PAGE_SHIFT));
 
-    perfc_incrc(guest_physmap_add_page);
+    perfc_incr(guest_physmap_add_page);
 }
 
 void
@@ -1719,7 +1719,7 @@ guest_physmap_remove_page(struct domain 
 {
     BUG_ON(mfn == 0);//XXX
     zap_domain_page_one(d, gpfn << PAGE_SHIFT, 0, mfn);
-    perfc_incrc(guest_physmap_remove_page);
+    perfc_incr(guest_physmap_remove_page);
 }
 
 static void
@@ -1799,7 +1799,7 @@ domain_page_flush_and_put(struct domain*
         break;
     }
 #endif
-    perfc_incrc(domain_page_flush_and_put);
+    perfc_incr(domain_page_flush_and_put);
 }
 
 int
@@ -1935,8 +1935,7 @@ void put_page_type(struct page_info *pag
          * page-table pages if we detect a referential loop.
          * See domain.c:relinquish_list().
          */
-        ASSERT((x & PGT_validated) ||
-               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
+        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
 
         if ( unlikely((nx & PGT_count_mask) == 0) )
         {
@@ -1996,7 +1995,7 @@ int get_page_type(struct page_info *page
 
                 if ( unlikely(!cpus_empty(mask)) )
                 {
-                    perfc_incrc(need_flush_tlb_flush);
+                    perfc_incr(need_flush_tlb_flush);
                     flush_tlb_mask(mask);
                 }
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/privop.c        Fri Mar 30 17:18:42 2007 -0600
@@ -641,15 +641,15 @@ static IA64FAULT priv_handle_op(VCPU * v
                        if (inst.M29.x3 != 0)
                                break;
                        if (inst.M30.x4 == 8 && inst.M30.x2 == 2) {
-                               perfc_incrc(mov_to_ar_imm);
+                               perfc_incr(mov_to_ar_imm);
                                return priv_mov_to_ar_imm(vcpu, inst);
                        }
                        if (inst.M44.x4 == 6) {
-                               perfc_incrc(ssm);
+                               perfc_incr(ssm);
                                return priv_ssm(vcpu, inst);
                        }
                        if (inst.M44.x4 == 7) {
-                               perfc_incrc(rsm);
+                               perfc_incr(rsm);
                                return priv_rsm(vcpu, inst);
                        }
                        break;
@@ -658,9 +658,9 @@ static IA64FAULT priv_handle_op(VCPU * v
                x6 = inst.M29.x6;
                if (x6 == 0x2a) {
                        if (privify_en && inst.M29.r2 > 63 && inst.M29.ar3 < 8)
-                               perfc_incrc(mov_from_ar); // privified mov from 
kr
+                               perfc_incr(mov_from_ar); // privified mov from 
kr
                        else
-                               perfc_incrc(mov_to_ar_reg);
+                               perfc_incr(mov_to_ar_reg);
                        return priv_mov_to_ar_reg(vcpu, inst);
                }
                if (inst.M29.x3 != 0)
@@ -676,9 +676,9 @@ static IA64FAULT priv_handle_op(VCPU * v
                        }
                }
                if (privify_en && x6 == 52 && inst.M28.r3 > 63)
-                       perfc_incrc(fc);
+                       perfc_incr(fc);
                else if (privify_en && x6 == 16 && inst.M43.r3 > 63)
-                       perfc_incrc(cpuid);
+                       perfc_incr(cpuid);
                else
                        perfc_incra(misc_privop, x6);
                return (*pfunc) (vcpu, inst);
@@ -688,23 +688,23 @@ static IA64FAULT priv_handle_op(VCPU * v
                        break;
                if (inst.B8.x6 == 0x08) {
                        IA64FAULT fault;
-                       perfc_incrc(rfi);
+                       perfc_incr(rfi);
                        fault = priv_rfi(vcpu, inst);
                        if (fault == IA64_NO_FAULT)
                                fault = IA64_RFI_IN_PROGRESS;
                        return fault;
                }
                if (inst.B8.x6 == 0x0c) {
-                       perfc_incrc(bsw0);
+                       perfc_incr(bsw0);
                        return priv_bsw0(vcpu, inst);
                }
                if (inst.B8.x6 == 0x0d) {
-                       perfc_incrc(bsw1);
+                       perfc_incr(bsw1);
                        return priv_bsw1(vcpu, inst);
                }
                if (inst.B8.x6 == 0x0) {
                        // break instr for privified cover
-                       perfc_incrc(cover);
+                       perfc_incr(cover);
                        return priv_cover(vcpu, inst);
                }
                break;
@@ -713,7 +713,7 @@ static IA64FAULT priv_handle_op(VCPU * v
                        break;
 #if 0
                if (inst.I26.x6 == 0 && inst.I26.x3 == 0) {
-                       perfc_incrc(cover);
+                       perfc_incr(cover);
                        return priv_cover(vcpu, inst);
                }
 #endif
@@ -721,13 +721,13 @@ static IA64FAULT priv_handle_op(VCPU * v
                        break;  // I26.x3 == I27.x3
                if (inst.I26.x6 == 0x2a) {
                        if (privify_en && inst.I26.r2 > 63 && inst.I26.ar3 < 8)
-                               perfc_incrc(mov_from_ar);       // privified 
mov from kr
+                               perfc_incr(mov_from_ar);        // privified 
mov from kr
                        else
-                               perfc_incrc(mov_to_ar_reg);
+                               perfc_incr(mov_to_ar_reg);
                        return priv_mov_to_ar_reg(vcpu, inst);
                }
                if (inst.I27.x6 == 0x0a) {
-                       perfc_incrc(mov_to_ar_imm);
+                       perfc_incr(mov_to_ar_imm);
                        return priv_mov_to_ar_imm(vcpu, inst);
                }
                break;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/privop_stat.c
--- a/xen/arch/ia64/xen/privop_stat.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/privop_stat.c   Fri Mar 30 17:18:42 2007 -0600
@@ -10,48 +10,39 @@ struct privop_addr_count {
        unsigned long addr[PRIVOP_COUNT_NADDRS];
        unsigned int count[PRIVOP_COUNT_NADDRS];
        unsigned int overflow;
-       atomic_t *perfc_addr;
-       atomic_t *perfc_count;
-       atomic_t *perfc_overflow;
 };
 
-#undef  PERFCOUNTER
+struct privop_addr_info {
+       enum perfcounter perfc_addr;
+       enum perfcounter perfc_count;
+       enum perfcounter perfc_overflow;
+};
+
 #define PERFCOUNTER(var, name)
-
-#undef  PERFCOUNTER_CPU
-#define PERFCOUNTER_CPU(var, name)
-
-#undef  PERFCOUNTER_ARRAY
 #define PERFCOUNTER_ARRAY(var, name, size)
 
-#undef  PERFSTATUS
 #define PERFSTATUS(var, name)
-
-#undef  PERFSTATUS_CPU
-#define PERFSTATUS_CPU(var, name)
-
-#undef  PERFSTATUS_ARRAY
 #define PERFSTATUS_ARRAY(var, name, size)
 
-#undef PERFPRIVOPADDR
 #define PERFPRIVOPADDR(name)                        \
     {                                               \
-        { 0 }, { 0 }, 0,                            \
-        perfcounters.privop_addr_##name##_addr,     \
-        perfcounters.privop_addr_##name##_count,    \
-        perfcounters.privop_addr_##name##_overflow  \
+        PERFC_privop_addr_##name##_addr,            \
+        PERFC_privop_addr_##name##_count,           \
+        PERFC_privop_addr_##name##_overflow         \
     },
 
-static struct privop_addr_count privop_addr_counter[] = {
+static const struct privop_addr_info privop_addr_info[] = {
 #include <asm/perfc_defn.h>
 };
 
 #define PRIVOP_COUNT_NINSTS \
-        (sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0]))
+        (sizeof(privop_addr_info) / sizeof(privop_addr_info[0]))
+
+static DEFINE_PER_CPU(struct privop_addr_count[PRIVOP_COUNT_NINSTS], 
privop_addr_counter);
 
 void privop_count_addr(unsigned long iip, enum privop_inst inst)
 {
-       struct privop_addr_count *v = &privop_addr_counter[inst];
+       struct privop_addr_count *v = this_cpu(privop_addr_counter) + inst;
        int i;
 
        if (inst >= PRIVOP_COUNT_NINSTS)
@@ -72,31 +63,44 @@ void privop_count_addr(unsigned long iip
 
 void gather_privop_addrs(void)
 {
-       int i, j;
-       atomic_t *v;
-       for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
-               /* Note: addresses are truncated!  */
-               v = privop_addr_counter[i].perfc_addr;
-               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
-                       atomic_set(&v[j], privop_addr_counter[i].addr[j]);
+       unsigned int cpu;
 
-               v = privop_addr_counter[i].perfc_count;
-               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
-                       atomic_set(&v[j], privop_addr_counter[i].count[j]);
+       for_each_cpu ( cpu ) {
+               perfc_t *perfcounters = per_cpu(perfcounters, cpu);
+               struct privop_addr_count *s = per_cpu(privop_addr_counter, cpu);
+               int i, j;
+
+               for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, s++) {
+                       perfc_t *d;
+
+                       /* Note: addresses are truncated!  */
+                       d = perfcounters + privop_addr_info[i].perfc_addr;
+                       for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                               d[j] = s->addr[j];
+
+                       d = perfcounters + privop_addr_info[i].perfc_count;
+                       for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                               d[j] = s->count[j];
                
-               atomic_set(privop_addr_counter[i].perfc_overflow,
-                          privop_addr_counter[i].overflow);
+                       perfcounters[privop_addr_info[i].perfc_overflow] =
+                               s->overflow;
+               }
        }
 }
 
 void reset_privop_addrs(void)
 {
-       int i, j;
-       for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
-               struct privop_addr_count *v = &privop_addr_counter[i];
-               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
-                       v->addr[j] = v->count[j] = 0;
-               v->overflow = 0;
+       unsigned int cpu;
+
+       for_each_cpu ( cpu ) {
+               struct privop_addr_count *v = per_cpu(privop_addr_counter, cpu);
+               int i, j;
+
+               for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, v++) {
+                       for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                               v->addr[j] = v->count[j] = 0;
+                       v->overflow = 0;
+               }
        }
 }
 #endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/tlb_track.c
--- a/xen/arch/ia64/xen/tlb_track.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/tlb_track.c     Fri Mar 30 17:18:42 2007 -0600
@@ -216,14 +216,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
     TLB_TRACK_RET_T ret = TLB_TRACK_NOT_FOUND;
 
 #if 0 /* this is done at vcpu_tlb_track_insert_or_dirty() */
-    perfc_incrc(tlb_track_iod);
+    perfc_incr(tlb_track_iod);
     if (!pte_tlb_tracking(old_pte)) {
-        perfc_incrc(tlb_track_iod_not_tracked);
+        perfc_incr(tlb_track_iod_not_tracked);
         return TLB_TRACK_NOT_TRACKED;
     }
 #endif
     if (pte_tlb_inserted_many(old_pte)) {
-        perfc_incrc(tlb_track_iod_tracked_many);
+        perfc_incr(tlb_track_iod_tracked_many);
         return TLB_TRACK_MANY;
     }
 
@@ -260,7 +260,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
             if (entry->vaddr == vaddr && entry->rid == rid) {
                 // tlb_track_printd("TLB_TRACK_FOUND\n");
                 ret = TLB_TRACK_FOUND;
-                perfc_incrc(tlb_track_iod_found);
+                perfc_incr(tlb_track_iod_found);
 #ifdef CONFIG_TLB_TRACK_CNT
                 entry->cnt++;
                 if (entry->cnt > TLB_TRACK_CNT_FORCE_MANY) {
@@ -276,7 +276,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
                      */
                      // tlb_track_entry_printf(entry);
                      // tlb_track_printd("cnt = %ld\n", entry->cnt);
-                    perfc_incrc(tlb_track_iod_force_many);
+                    perfc_incr(tlb_track_iod_force_many);
                     goto force_many;
                 }
 #endif
@@ -294,14 +294,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
                 if (pte_val(ret_pte) != pte_val(old_pte)) {
                     // tlb_track_printd("TLB_TRACK_AGAIN\n");
                     ret = TLB_TRACK_AGAIN;
-                    perfc_incrc(tlb_track_iod_again);
+                    perfc_incr(tlb_track_iod_again);
                 } else {
                     // tlb_track_printd("TLB_TRACK_MANY del entry 0x%p\n",
                     //                  entry);
                     ret = TLB_TRACK_MANY;
                     list_del(&entry->list);
                     // tlb_track_entry_printf(entry);
-                    perfc_incrc(tlb_track_iod_tracked_many_del);
+                    perfc_incr(tlb_track_iod_tracked_many_del);
                 }
                 goto out;
             }
@@ -314,7 +314,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
          */
         // tlb_track_printd("TLB_TRACK_AGAIN\n");
         ret = TLB_TRACK_AGAIN;
-        perfc_incrc(tlb_track_iod_again);
+        perfc_incr(tlb_track_iod_again);
         goto out;
     }
 
@@ -323,7 +323,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
         /* Other thread else removed the tlb_track_entry after we got old_pte
            before we got spin lock. */
         ret = TLB_TRACK_AGAIN;
-        perfc_incrc(tlb_track_iod_again);
+        perfc_incr(tlb_track_iod_again);
         goto out;
     }
     if (new_entry == NULL && bit_to_be_set == _PAGE_TLB_INSERTED) {
@@ -334,10 +334,10 @@ tlb_track_insert_or_dirty(struct tlb_tra
             /* entry can't be allocated.
                fall down into full flush mode. */
             bit_to_be_set |= _PAGE_TLB_INSERTED_MANY;
-            perfc_incrc(tlb_track_iod_new_failed);
+            perfc_incr(tlb_track_iod_new_failed);
         }
         // tlb_track_printd("new_entry 0x%p\n", new_entry);
-        perfc_incrc(tlb_track_iod_new_entry);
+        perfc_incr(tlb_track_iod_new_entry);
         goto again;
     }
 
@@ -348,7 +348,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
         if (tlb_track_pte_zapped(old_pte, ret_pte)) {
             // tlb_track_printd("zapped TLB_TRACK_AGAIN\n");
             ret = TLB_TRACK_AGAIN;
-            perfc_incrc(tlb_track_iod_again);
+            perfc_incr(tlb_track_iod_again);
             goto out;
         }
 
@@ -359,7 +359,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
             // tlb_track_printd("iserted TLB_TRACK_MANY\n");
             BUG_ON(!pte_tlb_inserted(ret_pte));
             ret = TLB_TRACK_MANY;
-            perfc_incrc(tlb_track_iod_new_many);
+            perfc_incr(tlb_track_iod_new_many);
             goto out;
         }
         BUG_ON(pte_tlb_inserted(ret_pte));
@@ -381,7 +381,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
 #ifdef CONFIG_TLB_TRACK_CNT
         entry->cnt = 0;
 #endif
-        perfc_incrc(tlb_track_iod_insert);
+        perfc_incr(tlb_track_iod_insert);
         // tlb_track_entry_printf(entry);
     } else {
         goto out;
@@ -392,7 +392,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
     cpu_set(v->processor, entry->pcpu_dirty_mask);
     BUG_ON(v->vcpu_id >= NR_CPUS);
     vcpu_set(v->vcpu_id, entry->vcpu_dirty_mask);
-    perfc_incrc(tlb_track_iod_dirtied);
+    perfc_incr(tlb_track_iod_dirtied);
 
  out:
     spin_unlock(&tlb_track->hash_lock);
@@ -432,19 +432,19 @@ tlb_track_search_and_remove(struct tlb_t
     struct list_head* head = tlb_track_hash_head(tlb_track, ptep);
     struct tlb_track_entry* entry;
 
-    perfc_incrc(tlb_track_sar);
+    perfc_incr(tlb_track_sar);
     if (!pte_tlb_tracking(old_pte)) {
-        perfc_incrc(tlb_track_sar_not_tracked);
+        perfc_incr(tlb_track_sar_not_tracked);
         return TLB_TRACK_NOT_TRACKED;
     }
     if (!pte_tlb_inserted(old_pte)) {
         BUG_ON(pte_tlb_inserted_many(old_pte));
-        perfc_incrc(tlb_track_sar_not_found);
+        perfc_incr(tlb_track_sar_not_found);
         return TLB_TRACK_NOT_FOUND;
     }
     if (pte_tlb_inserted_many(old_pte)) {
         BUG_ON(!pte_tlb_inserted(old_pte));
-        perfc_incrc(tlb_track_sar_many);
+        perfc_incr(tlb_track_sar_many);
         return TLB_TRACK_MANY;
     }
 
@@ -475,14 +475,14 @@ tlb_track_search_and_remove(struct tlb_t
                          pte_tlb_inserted(current_pte))) {
                 BUG_ON(pte_tlb_inserted_many(current_pte));
                 spin_unlock(&tlb_track->hash_lock);
-                perfc_incrc(tlb_track_sar_many);
+                perfc_incr(tlb_track_sar_many);
                 return TLB_TRACK_MANY;
             }
 
             list_del(&entry->list);
             spin_unlock(&tlb_track->hash_lock);
             *entryp = entry;
-            perfc_incrc(tlb_track_sar_found);
+            perfc_incr(tlb_track_sar_found);
             // tlb_track_entry_printf(entry);
 #ifdef CONFIG_TLB_TRACK_CNT
             // tlb_track_printd("cnt = %ld\n", entry->cnt);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/vcpu.c  Fri Mar 30 17:18:42 2007 -0600
@@ -1616,7 +1616,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
                        *pteval = (address & _PAGE_PPN_MASK) |
                                __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
                        *itir = PAGE_SHIFT << 2;
-                       perfc_incrc(phys_translate);
+                       perfc_incr(phys_translate);
                        return IA64_NO_FAULT;
                }
        } else if (!region && warn_region0_address) {
@@ -1637,7 +1637,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
                if (trp != NULL) {
                        *pteval = trp->pte.val;
                        *itir = trp->itir;
-                       perfc_incrc(tr_translate);
+                       perfc_incr(tr_translate);
                        return IA64_NO_FAULT;
                }
        }
@@ -1647,7 +1647,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
                if (trp != NULL) {
                        *pteval = trp->pte.val;
                        *itir = trp->itir;
-                       perfc_incrc(tr_translate);
+                       perfc_incr(tr_translate);
                        return IA64_NO_FAULT;
                }
        }
@@ -1660,7 +1660,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
            && vcpu_match_tr_entry_no_p(trp, address, rid)) {
                *pteval = pte.val;
                *itir = trp->itir;
-               perfc_incrc(dtlb_translate);
+               perfc_incr(dtlb_translate);
                return IA64_USE_TLB;
        }
 
@@ -1709,7 +1709,7 @@ out:
 out:
        *itir = rr & RR_PS_MASK;
        *pteval = pte.val;
-       perfc_incrc(vhpt_translate);
+       perfc_incr(vhpt_translate);
        return IA64_NO_FAULT;
 }
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/vhpt.c
--- a/xen/arch/ia64/xen/vhpt.c  Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/vhpt.c  Fri Mar 30 17:18:42 2007 -0600
@@ -48,14 +48,14 @@ local_vhpt_flush(void)
        /* this must be after flush */
        tlbflush_update_time(&__get_cpu_var(vhpt_tlbflush_timestamp),
                             flush_time);
-       perfc_incrc(local_vhpt_flush);
+       perfc_incr(local_vhpt_flush);
 }
 
 void
 vcpu_vhpt_flush(struct vcpu* v)
 {
        __vhpt_flush(vcpu_vhpt_maddr(v));
-       perfc_incrc(vcpu_vhpt_flush);
+       perfc_incr(vcpu_vhpt_flush);
 }
 
 static void
@@ -184,7 +184,7 @@ domain_purge_swtc_entries(struct domain 
 {
        struct vcpu* v;
        for_each_vcpu(d, v) {
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                /* Purge TC entries.
@@ -202,7 +202,7 @@ domain_purge_swtc_entries_vcpu_dirty_mas
 
        for_each_vcpu_mask(vcpu, vcpu_dirty_mask) {
                struct vcpu* v = d->vcpu[vcpu];
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                /* Purge TC entries.
@@ -248,7 +248,7 @@ void vcpu_flush_vtlb_all(struct vcpu *v)
           not running on this processor.  There is currently no easy way to
           check this.  */
 
-       perfc_incrc(vcpu_flush_vtlb_all);
+       perfc_incr(vcpu_flush_vtlb_all);
 }
 
 static void __vcpu_flush_vtlb_all(void *vcpu)
@@ -263,7 +263,7 @@ void domain_flush_vtlb_all(struct domain
        struct vcpu *v;
 
        for_each_vcpu(d, v) {
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                if (v->processor == cpu)
@@ -280,7 +280,7 @@ void domain_flush_vtlb_all(struct domain
                                                 __vcpu_flush_vtlb_all,
                                                 v, 1, 1);
        }
-       perfc_incrc(domain_flush_vtlb_all);
+       perfc_incr(domain_flush_vtlb_all);
 }
 
 // Callers may need to call smp_mb() before/after calling this.
@@ -322,7 +322,7 @@ void vcpu_flush_tlb_vhpt_range (u64 vadr
                                     vadr, 1UL << log_range);
        ia64_ptcl(vadr, log_range << 2);
        ia64_srlz_i();
-       perfc_incrc(vcpu_flush_tlb_vhpt_range);
+       perfc_incr(vcpu_flush_tlb_vhpt_range);
 }
 
 void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
@@ -341,7 +341,7 @@ void domain_flush_vtlb_range (struct dom
        smp_mb();
 
        for_each_vcpu (d, v) {
-               if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+               if (!v->is_initialised)
                        continue;
 
                if (HAS_PERVCPU_VHPT(d)) {
@@ -361,7 +361,7 @@ void domain_flush_vtlb_range (struct dom
 
        /* ptc.ga  */
        platform_global_tlb_purge(vadr, vadr + addr_range, PAGE_SHIFT);
-       perfc_incrc(domain_flush_vtlb_range);
+       perfc_incr(domain_flush_vtlb_range);
 }
 
 #ifdef CONFIG_XEN_IA64_TLB_TRACK
@@ -391,11 +391,11 @@ __domain_flush_vtlb_track_entry(struct d
         */
        vcpu_get_rr(current, VRN7 << VRN_SHIFT, &rr7_rid);
        if (likely(rr7_rid == entry->rid)) {
-               perfc_incrc(tlb_track_use_rr7);
+               perfc_incr(tlb_track_use_rr7);
        } else {
                swap_rr0 = 1;
                vaddr = (vaddr << 3) >> 3;// force vrn0
-               perfc_incrc(tlb_track_swap_rr0);
+               perfc_incr(tlb_track_swap_rr0);
        }
 
        // tlb_track_entry_printf(entry);
@@ -407,7 +407,7 @@ __domain_flush_vtlb_track_entry(struct d
        if (HAS_PERVCPU_VHPT(d)) {
                for_each_vcpu_mask(vcpu, entry->vcpu_dirty_mask) {
                        v = d->vcpu[vcpu];
-                       if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+                       if (!v->is_initialised)
                                continue;
 
                        /* Invalidate VHPT entries.  */
@@ -435,18 +435,18 @@ __domain_flush_vtlb_track_entry(struct d
        /* ptc.ga  */
        if (local_purge) {
                ia64_ptcl(vaddr, PAGE_SHIFT << 2);
-               perfc_incrc(domain_flush_vtlb_local);
+               perfc_incr(domain_flush_vtlb_local);
        } else {
                /* ptc.ga has release semantics. */
                platform_global_tlb_purge(vaddr, vaddr + PAGE_SIZE,
                                          PAGE_SHIFT);
-               perfc_incrc(domain_flush_vtlb_global);
+               perfc_incr(domain_flush_vtlb_global);
        }
 
        if (swap_rr0) {
                vcpu_set_rr(current, 0, old_rid);
        }
-       perfc_incrc(domain_flush_vtlb_track_entry);
+       perfc_incr(domain_flush_vtlb_track_entry);
 }
 
 void
@@ -512,7 +512,7 @@ void gather_vhpt_stats(void)
                for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
                        if (!(v->ti_tag & INVALID_TI_TAG))
                                vhpt_valid++;
-               perfc_seta(vhpt_valid_entries, cpu, vhpt_valid);
-       }
-}
-#endif
+               per_cpu(perfcounters, cpu)[PERFC_vhpt_valid_entries] = 
vhpt_valid;
+       }
+}
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/backtrace.c
--- a/xen/arch/powerpc/backtrace.c      Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/backtrace.c      Fri Mar 30 17:18:42 2007 -0600
@@ -205,21 +205,6 @@ void show_backtrace_regs(struct cpu_user
     console_end_sync();
 }
 
-void __warn(char *file, int line)
-{
-    ulong sp;
-    ulong lr;
-
-    console_start_sync();
-    printk("WARN at %s:%d\n", file, line);
-
-    sp = (ulong)__builtin_frame_address(0);
-    lr = (ulong)__builtin_return_address(0);
-    backtrace(sp, lr, lr);
-
-    console_end_sync();
-}
-
 void dump_execution_state(void)
 {
     struct cpu_user_regs *regs = guest_cpu_user_regs();
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/domain.c Fri Mar 30 17:18:42 2007 -0600
@@ -168,10 +168,13 @@ int arch_set_info_guest(struct vcpu *v, 
     d->shared_info->wc_nsec = dom0->shared_info->wc_nsec;
     d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase;
 
-    /* Auto-online VCPU0 when it is initialised. */
-    if ( !test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
-         (v->vcpu_id == 0) )
-        clear_bit(_VCPUF_down, &v->vcpu_flags);
+    if ( !v->is_initialised )
+    {
+        v->is_initialised = 1;
+        /* Auto-online VCPU0 when it is initialised. */
+        if ( v->vcpu_id == 0 )
+            clear_bit(_VPF_down, &v->pause_flags);
+    }
 
     cpu_init_vcpu(v);
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/domain_build.c
--- a/xen/arch/powerpc/domain_build.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/domain_build.c   Fri Mar 30 17:18:42 2007 -0600
@@ -273,8 +273,8 @@ int construct_dom0(struct domain *d,
 
     ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
 
-    set_bit(_VCPUF_initialised, &v->vcpu_flags);
-    clear_bit(_VCPUF_down, &v->vcpu_flags);
+    v->is_initialised = 1;
+    clear_bit(_VPF_down, &v->pause_flags);
 
     rc = 0;
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/mm.c     Fri Mar 30 17:18:42 2007 -0600
@@ -106,7 +106,7 @@ void share_xen_page_with_guest(
     ASSERT(page->count_info == 0);
 
     /* Only add to the allocation list if the domain isn't dying. */
-    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
+    if ( !d->is_dying )
     {
         page->count_info |= PGC_allocated | 1;
         if ( unlikely(d->xenheap_pages++ == 0) )
@@ -218,8 +218,7 @@ void put_page_type(struct page_info *pag
          * page-table pages if we detect a referential loop.
          * See domain.c:relinquish_list().
          */
-        ASSERT((x & PGT_validated) || 
-               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
+        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
 
         if ( unlikely((nx & PGT_count_mask) == 0) )
         {
@@ -261,7 +260,7 @@ int get_page_type(struct page_info *page
 
                 if ( unlikely(!cpus_empty(mask)) )
                 {
-                    perfc_incrc(need_flush_tlb_flush);
+                    perfc_incr(need_flush_tlb_flush);
                     flush_tlb_mask(mask);
                 }
 
@@ -402,7 +401,7 @@ void free_rma_check(struct page_info *pa
 void free_rma_check(struct page_info *page)
 {
     if (test_bit(_PGC_page_RMA, &page->count_info)) {
-        if (!test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags)) {
+        if (!page_get_owner(page)->is_dying) {
             panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
         } else {
             clear_bit(_PGC_page_RMA, &page->count_info);
@@ -439,8 +438,7 @@ ulong pfn2mfn(struct domain *d, ulong pf
             mfn = d->arch.p2m[pfn];
         }
 #ifdef DEBUG
-        if (t != PFN_TYPE_NONE &&
-            (d->domain_flags & DOMF_dying) &&
+        if (t != PFN_TYPE_NONE && d->is_dying &&
             page_get_owner(mfn_to_page(mfn)) != d) {
             printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
                    __func__, t,
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/Rules.mk     Fri Mar 30 17:18:42 2007 -0600
@@ -59,6 +59,4 @@ HDRS += $(wildcard $(BASEDIR)/include/as
 HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/vmx/*.h)
 
 # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
-ifneq ($(call cc-ver,$(CC),0x030400),y)
-$(error Xen requires at least gcc-3.4)
-endif
+$(call cc-ver-check,CC,0x030400,"Xen requires at least gcc-3.4")
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/apic.c       Fri Mar 30 17:18:42 2007 -0600
@@ -1076,7 +1076,7 @@ fastcall void smp_apic_timer_interrupt(s
 fastcall void smp_apic_timer_interrupt(struct cpu_user_regs * regs)
 {
     ack_APIC_irq();
-    perfc_incrc(apic_timer);
+    perfc_incr(apic_timer);
     raise_softirq(TIMER_SOFTIRQ);
 }
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/domain.c     Fri Mar 30 17:18:42 2007 -0600
@@ -274,7 +274,7 @@ int switch_native(struct domain *d)
     if ( !IS_COMPAT(d) )
         return 0;
 
-    clear_bit(_DOMF_compat, &d->domain_flags);
+    d->is_compat = 0;
     release_arg_xlat_area(d);
 
     /* switch gdt */
@@ -306,7 +306,7 @@ int switch_compat(struct domain *d)
     if ( IS_COMPAT(d) )
         return 0;
 
-    set_bit(_DOMF_compat, &d->domain_flags);
+    d->is_compat = 1;
 
     /* switch gdt */
     gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
@@ -563,9 +563,7 @@ int arch_set_info_guest(
 #endif
     }
 
-    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
-    if ( flags & VGCF_I387_VALID )
-        set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
+    v->fpu_initialised = !!(flags & VGCF_I387_VALID);
 
     v->arch.flags &= ~TF_kernel_mode;
     if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
@@ -600,7 +598,7 @@ int arch_set_info_guest(
         hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
     }
 
-    if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+    if ( v->is_initialised )
         goto out;
 
     memset(v->arch.guest_context.debugreg, 0,
@@ -699,7 +697,7 @@ int arch_set_info_guest(
         update_domain_wallclock_time(d);
 
     /* Don't redo final setup */
-    set_bit(_VCPUF_initialised, &v->vcpu_flags);
+    v->is_initialised = 1;
 
     if ( paging_mode_enabled(d) )
         paging_update_paging_modes(v);
@@ -708,9 +706,9 @@ int arch_set_info_guest(
 
  out:
     if ( flags & VGCF_online )
-        clear_bit(_VCPUF_down, &v->vcpu_flags);
+        clear_bit(_VPF_down, &v->pause_flags);
     else
-        set_bit(_VCPUF_down, &v->vcpu_flags);
+        set_bit(_VPF_down, &v->pause_flags);
     return 0;
 #undef c
 }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/domain_build.c       Fri Mar 30 17:18:42 2007 -0600
@@ -254,7 +254,7 @@ int construct_dom0(struct domain *d,
     /* Sanity! */
     BUG_ON(d->domain_id != 0);
     BUG_ON(d->vcpu[0] == NULL);
-    BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
+    BUG_ON(v->is_initialised);
 
     printk("*** LOADING DOMAIN 0 ***\n");
 
@@ -324,7 +324,7 @@ int construct_dom0(struct domain *d,
     {
         l1_pgentry_t gdt_l1e;
 
-        set_bit(_DOMF_compat, &d->domain_flags);
+        d->is_compat = 1;
         v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
 
         if ( nr_pages != (unsigned int)nr_pages )
@@ -901,8 +901,8 @@ int construct_dom0(struct domain *d,
 
     update_domain_wallclock_time(d);
 
-    set_bit(_VCPUF_initialised, &v->vcpu_flags);
-    clear_bit(_VCPUF_down, &v->vcpu_flags);
+    v->is_initialised = 1;
+    clear_bit(_VPF_down, &v->pause_flags);
 
     /*
      * Initial register values:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/domctl.c     Fri Mar 30 17:18:42 2007 -0600
@@ -448,9 +448,9 @@ void arch_get_info_guest(struct vcpu *v,
 #endif
 
     c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
-    if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
+    if ( v->fpu_initialised )
         c(flags |= VGCF_i387_valid);
-    if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
+    if ( !test_bit(_VPF_down, &v->pause_flags) )
         c(flags |= VGCF_online);
 
     if ( is_hvm_vcpu(v) )
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/extable.c
--- a/xen/arch/x86/extable.c    Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/extable.c    Fri Mar 30 17:18:42 2007 -0600
@@ -72,7 +72,7 @@ search_pre_exception_table(struct cpu_us
     if ( fixup )
     {
         dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
-        perfc_incrc(exception_fixed);
+        perfc_incr(exception_fixed);
     }
     return fixup;
 }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Fri Mar 30 17:18:42 2007 -0600
@@ -59,11 +59,14 @@ struct hvm_function_table hvm_funcs __re
 /* I/O permission bitmap is globally shared by all HVM guests. */
 char __attribute__ ((__section__ (".bss.page_aligned")))
     hvm_io_bitmap[3*PAGE_SIZE];
+/* MSR permission bitmap is globally shared by all HVM guests. */
+char __attribute__ ((__section__ (".bss.page_aligned")))
+    hvm_msr_bitmap[PAGE_SIZE];
 
 void hvm_enable(struct hvm_function_table *fns)
 {
-    if ( hvm_enabled )
-        return;
+    BUG_ON(hvm_enabled);
+    printk("HVM: %s enabled\n", fns->name);
 
     /*
      * Allow direct access to the PC debug port (it is often used for I/O
@@ -72,6 +75,9 @@ void hvm_enable(struct hvm_function_tabl
     memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap));
     clear_bit(0x80, hvm_io_bitmap);
 
+    /* All MSR accesses are intercepted by default. */
+    memset(hvm_msr_bitmap, ~0, sizeof(hvm_msr_bitmap));
+
     hvm_funcs   = *fns;
     hvm_enabled = 1;
 }
@@ -85,7 +91,7 @@ void hvm_stts(struct vcpu *v)
 void hvm_stts(struct vcpu *v)
 {
     /* FPU state already dirty? Then no need to setup_fpu() lazily. */
-    if ( !test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
+    if ( !v->fpu_dirtied )
         hvm_funcs.stts(v);
 }
 
@@ -238,7 +244,7 @@ static int hvm_save_cpu_ctxt(struct doma
     {
         /* We don't need to save state for a vcpu that is down; the restore 
          * code will leave it down if there is nothing saved. */
-        if ( test_bit(_VCPUF_down, &v->vcpu_flags) ) 
+        if ( test_bit(_VPF_down, &v->pause_flags) ) 
             continue;
 
         hvm_funcs.save_cpu_ctxt(v, &ctxt);
@@ -269,7 +275,7 @@ static int hvm_load_cpu_ctxt(struct doma
         return -EINVAL;
 
     /* Auxiliary processors should be woken immediately. */
-    if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+    if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
         vcpu_wake(v);
 
     return 0;
@@ -331,11 +337,11 @@ void hvm_vcpu_reset(struct vcpu *v)
 
     hvm_funcs.vcpu_initialise(v);
 
-    set_bit(_VCPUF_down, &v->vcpu_flags);
-    clear_bit(_VCPUF_initialised, &v->vcpu_flags);
-    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
-    clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
-    clear_bit(_VCPUF_blocked, &v->vcpu_flags);
+    set_bit(_VPF_down, &v->pause_flags);
+    clear_bit(_VPF_blocked, &v->pause_flags);
+    v->fpu_initialised = 0;
+    v->fpu_dirtied     = 0;
+    v->is_initialised  = 0;
 
     vcpu_unpause(v);
 }
@@ -350,13 +356,13 @@ static void hvm_vcpu_down(void)
            d->domain_id, v->vcpu_id);
 
     /* Doesn't halt us immediately, but we'll never return to guest context. */
-    set_bit(_VCPUF_down, &v->vcpu_flags);
+    set_bit(_VPF_down, &v->pause_flags);
     vcpu_sleep_nosync(v);
 
     /* Any other VCPUs online? ... */
     LOCK_BIGLOCK(d);
     for_each_vcpu ( d, v )
-        if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
+        if ( !test_bit(_VPF_down, &v->pause_flags) )
             online_count++;
     UNLOCK_BIGLOCK(d);
 
@@ -556,6 +562,7 @@ static hvm_hypercall_t *hvm_hypercall_ta
     HYPERCALL(multicall),
     HYPERCALL(xen_version),
     HYPERCALL(event_channel_op),
+    HYPERCALL(sched_op),
     HYPERCALL(hvm_op)
 };
 
@@ -722,7 +729,7 @@ int hvm_bringup_ap(int vcpuid, int tramp
 
     LOCK_BIGLOCK(d);
     rc = -EEXIST;
-    if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+    if ( !v->is_initialised )
         rc = boot_vcpu(d, vcpuid, ctxt);
     UNLOCK_BIGLOCK(d);
 
@@ -733,7 +740,7 @@ int hvm_bringup_ap(int vcpuid, int tramp
         goto out;
     }
 
-    if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+    if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
         vcpu_wake(v);
     gdprintk(XENLOG_INFO, "AP %d bringup suceeded.\n", vcpuid);
 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/io.c     Fri Mar 30 17:18:42 2007 -0600
@@ -287,12 +287,18 @@ static void set_reg_value (int size, int
 }
 #endif
 
-extern long get_reg_value(int size, int index, int seg, struct cpu_user_regs 
*regs);
+long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs);
 
 static inline void set_eflags_CF(int size, unsigned long v1,
                                  unsigned long v2, struct cpu_user_regs *regs)
 {
-    unsigned long mask = (1 << (8 * size)) - 1;
+    unsigned long mask;
+
+    if ( size == BYTE_64 )
+        size = BYTE;
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
 
     if ((v1 & mask) > (v2 & mask))
         regs->eflags |= X86_EFLAGS_CF;
@@ -301,14 +307,24 @@ static inline void set_eflags_CF(int siz
 }
 
 static inline void set_eflags_OF(int size, unsigned long v1,
-                                 unsigned long v2, unsigned long v3, struct 
cpu_user_regs *regs)
-{
-    if ((v3 ^ v2) & (v3 ^ v1) & (1 << ((8 * size) - 1)))
+                                 unsigned long v2, unsigned long v3,
+                                 struct cpu_user_regs *regs)
+{
+    unsigned long mask;
+
+    if ( size == BYTE_64 )
+        size = BYTE;
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
+
+    if ((v3 ^ v2) & (v3 ^ v1) & mask)
         regs->eflags |= X86_EFLAGS_OF;
 }
 
 static inline void set_eflags_AF(int size, unsigned long v1,
-                                 unsigned long v2, unsigned long v3, struct 
cpu_user_regs *regs)
+                                 unsigned long v2, unsigned long v3,
+                                 struct cpu_user_regs *regs)
 {
     if ((v1 ^ v2 ^ v3) & 0x10)
         regs->eflags |= X86_EFLAGS_AF;
@@ -317,7 +333,13 @@ static inline void set_eflags_ZF(int siz
 static inline void set_eflags_ZF(int size, unsigned long v1,
                                  struct cpu_user_regs *regs)
 {
-    unsigned long mask = (1 << (8 * size)) - 1;
+    unsigned long mask;
+
+    if ( size == BYTE_64 )
+        size = BYTE;
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
 
     if ((v1 & mask) == 0)
         regs->eflags |= X86_EFLAGS_ZF;
@@ -326,7 +348,15 @@ static inline void set_eflags_SF(int siz
 static inline void set_eflags_SF(int size, unsigned long v1,
                                  struct cpu_user_regs *regs)
 {
-    if (v1 & (1 << ((8 * size) - 1)))
+    unsigned long mask;
+
+    if ( size == BYTE_64 )
+        size = BYTE;
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
+
+    if (v1 & mask)
         regs->eflags |= X86_EFLAGS_SF;
 }
 
@@ -375,14 +405,14 @@ static void hvm_pio_assist(struct cpu_us
                 if ( hvm_paging_enabled(current) )
                 {
                     int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
-                    if ( rv != 0 ) 
+                    if ( rv != 0 )
                     {
                         /* Failed on the page-spanning copy.  Inject PF into
                          * the guest for the address where we failed. */
                         addr += p->size - rv;
                         gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side "
                                  "of a page-spanning PIO: va=%#lx\n", addr);
-                        hvm_inject_exception(TRAP_page_fault, 
+                        hvm_inject_exception(TRAP_page_fault,
                                              PFEC_write_access, addr);
                         return;
                     }
@@ -505,14 +535,14 @@ static void hvm_mmio_assist(struct cpu_u
             if (hvm_paging_enabled(current))
             {
                 int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
-                if ( rv != 0 ) 
+                if ( rv != 0 )
                 {
                     /* Failed on the page-spanning copy.  Inject PF into
                      * the guest for the address where we failed. */
                     addr += p->size - rv;
                     gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side of "
                              "a page-spanning MMIO: va=%#lx\n", addr);
-                    hvm_inject_exception(TRAP_page_fault, 
+                    hvm_inject_exception(TRAP_page_fault,
                                          PFEC_write_access, addr);
                     return;
                 }
@@ -718,14 +748,14 @@ static void hvm_mmio_assist(struct cpu_u
 
     case INSTR_PUSH:
         mmio_opp->addr += hvm_get_segment_base(current, x86_seg_ss);
-        { 
+        {
             unsigned long addr = mmio_opp->addr;
             int rv = hvm_copy_to_guest_virt(addr, &p->data, size);
-            if ( rv != 0 ) 
+            if ( rv != 0 )
             {
                 addr += p->size - rv;
-                gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO: "
-                         "va=%#lx\n", addr);
+                gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO:"
+                         " va=%#lx\n", addr);
                 hvm_inject_exception(TRAP_page_fault, PFEC_write_access, addr);
                 return;
             }
@@ -767,7 +797,7 @@ void hvm_io_assist(struct vcpu *v)
     memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
 
     /* Has memory been dirtied? */
-    if ( p->dir == IOREQ_READ && p->data_is_ptr ) 
+    if ( p->dir == IOREQ_READ && p->data_is_ptr )
     {
         gmfn = get_mfn_from_gpfn(paging_gva_to_gfn(v, p->data));
         mark_dirty(v->domain, gmfn);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/save.c
--- a/xen/arch/x86/hvm/save.c   Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/save.c   Fri Mar 30 17:18:42 2007 -0600
@@ -185,7 +185,7 @@ int hvm_load(struct domain *d, hvm_domai
 
     /* Down all the vcpus: we only re-enable the ones that had state saved. */
     for_each_vcpu(d, v) 
-        if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+        if ( test_and_set_bit(_VPF_down, &v->pause_flags) )
             vcpu_sleep_nosync(v);
 
     while(1) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c    Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/svm/emulate.c    Fri Mar 30 17:18:42 2007 -0600
@@ -373,6 +373,7 @@ MAKE_INSTR(CLTS,   2, 0x0f, 0x06);
 MAKE_INSTR(CLTS,   2, 0x0f, 0x06);
 MAKE_INSTR(LMSW,   3, 0x0f, 0x01, 0x00);
 MAKE_INSTR(SMSW,   3, 0x0f, 0x01, 0x00);
+MAKE_INSTR(INT3,   1, 0xcc);
 
 static const u8 *opc_bytes[INSTR_MAX_COUNT] = 
 {
@@ -405,7 +406,8 @@ static const u8 *opc_bytes[INSTR_MAX_COU
     [INSTR_CLTS]   = OPCODE_CLTS,
     [INSTR_HLT]    = OPCODE_HLT,
     [INSTR_LMSW]   = OPCODE_LMSW,
-    [INSTR_SMSW]   = OPCODE_SMSW
+    [INSTR_SMSW]   = OPCODE_SMSW,
+    [INSTR_INT3]   = OPCODE_INT3
 };
 
 /* 
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/svm/intr.c       Fri Mar 30 17:18:42 2007 -0600
@@ -64,87 +64,73 @@ asmlinkage void svm_intr_assist(void)
 {
     struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    struct periodic_time *pt;
     int intr_type = APIC_DM_EXTINT;
     int intr_vector = -1;
-    int re_injecting = 0;
 
-    /* Check if an Injection is active */
-    /* Previous Interrupt delivery caused this Intercept? */
+    /*
+     * Previous Interrupt delivery caused this intercept?
+     * This will happen if the injection is latched by the processor (hence
+     * clearing vintr.fields.irq) but then subsequently a fault occurs (e.g.,
+     * due to lack of shadow mapping of guest IDT or guest-kernel stack).
+     * 
+     * NB. Exceptions that fault during delivery are lost. This needs to be
+     * fixed but we'll usually get away with it since faults are usually
+     * idempotent. But this isn't the case for e.g. software interrupts!
+     */
     if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) )
     {
-        v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector;
+        intr_vector = vmcb->exitintinfo.fields.vector;
         vmcb->exitintinfo.bytes = 0;
-        re_injecting = 1;
+        HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
+        svm_inject_extint(v, intr_vector);
+        return;
     }
 
-    /* Previous interrupt still pending? */
+    /*
+     * Previous interrupt still pending? This occurs if we return from VMRUN
+     * very early in the entry-to-guest process. Usually this is because an
+     * external physical interrupt was pending when we executed VMRUN.
+     */
     if ( vmcb->vintr.fields.irq )
+        return;
+
+    /* Crank the handle on interrupt state and check for new interrrupts. */
+    pt_update_irq(v);
+    hvm_set_callback_irq_level();
+    if ( !cpu_has_pending_irq(v) )
+        return;
+
+    /*
+     * If the guest can't take an interrupt right now, create a 'fake'
+     * virtual interrupt on to intercept as soon as the guest _can_ take
+     * interrupts.  Do not obtain the next interrupt from the vlapic/pic
+     * if unable to inject.
+     *
+     * Also do this if there is an exception pending.  This is because
+     * the delivery of the exception can arbitrarily delay the injection
+     * of the vintr (for example, if the exception is handled via an
+     * interrupt gate, hence zeroing RFLAGS.IF). In the meantime:
+     * - the vTPR could be modified upwards, so we need to wait until the
+     *   exception is delivered before we can safely decide that an
+     *   interrupt is deliverable; and
+     * - the guest might look at the APIC/PIC state, so we ought not to have 
+     *   cleared the interrupt out of the IRR.
+     */
+    if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow 
+         || vmcb->eventinj.fields.v )  
     {
-        intr_vector = vmcb->vintr.fields.vector;
-        vmcb->vintr.bytes = 0;
-        re_injecting = 1;
-    }
-    /* Pending IRQ saved at last VMExit? */
-    else if ( v->arch.hvm_svm.saved_irq_vector >= 0 )
-    {
-        intr_vector = v->arch.hvm_svm.saved_irq_vector;
-        v->arch.hvm_svm.saved_irq_vector = -1;
-        re_injecting = 1;
-    }
-    /* Now let's check for newer interrrupts  */
-    else
-    {
-        pt_update_irq(v);
-
-        hvm_set_callback_irq_level();
-
-        if ( cpu_has_pending_irq(v) )
-        {
-            /*
-             * Create a 'fake' virtual interrupt on to intercept as soon
-             * as the guest _can_ take interrupts.  Do not obtain the next
-             * interrupt from the vlapic/pic if unable to inject.
-             */
-            if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )  
-            {
-                vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
-                HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
-                svm_inject_extint(v, 0x0); /* actual vector doesn't really 
matter */
-                return;
-            }
-            intr_vector = cpu_get_interrupt(v, &intr_type);
-        }
+        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
+        HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
+        svm_inject_extint(v, 0x0); /* actual vector doesn't matter */
+        return;
     }
 
-    /* have we got an interrupt to inject? */
-    if ( intr_vector < 0 )
-        return;
+    /* Okay, we can deliver the interrupt: grab it and update PIC state. */
+    intr_vector = cpu_get_interrupt(v, &intr_type);
+    BUG_ON(intr_vector < 0);
 
-    switch ( intr_type )
-    {
-    case APIC_DM_EXTINT:
-    case APIC_DM_FIXED:
-    case APIC_DM_LOWEST:
-        /* Re-injecting a PIT interruptt? */
-        if ( re_injecting && (pt = is_pt_irq(v, intr_vector, intr_type)) )
-            ++pt->pending_intr_nr;
-        /* let's inject this interrupt */
-        if (re_injecting)
-            HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
-        else
-            HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
-        svm_inject_extint(v, intr_vector);
-        break;
-    case APIC_DM_SMI:
-    case APIC_DM_NMI:
-    case APIC_DM_INIT:
-    case APIC_DM_STARTUP:
-    default:
-        printk("Unsupported interrupt type: %d\n", intr_type);
-        BUG();
-        break;
-    }
+    HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
+    svm_inject_extint(v, intr_vector);
 
     pt_intr_post(v, intr_vector, intr_type);
 }
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Mar 30 17:18:42 2007 -0600
@@ -15,7 +15,6 @@
  * You should have received a copy of the GNU General Public License along with
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
  */
 
 #include <xen/config.h>
@@ -50,22 +49,15 @@
 #include <asm/hvm/trace.h>
 #include <asm/hap.h>
 
-#define SVM_EXTRA_DEBUG
-
 #define set_segment_register(name, value)  \
-       __asm__ __volatile__ ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
-
-/* External functions. We should move these to some suitable header file(s) */
-
-extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
-                                int inst_len);
-extern asmlinkage void do_IRQ(struct cpu_user_regs *);
-extern void svm_dump_inst(unsigned long eip);
-extern int svm_dbg_on;
-void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
-
-static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
-                                            struct cpu_user_regs *regs);
+    asm volatile ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
+
+int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
+                         int inst_len);
+asmlinkage void do_IRQ(struct cpu_user_regs *);
+
+static int svm_reset_to_realmode(struct vcpu *v,
+                                 struct cpu_user_regs *regs);
 
 /* va of hardware host save area     */
 static void *hsa[NR_CPUS] __read_mostly;
@@ -78,7 +70,6 @@ u64 root_vmcb_pa[NR_CPUS] __read_mostly;
 
 /* hardware assisted paging bits */
 extern int opt_hap_enabled;
-extern int hap_capable_system;
 
 static inline void svm_inject_exception(struct vcpu *v, int trap, 
                                         int ev, int error_code)
@@ -213,7 +204,7 @@ static inline int long_mode_do_msr_write
     switch ( ecx )
     {
     case MSR_EFER:
-        /* offending reserved bit will cause #GP */
+        /* Offending reserved bit will cause #GP. */
         if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
         {
             gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
@@ -221,53 +212,33 @@ static inline int long_mode_do_msr_write
             goto gp_fault;
         }
 
-        /* 
-         * update the VMCB's EFER with the intended value along with
-         * that crucial EFER.SVME bit =)
-         */
-        vmcb->efer = msr_content | EFER_SVME;
-
 #ifdef __x86_64__
-
-        /*
-         * Check for EFER.LME transitions from 0->1 or 1->0.  Do the
-         * sanity checks and then make sure that both EFER.LME and
-         * EFER.LMA are cleared. (EFER.LME can't be set in the vmcb
-         * until the guest also sets CR0.PG, since even if the guest has
-         * paging "disabled", the vmcb's CR0 always has PG set.)
-         */
         if ( (msr_content & EFER_LME) && !svm_lme_is_set(v) )
         {
-            /* EFER.LME transition from 0 to 1 */
-            
-            if ( svm_paging_enabled(v) ||
-                 !svm_cr4_pae_is_set(v) )
+            /* EFER.LME transition from 0 to 1. */
+            if ( svm_paging_enabled(v) || !svm_cr4_pae_is_set(v) )
             {
                 gdprintk(XENLOG_WARNING, "Trying to set LME bit when "
                          "in paging mode or PAE bit is not set\n");
                 goto gp_fault;
             }
-
-            vmcb->efer &= ~(EFER_LME | EFER_LMA);
         }
         else if ( !(msr_content & EFER_LME) && svm_lme_is_set(v) )
         {
-            /* EFER.LME transistion from 1 to 0 */
-            
+            /* EFER.LME transistion from 1 to 0. */
             if ( svm_paging_enabled(v) )
             {
                 gdprintk(XENLOG_WARNING, 
                          "Trying to clear EFER.LME while paging enabled\n");
                 goto gp_fault;
             }
-
+        }
+#endif /* __x86_64__ */
+
+        v->arch.hvm_svm.cpu_shadow_efer = msr_content;
+        vmcb->efer = msr_content | EFER_SVME;
+        if ( !svm_paging_enabled(v) )
             vmcb->efer &= ~(EFER_LME | EFER_LMA);
-        }
-
-#endif /* __x86_64__ */
-
-        /* update the guest EFER's shadow with the intended value */
-        v->arch.hvm_svm.cpu_shadow_efer = msr_content;
 
         break;
 
@@ -324,9 +295,9 @@ static inline int long_mode_do_msr_write
 
 
 #define loaddebug(_v,_reg) \
-    __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
+    asm volatile ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
 #define savedebug(_v,_reg) \
-    __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r" 
((_v)->debugreg[_reg]))
+    asm volatile ("mov %%db" #_reg ",%0" : : "r" ((_v)->debugreg[_reg]))
 
 static inline void svm_save_dr(struct vcpu *v)
 {
@@ -733,7 +704,7 @@ static void svm_stts(struct vcpu *v)
      */
     if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
     {
-        v->arch.hvm_svm.vmcb->exception_intercepts |= EXCEPTION_BITMAP_NM;
+        v->arch.hvm_svm.vmcb->exception_intercepts |= 1U << TRAP_no_device;
         vmcb->cr0 |= X86_CR0_TS;
     }
 }
@@ -749,19 +720,21 @@ static void svm_init_ap_context(
     struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
 {
     struct vcpu *v;
+    struct vmcb_struct *vmcb;
     cpu_user_regs_t *regs;
     u16 cs_sel;
 
     /* We know this is safe because hvm_bringup_ap() does it */
     v = current->domain->vcpu[vcpuid];
+    vmcb = v->arch.hvm_svm.vmcb;
     regs = &v->arch.guest_context.user_regs;
 
     memset(ctxt, 0, sizeof(*ctxt));
 
     /*
      * We execute the trampoline code in real mode. The trampoline vector
-     * passed to us is page alligned and is the physicall frame number for
-     * the code. We will execute this code in real mode. 
+     * passed to us is page alligned and is the physical frame number for
+     * the code. We will execute this code in real mode.
      */
     cs_sel = trampoline_vector << 8;
     ctxt->user_regs.eip = 0x0;
@@ -771,11 +744,11 @@ static void svm_init_ap_context(
      * This is the launch of an AP; set state so that we begin executing
      * the trampoline code in real-mode.
      */
-    svm_do_vmmcall_reset_to_realmode(v, regs);  
+    svm_reset_to_realmode(v, regs);  
     /* Adjust the vmcb's hidden register state. */
-    v->arch.hvm_svm.vmcb->rip = 0;
-    v->arch.hvm_svm.vmcb->cs.sel = cs_sel;
-    v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
+    vmcb->rip = 0;
+    vmcb->cs.sel = cs_sel;
+    vmcb->cs.base = (cs_sel << 4);
 }
 
 static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
@@ -800,74 +773,9 @@ static void svm_init_hypercall_page(stru
     *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
 }
 
-
-int svm_dbg_on = 0;
-
-static inline int svm_do_debugout(unsigned long exit_code)
-{
-    int i;
-
-    static unsigned long counter = 0;
-    static unsigned long works[] =
-    {
-        VMEXIT_IOIO,
-        VMEXIT_HLT,
-        VMEXIT_CPUID,
-        VMEXIT_DR0_READ,
-        VMEXIT_DR1_READ,
-        VMEXIT_DR2_READ,
-        VMEXIT_DR3_READ,
-        VMEXIT_DR6_READ,
-        VMEXIT_DR7_READ,
-        VMEXIT_DR0_WRITE,
-        VMEXIT_DR1_WRITE,
-        VMEXIT_DR2_WRITE,
-        VMEXIT_DR3_WRITE,
-        VMEXIT_CR0_READ,
-        VMEXIT_CR0_WRITE,
-        VMEXIT_CR3_READ,
-        VMEXIT_CR4_READ, 
-        VMEXIT_MSR,
-        VMEXIT_CR0_WRITE,
-        VMEXIT_CR3_WRITE,
-        VMEXIT_CR4_WRITE,
-        VMEXIT_EXCEPTION_PF,
-        VMEXIT_INTR,
-        VMEXIT_INVLPG,
-        VMEXIT_EXCEPTION_NM
-    };
-
-
-#if 0
-    if (svm_dbg_on && exit_code != 0x7B)
-        return 1;
-#endif
-
-    counter++;
-
-#if 0
-    if ((exit_code == 0x4E 
-         || exit_code == VMEXIT_CR0_READ 
-         || exit_code == VMEXIT_CR0_WRITE) 
-        && counter < 200000)
-        return 0;
-
-    if ((exit_code == 0x4E) && counter < 500000)
-        return 0;
-#endif
-
-    for (i = 0; i < sizeof(works) / sizeof(works[0]); i++)
-        if (exit_code == works[i])
-            return 0;
-
-    return 1;
-}
-
 static void save_svm_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *ctxt)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    ASSERT(vmcb);
 
     ctxt->eax = vmcb->rax;
     ctxt->ss = vmcb->ss.sel;
@@ -882,42 +790,16 @@ static void save_svm_cpu_user_regs(struc
     ctxt->ds = vmcb->ds.sel;
 }
 
-static void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    regs->eip    = vmcb->rip;
-    regs->esp    = vmcb->rsp;
-    regs->eflags = vmcb->rflags;
-    regs->cs     = vmcb->cs.sel;
-    regs->ds     = vmcb->ds.sel;
-    regs->es     = vmcb->es.sel;
-    regs->ss     = vmcb->ss.sel;
-}
-
-/* XXX Use svm_load_cpu_guest_regs instead */
-static void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{ 
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    u32 *intercepts = &v->arch.hvm_svm.vmcb->exception_intercepts;
+static void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     
-    /* Write the guest register value into VMCB */
     vmcb->rax      = regs->eax;
     vmcb->ss.sel   = regs->ss;
     vmcb->rsp      = regs->esp;   
     vmcb->rflags   = regs->eflags | 2UL;
     vmcb->cs.sel   = regs->cs;
     vmcb->rip      = regs->eip;
-    if (regs->eflags & EF_TF)
-        *intercepts |= EXCEPTION_BITMAP_DB;
-    else
-        *intercepts &= ~EXCEPTION_BITMAP_DB;
-}
-
-static void svm_load_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *regs)
-{
-    svm_load_cpu_user_regs(v, regs);
 }
 
 static void svm_ctxt_switch_from(struct vcpu *v)
@@ -941,8 +823,20 @@ static void svm_ctxt_switch_to(struct vc
     svm_restore_dr(v);
 }
 
-static void arch_svm_do_resume(struct vcpu *v) 
-{
+static void svm_do_resume(struct vcpu *v) 
+{
+    bool_t debug_state = v->domain->debugger_attached;
+
+    if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
+    {
+        uint32_t mask = (1U << TRAP_debug) | (1U << TRAP_int3);
+        v->arch.hvm_vcpu.debug_state_latch = debug_state;
+        if ( debug_state )
+            v->arch.hvm_svm.vmcb->exception_intercepts |= mask;
+        else
+            v->arch.hvm_svm.vmcb->exception_intercepts &= ~mask;
+    }
+
     if ( v->arch.hvm_svm.launch_core != smp_processor_id() )
     {
         v->arch.hvm_svm.launch_core = smp_processor_id();
@@ -957,11 +851,9 @@ static int svm_vcpu_initialise(struct vc
 {
     int rc;
 
-    v->arch.schedule_tail    = arch_svm_do_resume;
+    v->arch.schedule_tail    = svm_do_resume;
     v->arch.ctxt_switch_from = svm_ctxt_switch_from;
     v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
-
-    v->arch.hvm_svm.saved_irq_vector = -1;
 
     v->arch.hvm_svm.launch_core = -1;
 
@@ -997,6 +889,7 @@ static int svm_event_injection_faulted(s
 }
 
 static struct hvm_function_table svm_function_table = {
+    .name                 = "SVM",
     .disable              = stop_svm,
     .vcpu_initialise      = svm_vcpu_initialise,
     .vcpu_destroy         = svm_vcpu_destroy,
@@ -1026,16 +919,13 @@ void svm_npt_detect(void)
 {
     u32 eax, ebx, ecx, edx;
 
-    /* check CPUID for nested paging support */
+    /* Check CPUID for nested paging support. */
     cpuid(0x8000000A, &eax, &ebx, &ecx, &edx);
-    if ( edx & 0x01 ) /* nested paging */
-    {
-        hap_capable_system = 1;
-    }
-    else if ( opt_hap_enabled )
-    {
-        printk(" nested paging is not supported by this CPU.\n");
-        hap_capable_system = 0; /* no nested paging, we disable flag. */
+
+    if ( !(edx & 1) && opt_hap_enabled )
+    {
+        printk("SVM: Nested paging is not supported by this CPU.\n");
+        opt_hap_enabled = 0;
     }
 }
 
@@ -1050,7 +940,7 @@ int start_svm(void)
     ecx = cpuid_ecx(0x80000001);
     boot_cpu_data.x86_capability[5] = ecx;
     
-    if (!(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)))
+    if ( !(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)) )
         return 0;
 
     /* check whether SVM feature is disabled in BIOS */
@@ -1061,14 +951,13 @@ int start_svm(void)
         return 0;
     }
 
-    if (!hsa[cpu])
-        if (!(hsa[cpu] = alloc_host_save_area()))
-            return 0;
-    
+    if ( ((hsa[cpu] = alloc_host_save_area()) == NULL) ||
+         ((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
+        return 0;
+
     rdmsr(MSR_EFER, eax, edx);
     eax |= EFER_SVME;
     wrmsr(MSR_EFER, eax, edx);
-    printk("AMD SVM Extension is enabled for cpu %d.\n", cpu );
 
     svm_npt_detect();
 
@@ -1077,14 +966,13 @@ int start_svm(void)
     phys_hsa_lo = (u32) phys_hsa;
     phys_hsa_hi = (u32) (phys_hsa >> 32);    
     wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
+
+    root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
   
-    if (!root_vmcb[cpu])
-        if (!(root_vmcb[cpu] = alloc_vmcb())) 
-            return 0;
-    root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
-
-    if (cpu == 0)
-        setup_vmcb_dump();
+    if ( cpu != 0 )
+        return 1;
+
+    setup_vmcb_dump();
 
     hvm_enable(&svm_function_table);
 
@@ -1102,61 +990,15 @@ static int svm_do_nested_pgfault(paddr_t
     return 0;
 }
 
-
-static int svm_do_page_fault(unsigned long va, struct cpu_user_regs *regs) 
-{
-    HVM_DBG_LOG(DBG_LEVEL_VMMU, 
-                "svm_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
-                va, (unsigned long)current->arch.hvm_svm.vmcb->rip,
-                (unsigned long)regs->error_code);
-    return paging_fault(va, regs); 
-}
-
-
 static void svm_do_no_device_fault(struct vmcb_struct *vmcb)
 {
     struct vcpu *v = current;
 
     setup_fpu(v);    
-    vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
+    vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
 
     if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
         vmcb->cr0 &= ~X86_CR0_TS;
-}
-
-
-static void svm_do_general_protection_fault(struct vcpu *v, 
-                                            struct cpu_user_regs *regs) 
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    unsigned long eip, error_code;
-
-    ASSERT(vmcb);
-
-    eip = vmcb->rip;
-    error_code = vmcb->exitinfo1;
-
-    if (vmcb->idtr.limit == 0) {
-        printk("Huh? We got a GP Fault with an invalid IDTR!\n");
-        svm_dump_vmcb(__func__, vmcb);
-        svm_dump_regs(__func__, regs);
-        svm_dump_inst(svm_rip2pointer(v));
-        domain_crash(v->domain);
-        return;
-    }
-
-    HVM_DBG_LOG(DBG_LEVEL_1,
-                "svm_general_protection_fault: eip = %lx, erro_code = %lx",
-                eip, error_code);
-
-    HVM_DBG_LOG(DBG_LEVEL_1, 
-                "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
-                (unsigned long)regs->eax, (unsigned long)regs->ebx,
-                (unsigned long)regs->ecx, (unsigned long)regs->edx,
-                (unsigned long)regs->esi, (unsigned long)regs->edi);
-      
-    /* Reflect it back into the guest */
-    svm_inject_exception(v, TRAP_gp_fault, 1, error_code);
 }
 
 /* Reserved bits ECX: [31:14], [12:4], [2:1]*/
@@ -1171,8 +1013,6 @@ static void svm_vmexit_do_cpuid(struct v
     unsigned int eax, ebx, ecx, edx;
     struct vcpu *v = current;
     int inst_len;
-
-    ASSERT(vmcb);
 
     hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
 
@@ -1305,8 +1145,8 @@ static inline unsigned long *get_reg_p(
 }
 
 
-static inline unsigned long get_reg(unsigned int gpreg, 
-                                    struct cpu_user_regs *regs, struct 
vmcb_struct *vmcb)
+static inline unsigned long get_reg(
+    unsigned int gpreg, struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
 {
     unsigned long *gp;
     gp = get_reg_p(gpreg, regs, vmcb);
@@ -1314,8 +1154,9 @@ static inline unsigned long get_reg(unsi
 }
 
 
-static inline void set_reg(unsigned int gpreg, unsigned long value, 
-                           struct cpu_user_regs *regs, struct vmcb_struct 
*vmcb)
+static inline void set_reg(
+    unsigned int gpreg, unsigned long value, 
+    struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
 {
     unsigned long *gp;
     gp = get_reg_p(gpreg, regs, vmcb);
@@ -1585,7 +1426,6 @@ static void svm_io_instruction(struct vc
     ioio_info_t info;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
-    ASSERT(vmcb);
     pio_opp = &current->arch.hvm_vcpu.io_op;
     pio_opp->instr = INSTR_PIO;
     pio_opp->flags = 0;
@@ -1729,226 +1569,95 @@ static void svm_io_instruction(struct vc
     }
 }
 
-static int npt_set_cr0(unsigned long value) 
+static int svm_set_cr0(unsigned long value)
 {
     struct vcpu *v = current;
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-  
-    ASSERT(vmcb);
-
-    /* ET is reserved and should be always be 1*/
-    value |= X86_CR0_ET;
-
-    /* Check whether the guest is about to turn on long mode. 
-     * If it is, set EFER.LME and EFER.LMA.  Update the shadow EFER.LMA
-     * bit too, so svm_long_mode_enabled() will work.
-     */
-    if ( (value & X86_CR0_PG) && svm_lme_is_set(v) &&
-         (vmcb->cr4 & X86_CR4_PAE) && (vmcb->cr0 & X86_CR0_PE) )
-    {
-        v->arch.hvm_svm.cpu_shadow_efer |= EFER_LMA;
-        vmcb->efer |= EFER_LMA | EFER_LME;
-    }
-
-    /* Whenever CR0.PG is cleared under long mode, LMA will be cleared 
-     * immediatly. We emulate this process for svm_long_mode_enabled().
-     */
-    if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
-    {
-        if ( svm_long_mode_enabled(v) )
-        {
-            v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
-        }
-    }
-    
-    vmcb->cr0 = value | X86_CR0_WP;
-    v->arch.hvm_svm.cpu_shadow_cr0 = value;
-
-    /* TS cleared? Then initialise FPU now. */
-    if ( !(value & X86_CR0_TS) ) {
-        setup_fpu(v);
-        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
-    }
-    
-    paging_update_paging_modes(v);
-    
-    return 1;
-}
-
-static int svm_set_cr0(unsigned long value)
-{
-    struct vcpu *v = current;
-    unsigned long mfn;
-    int paging_enabled;
+    unsigned long mfn, old_value = v->arch.hvm_svm.cpu_shadow_cr0;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     unsigned long old_base_mfn;
   
-    ASSERT(vmcb);
-
-    /* We don't want to lose PG.  ET is reserved and should be always be 1*/
-    paging_enabled = svm_paging_enabled(v);
+    HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
+
+    /* ET is reserved and should be always be 1. */
     value |= X86_CR0_ET;
-    vmcb->cr0 = value | X86_CR0_PG | X86_CR0_WP;
-    v->arch.hvm_svm.cpu_shadow_cr0 = value;
+
+    if ( (value & (X86_CR0_PE|X86_CR0_PG)) == X86_CR0_PG )
+    {
+        svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+        return 0;
+    }
 
     /* TS cleared? Then initialise FPU now. */
     if ( !(value & X86_CR0_TS) )
     {
         setup_fpu(v);
-        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
-    }
-
-    HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
-
-    if ( ((value & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG))
-         && !paging_enabled ) 
-    {
-        /* The guest CR3 must be pointing to the guest physical. */
-        mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
-        if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
-        {
-            gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", 
-                     v->arch.hvm_svm.cpu_cr3, mfn);
-            domain_crash(v->domain);
-            return 0;
-        }
-
+        vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
+    }
+
+    if ( (value & X86_CR0_PG) && !(old_value & X86_CR0_PG) )
+    {
 #if defined(__x86_64__)
-        if ( svm_lme_is_set(v) && !svm_cr4_pae_is_set(v) )
-        {
-            HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
-            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
-        }
-
         if ( svm_lme_is_set(v) )
         {
+            if ( !svm_cr4_pae_is_set(v) )
+            {
+                HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
+                svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+                return 0;
+            }
             HVM_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode\n");
             v->arch.hvm_svm.cpu_shadow_efer |= EFER_LMA;
             vmcb->efer |= EFER_LMA | EFER_LME;
         }
 #endif  /* __x86_64__ */
 
-        /* Now arch.guest_table points to machine physical. */
-        old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-        v->arch.guest_table = pagetable_from_pfn(mfn);
-        if ( old_base_mfn )
-            put_page(mfn_to_page(old_base_mfn));
-        paging_update_paging_modes(v);
-
-        HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
-                    (unsigned long) (mfn << PAGE_SHIFT));
-    }
-
-    if ( !((value & X86_CR0_PE) && (value & X86_CR0_PG)) && paging_enabled )
-        if ( v->arch.hvm_svm.cpu_cr3 ) {
+        if ( !paging_mode_hap(v->domain) )
+        {
+            /* The guest CR3 must be pointing to the guest physical. */
+            mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
+            if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
+            {
+                gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", 
+                         v->arch.hvm_svm.cpu_cr3, mfn);
+                domain_crash(v->domain);
+                return 0;
+            }
+
+            /* Now arch.guest_table points to machine physical. */
+            old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
+            v->arch.guest_table = pagetable_from_pfn(mfn);
+            if ( old_base_mfn )
+                put_page(mfn_to_page(old_base_mfn));
+
+            HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
+                        (unsigned long) (mfn << PAGE_SHIFT));
+        }
+    }
+    else if ( !(value & X86_CR0_PG) && (old_value & X86_CR0_PG) )
+    {
+        /* When CR0.PG is cleared, LMA is cleared immediately. */
+        if ( svm_long_mode_enabled(v) )
+        {
+            vmcb->efer &= ~(EFER_LME | EFER_LMA);
+            v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
+        }
+
+        if ( !paging_mode_hap(v->domain) && v->arch.hvm_svm.cpu_cr3 )
+        {
             put_page(mfn_to_page(get_mfn_from_gpfn(
                 v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT)));
             v->arch.guest_table = pagetable_null();
         }
-
-    /*
-     * SVM implements paged real-mode and when we return to real-mode
-     * we revert back to the physical mappings that the domain builder
-     * created.
-     */
-    if ((value & X86_CR0_PE) == 0) {
-        if (value & X86_CR0_PG) {
-            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
-            return 0;
-        }
+    }
+
+    vmcb->cr0 = v->arch.hvm_svm.cpu_shadow_cr0 = value;
+    if ( !paging_mode_hap(v->domain) )
+        vmcb->cr0 |= X86_CR0_PG | X86_CR0_WP;
+
+    if ( (value ^ old_value) & X86_CR0_PG )
         paging_update_paging_modes(v);
-    }
-    else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
-    {
-        if ( svm_long_mode_enabled(v) )
-        {
-            vmcb->efer &= ~(EFER_LME | EFER_LMA);
-            v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
-        }
-        /* we should take care of this kind of situation */
-        paging_update_paging_modes(v);
-    }
 
     return 1;
-}
-
-//
-// nested paging functions
-//
-
-static int npt_mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
-{  
-    unsigned long value;
-    struct vcpu *v = current;
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    struct vlapic *vlapic = vcpu_vlapic(v);
-
-    ASSERT(vmcb);
-
-    value = get_reg(gpreg, regs, vmcb);
-
-    switch (cr) {
-    case 0:
-        return npt_set_cr0(value);
-
-    case 3:
-        vmcb->cr3 = value;
-        v->arch.hvm_svm.cpu_cr3 = value;
-        break;
-
-    case 4: /* CR4 */
-        vmcb->cr4 = value;
-        v->arch.hvm_svm.cpu_shadow_cr4 = value;
-        paging_update_paging_modes(v);
-        break;
-
-    case 8:
-        vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
-        vmcb->vintr.fields.tpr = value & 0x0F;
-        break;
-
-    default:
-        gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
-        domain_crash(v->domain);
-        return 0;
-    }
-    
-    return 1;
-}
-
-static void npt_mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
-{
-    unsigned long value = 0;
-    struct vcpu *v = current;
-    struct vmcb_struct *vmcb;
-    struct vlapic *vlapic = vcpu_vlapic(v);
-
-    vmcb = v->arch.hvm_svm.vmcb;
-    ASSERT(vmcb);
-
-    switch(cr) {
-    case 0:
-        value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr0;
-        break;
-    case 2:
-        value = vmcb->cr2;
-        break;
-    case 3:
-        value = (unsigned long) v->arch.hvm_svm.cpu_cr3;
-        break;
-    case 4:
-        value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
-       break;
-    case 8:
-        value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
-        value = (value & 0xF0) >> 4;
-        break;
-    default:
-        domain_crash(v->domain);
-        return;
-    }
-    
-    set_reg(gp, value, regs, vmcb);
 }
 
 /*
@@ -1959,30 +1668,21 @@ static void mov_from_cr(int cr, int gp, 
     unsigned long value = 0;
     struct vcpu *v = current;
     struct vlapic *vlapic = vcpu_vlapic(v);
-    struct vmcb_struct *vmcb;
-
-    vmcb = v->arch.hvm_svm.vmcb;
-    ASSERT(vmcb);
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
     switch ( cr )
     {
     case 0:
         value = v->arch.hvm_svm.cpu_shadow_cr0;
-        if (svm_dbg_on)
-            printk("CR0 read =%lx \n", value );
         break;
     case 2:
         value = vmcb->cr2;
         break;
     case 3:
-        value = (unsigned long) v->arch.hvm_svm.cpu_cr3;
-        if (svm_dbg_on)
-            printk("CR3 read =%lx \n", value );
+        value = (unsigned long)v->arch.hvm_svm.cpu_cr3;
         break;
     case 4:
-        value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
-        if (svm_dbg_on)
-            printk("CR4 read=%lx\n", value);
+        value = (unsigned long)v->arch.hvm_svm.cpu_shadow_cr4;
         break;
     case 8:
         value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
@@ -2019,24 +1719,27 @@ static int mov_to_cr(int gpreg, int cr, 
     HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
     HVM_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current);
 
-    switch (cr) 
+    switch ( cr )
     {
     case 0: 
-        if (svm_dbg_on)
-            printk("CR0 write =%lx \n", value );
         return svm_set_cr0(value);
 
-    case 3: 
-        if (svm_dbg_on)
-            printk("CR3 write =%lx \n", value );
+    case 3:
+        if ( paging_mode_hap(v->domain) )
+        {
+            vmcb->cr3 = v->arch.hvm_svm.cpu_cr3 = value;
+            break;
+        }
+
         /* If paging is not enabled yet, simply copy the value to CR3. */
-        if (!svm_paging_enabled(v)) {
+        if ( !svm_paging_enabled(v) )
+        {
             v->arch.hvm_svm.cpu_cr3 = value;
             break;
         }
 
         /* We make a new one if the shadow does not exist. */
-        if (value == v->arch.hvm_svm.cpu_cr3) 
+        if ( value == v->arch.hvm_svm.cpu_cr3 )
         {
             /* 
              * This is simple TLB flush, implying the guest has 
@@ -2044,7 +1747,7 @@ static int mov_to_cr(int gpreg, int cr, 
              * We simply invalidate the shadow.
              */
             mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
-            if (mfn != pagetable_get_pfn(v->arch.guest_table))
+            if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
                 goto bad_cr3;
             paging_update_cr3(v);
         }
@@ -2056,13 +1759,13 @@ static int mov_to_cr(int gpreg, int cr, 
              */
             HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
             mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
-            if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
+            if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
                 goto bad_cr3;
 
             old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
             v->arch.guest_table = pagetable_from_pfn(mfn);
 
-            if (old_base_mfn)
+            if ( old_base_mfn )
                 put_page(mfn_to_page(old_base_mfn));
 
             v->arch.hvm_svm.cpu_cr3 = value;
@@ -2072,9 +1775,13 @@ static int mov_to_cr(int gpreg, int cr, 
         break;
 
     case 4: /* CR4 */
-        if (svm_dbg_on)
-            printk( "write cr4=%lx, cr0=%lx\n", 
-                    value,  v->arch.hvm_svm.cpu_shadow_cr0 );
+        if ( paging_mode_hap(v->domain) )
+        {
+            vmcb->cr4 = v->arch.hvm_svm.cpu_shadow_cr4 = value;
+            paging_update_paging_modes(v);
+            break;
+        }
+
         old_cr = v->arch.hvm_svm.cpu_shadow_cr4;
         if ( value & X86_CR4_PAE && !(old_cr & X86_CR4_PAE) )
         {
@@ -2154,17 +1861,17 @@ static int svm_cr_access(struct vcpu *v,
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     int inst_len = 0;
-    int index;
-    unsigned int gpreg;
-    unsigned long value;
+    int index,addr_size,i;
+    unsigned int gpreg,offset;
+    unsigned long value,addr;
     u8 buffer[MAX_INST_LEN];   
     u8 prefix = 0;
+    u8 modrm;
+    enum x86_segment seg;
     int result = 1;
     enum instruction_index list_a[] = {INSTR_MOV2CR, INSTR_CLTS, INSTR_LMSW};
     enum instruction_index list_b[] = {INSTR_MOVCR2, INSTR_SMSW};
     enum instruction_index match;
-
-    ASSERT(vmcb);
 
     inst_copy_from_guest(buffer, svm_rip2pointer(v), sizeof(buffer));
 
@@ -2197,60 +1904,83 @@ static int svm_cr_access(struct vcpu *v,
     {
     case INSTR_MOV2CR:
         gpreg = decode_src_reg(prefix, buffer[index+2]);
-        if ( paging_mode_hap(v->domain) )
-            result = npt_mov_to_cr(gpreg, cr, regs);
-        else
-            result = mov_to_cr(gpreg, cr, regs);
+        result = mov_to_cr(gpreg, cr, regs);
         break;
 
     case INSTR_MOVCR2:
         gpreg = decode_src_reg(prefix, buffer[index+2]);
-        if ( paging_mode_hap(v->domain) )
-            npt_mov_from_cr(cr, gpreg, regs);
-        else
-            mov_from_cr(cr, gpreg, regs);
+        mov_from_cr(cr, gpreg, regs);
         break;
 
     case INSTR_CLTS:
         /* TS being cleared means that it's time to restore fpu state. */
         setup_fpu(current);
-        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
+        vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
         vmcb->cr0 &= ~X86_CR0_TS; /* clear TS */
         v->arch.hvm_svm.cpu_shadow_cr0 &= ~X86_CR0_TS; /* clear TS */
         break;
 
     case INSTR_LMSW:
-        if (svm_dbg_on)
-            svm_dump_inst(svm_rip2pointer(v));
-        
         gpreg = decode_src_reg(prefix, buffer[index+2]);
         value = get_reg(gpreg, regs, vmcb) & 0xF;
-
-        if (svm_dbg_on)
-            printk("CR0-LMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg, 
-                   inst_len);
-
         value = (v->arch.hvm_svm.cpu_shadow_cr0 & ~0xF) | value;
-
-        if (svm_dbg_on)
-            printk("CR0-LMSW CR0 - New value=%lx\n", value);
-
-        if ( paging_mode_hap(v->domain) )
-            result = npt_set_cr0(value);
+        result = svm_set_cr0(value);
+        break;
+
+    case INSTR_SMSW:
+        value = v->arch.hvm_svm.cpu_shadow_cr0 & 0xFFFF;
+        modrm = buffer[index+2];
+        addr_size = svm_guest_x86_mode( v );
+        if ( likely((modrm & 0xC0) >> 6 == 3) )
+        {
+            gpreg = decode_src_reg(prefix, modrm);
+            set_reg(gpreg, value, regs, vmcb);
+        }
+        /*
+         * For now, only implement decode of the offset mode, since that's the
+         * only mode observed in a real-world OS. This code is also making the
+         * assumption that we'll never hit this code in long mode.
+         */
+        else if ( (modrm == 0x26) || (modrm == 0x25) )
+        {   
+            seg = x86_seg_ds;
+            i = index;
+            /* Segment or address size overrides? */
+            while ( i-- )
+            {
+                switch ( buffer[i] )
+                {
+                   case 0x26: seg = x86_seg_es; break;
+                   case 0x2e: seg = x86_seg_cs; break;
+                   case 0x36: seg = x86_seg_ss; break;
+                   case 0x64: seg = x86_seg_fs; break;
+                   case 0x65: seg = x86_seg_gs; break;
+                   case 0x67: addr_size ^= 6;   break;
+                }
+            }
+            /* Bail unless this really is a seg_base + offset case */
+            if ( ((modrm == 0x26) && (addr_size == 4)) ||
+                 ((modrm == 0x25) && (addr_size == 2)) )
+            {
+                gdprintk(XENLOG_ERR, "SMSW emulation at guest address: "
+                         "%lx failed due to unhandled addressing mode."
+                         "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
+                domain_crash(v->domain);
+            }
+            inst_len += addr_size;
+            offset = *(( unsigned int *) ( void *) &buffer[index + 3]);
+            offset = ( addr_size == 4 ) ? offset : ( offset & 0xFFFF );
+            addr = hvm_get_segment_base(v, seg);
+            addr += offset;
+            hvm_copy_to_guest_virt(addr,&value,2);
+        }
         else
-            result = svm_set_cr0(value);
-        break;
-
-    case INSTR_SMSW:
-        if (svm_dbg_on)
-            svm_dump_inst(svm_rip2pointer(v));
-        value = v->arch.hvm_svm.cpu_shadow_cr0;
-        gpreg = decode_src_reg(prefix, buffer[index+2]);
-        set_reg(gpreg, value, regs, vmcb);
-
-        if (svm_dbg_on)
-            printk("CR0-SMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg, 
-                   inst_len);
+        {
+           gdprintk(XENLOG_ERR, "SMSW emulation at guest address: %lx "
+                    "failed due to unhandled addressing mode!"
+                    "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
+           domain_crash(v->domain);
+        }
         break;
 
     default:
@@ -2271,8 +2001,6 @@ static inline void svm_do_msr_access(
     int  inst_len;
     u64 msr_content=0;
     u32 ecx = regs->ecx, eax, edx;
-
-    ASSERT(vmcb);
 
     HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x, exitinfo = %lx",
                 ecx, (u32)regs->eax, (u32)regs->edx,
@@ -2357,7 +2085,6 @@ static inline void svm_do_msr_access(
     __update_guest_eip(vmcb, inst_len);
 }
 
-
 static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
 {
     __update_guest_eip(vmcb, 1);
@@ -2372,7 +2099,6 @@ static inline void svm_vmexit_do_hlt(str
     HVMTRACE_1D(HLT, current, /*int pending=*/ 0);
     hvm_hlt(vmcb->rflags);
 }
-
 
 static void svm_vmexit_do_invd(struct vcpu *v)
 {
@@ -2387,48 +2113,12 @@ static void svm_vmexit_do_invd(struct vc
     /* Tell the user that we did this - just in case someone runs some really 
      * weird operating system and wants to know why it's not working...
      */
-    printk("INVD instruction intercepted - ignored\n");
+    gdprintk(XENLOG_WARNING, "INVD instruction intercepted - ignored\n");
     
     inst_len = __get_instruction_length(v, INSTR_INVD, NULL);
     __update_guest_eip(vmcb, inst_len);
 }    
         
-
-
-
-#ifdef XEN_DEBUGGER
-static void svm_debug_save_cpu_user_regs(struct vmcb_struct *vmcb, 
-                                         struct cpu_user_regs *regs)
-{
-    regs->eip = vmcb->rip;
-    regs->esp = vmcb->rsp;
-    regs->eflags = vmcb->rflags;
-
-    regs->xcs = vmcb->cs.sel;
-    regs->xds = vmcb->ds.sel;
-    regs->xes = vmcb->es.sel;
-    regs->xfs = vmcb->fs.sel;
-    regs->xgs = vmcb->gs.sel;
-    regs->xss = vmcb->ss.sel;
-}
-
-
-static void svm_debug_restore_cpu_user_regs(struct cpu_user_regs *regs)
-{
-    vmcb->ss.sel   = regs->xss;
-    vmcb->rsp      = regs->esp;
-    vmcb->rflags   = regs->eflags;
-    vmcb->cs.sel   = regs->xcs;
-    vmcb->rip      = regs->eip;
-
-    vmcb->gs.sel = regs->xgs;
-    vmcb->fs.sel = regs->xfs;
-    vmcb->es.sel = regs->xes;
-    vmcb->ds.sel = regs->xds;
-}
-#endif
-
-
 void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
 {
     struct vcpu *v = current;
@@ -2494,18 +2184,11 @@ void svm_handle_invlpg(const short invlp
  *
  * returns 0 on success, non-zero otherwise
  */
-static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v, 
-                                            struct cpu_user_regs *regs)
-{
-    struct vmcb_struct *vmcb;
-
-    ASSERT(v);
-    ASSERT(regs);
-
-    vmcb = v->arch.hvm_svm.vmcb;
-
-    ASSERT(vmcb);
-    
+static int svm_reset_to_realmode(struct vcpu *v, 
+                                 struct cpu_user_regs *regs)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
     /* clear the vmcb and user regs */
     memset(regs, 0, sizeof(struct cpu_user_regs));
    
@@ -2587,449 +2270,65 @@ static int svm_do_vmmcall_reset_to_realm
     return 0;
 }
 
-
-void svm_dump_inst(unsigned long eip)
-{
-    u8 opcode[256];
-    unsigned long ptr;
-    int len;
-    int i;
-
-    ptr = eip & ~0xff;
-    len = 0;
-
-    if (hvm_copy_from_guest_virt(opcode, ptr, sizeof(opcode)) == 0)
-        len = sizeof(opcode);
-
-    printk("Code bytes around(len=%d) %lx:", len, eip);
-    for (i = 0; i < len; i++)
-    {
-        if ((i & 0x0f) == 0)
-            printk("\n%08lx:", ptr+i);
-
-        printk("%02x ", opcode[i]);
-    }
-
-    printk("\n");
-}
-
-
-void svm_dump_regs(const char *from, struct cpu_user_regs *regs)
-{
-    struct vcpu *v = current;
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    unsigned long pt = v->arch.hvm_vcpu.hw_cr3;
-
-    printk("%s: guest registers from %s:\n", __func__, from);
-#if defined (__x86_64__)
-    printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",
-           regs->rax, regs->rbx, regs->rcx);
-    printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
-           regs->rdx, regs->rsi, regs->rdi);
-    printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",
-           regs->rbp, regs->rsp, regs->r8);
-    printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
-           regs->r9,  regs->r10, regs->r11);
-    printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
-           regs->r12, regs->r13, regs->r14);
-    printk("r15: %016lx   cr0: %016lx   cr3: %016lx\n",
-           regs->r15, v->arch.hvm_svm.cpu_shadow_cr0, vmcb->cr3);
-#else
-    printk("eax: %08x, ebx: %08x, ecx: %08x, edx: %08x\n", 
-           regs->eax, regs->ebx, regs->ecx, regs->edx);
-    printk("edi: %08x, esi: %08x, ebp: %08x, esp: %08x\n", 
-           regs->edi, regs->esi, regs->ebp, regs->esp);
-    printk("%s: guest cr0: %lx\n", __func__, 
-           v->arch.hvm_svm.cpu_shadow_cr0);
-    printk("guest CR3 = %llx\n", vmcb->cr3);
-#endif
-    printk("%s: pt = %lx\n", __func__, pt);
-}
-
-
-void svm_dump_host_regs(const char *from)
-{
-    struct vcpu *v = current;
-    unsigned long pt = pt = pagetable_get_paddr(v->arch.monitor_table);
-    unsigned long cr3, cr0;
-    printk("Host registers at %s\n", from);
-
-    __asm__ __volatile__ ("\tmov %%cr0,%0\n"
-                          "\tmov %%cr3,%1\n"
-                          : "=r" (cr0), "=r"(cr3));
-    printk("%s: pt = %lx, cr3 = %lx, cr0 = %lx\n", __func__, pt, cr3, cr0);
-}
-
-#ifdef SVM_EXTRA_DEBUG
-static char *exit_reasons[] = {
-    [VMEXIT_CR0_READ] = "CR0_READ",
-    [VMEXIT_CR1_READ] = "CR1_READ",
-    [VMEXIT_CR2_READ] = "CR2_READ",
-    [VMEXIT_CR3_READ] = "CR3_READ",
-    [VMEXIT_CR4_READ] = "CR4_READ",
-    [VMEXIT_CR5_READ] = "CR5_READ",
-    [VMEXIT_CR6_READ] = "CR6_READ",
-    [VMEXIT_CR7_READ] = "CR7_READ",
-    [VMEXIT_CR8_READ] = "CR8_READ",
-    [VMEXIT_CR9_READ] = "CR9_READ",
-    [VMEXIT_CR10_READ] = "CR10_READ",
-    [VMEXIT_CR11_READ] = "CR11_READ",
-    [VMEXIT_CR12_READ] = "CR12_READ",
-    [VMEXIT_CR13_READ] = "CR13_READ",
-    [VMEXIT_CR14_READ] = "CR14_READ",
-    [VMEXIT_CR15_READ] = "CR15_READ",
-    [VMEXIT_CR0_WRITE] = "CR0_WRITE",
-    [VMEXIT_CR1_WRITE] = "CR1_WRITE",
-    [VMEXIT_CR2_WRITE] = "CR2_WRITE",
-    [VMEXIT_CR3_WRITE] = "CR3_WRITE",
-    [VMEXIT_CR4_WRITE] = "CR4_WRITE",
-    [VMEXIT_CR5_WRITE] = "CR5_WRITE",
-    [VMEXIT_CR6_WRITE] = "CR6_WRITE",
-    [VMEXIT_CR7_WRITE] = "CR7_WRITE",
-    [VMEXIT_CR8_WRITE] = "CR8_WRITE",
-    [VMEXIT_CR9_WRITE] = "CR9_WRITE",
-    [VMEXIT_CR10_WRITE] = "CR10_WRITE",
-    [VMEXIT_CR11_WRITE] = "CR11_WRITE",
-    [VMEXIT_CR12_WRITE] = "CR12_WRITE",
-    [VMEXIT_CR13_WRITE] = "CR13_WRITE",
-    [VMEXIT_CR14_WRITE] = "CR14_WRITE",
-    [VMEXIT_CR15_WRITE] = "CR15_WRITE",
-    [VMEXIT_DR0_READ] = "DR0_READ",
-    [VMEXIT_DR1_READ] = "DR1_READ",
-    [VMEXIT_DR2_READ] = "DR2_READ",
-    [VMEXIT_DR3_READ] = "DR3_READ",
-    [VMEXIT_DR4_READ] = "DR4_READ",
-    [VMEXIT_DR5_READ] = "DR5_READ",
-    [VMEXIT_DR6_READ] = "DR6_READ",
-    [VMEXIT_DR7_READ] = "DR7_READ",
-    [VMEXIT_DR8_READ] = "DR8_READ",
-    [VMEXIT_DR9_READ] = "DR9_READ",
-    [VMEXIT_DR10_READ] = "DR10_READ",
-    [VMEXIT_DR11_READ] = "DR11_READ",
-    [VMEXIT_DR12_READ] = "DR12_READ",
-    [VMEXIT_DR13_READ] = "DR13_READ",
-    [VMEXIT_DR14_READ] = "DR14_READ",
-    [VMEXIT_DR15_READ] = "DR15_READ",
-    [VMEXIT_DR0_WRITE] = "DR0_WRITE",
-    [VMEXIT_DR1_WRITE] = "DR1_WRITE",
-    [VMEXIT_DR2_WRITE] = "DR2_WRITE",
-    [VMEXIT_DR3_WRITE] = "DR3_WRITE",
-    [VMEXIT_DR4_WRITE] = "DR4_WRITE",
-    [VMEXIT_DR5_WRITE] = "DR5_WRITE",
-    [VMEXIT_DR6_WRITE] = "DR6_WRITE",
-    [VMEXIT_DR7_WRITE] = "DR7_WRITE",
-    [VMEXIT_DR8_WRITE] = "DR8_WRITE",
-    [VMEXIT_DR9_WRITE] = "DR9_WRITE",
-    [VMEXIT_DR10_WRITE] = "DR10_WRITE",
-    [VMEXIT_DR11_WRITE] = "DR11_WRITE",
-    [VMEXIT_DR12_WRITE] = "DR12_WRITE",
-    [VMEXIT_DR13_WRITE] = "DR13_WRITE",
-    [VMEXIT_DR14_WRITE] = "DR14_WRITE",
-    [VMEXIT_DR15_WRITE] = "DR15_WRITE",
-    [VMEXIT_EXCEPTION_DE] = "EXCEPTION_DE",
-    [VMEXIT_EXCEPTION_DB] = "EXCEPTION_DB",
-    [VMEXIT_EXCEPTION_NMI] = "EXCEPTION_NMI",
-    [VMEXIT_EXCEPTION_BP] = "EXCEPTION_BP",
-    [VMEXIT_EXCEPTION_OF] = "EXCEPTION_OF",
-    [VMEXIT_EXCEPTION_BR] = "EXCEPTION_BR",
-    [VMEXIT_EXCEPTION_UD] = "EXCEPTION_UD",
-    [VMEXIT_EXCEPTION_NM] = "EXCEPTION_NM",
-    [VMEXIT_EXCEPTION_DF] = "EXCEPTION_DF",
-    [VMEXIT_EXCEPTION_09] = "EXCEPTION_09",
-    [VMEXIT_EXCEPTION_TS] = "EXCEPTION_TS",
-    [VMEXIT_EXCEPTION_NP] = "EXCEPTION_NP",
-    [VMEXIT_EXCEPTION_SS] = "EXCEPTION_SS",
-    [VMEXIT_EXCEPTION_GP] = "EXCEPTION_GP",
-    [VMEXIT_EXCEPTION_PF] = "EXCEPTION_PF",
-    [VMEXIT_EXCEPTION_15] = "EXCEPTION_15",
-    [VMEXIT_EXCEPTION_MF] = "EXCEPTION_MF",
-    [VMEXIT_EXCEPTION_AC] = "EXCEPTION_AC",
-    [VMEXIT_EXCEPTION_MC] = "EXCEPTION_MC",
-    [VMEXIT_EXCEPTION_XF] = "EXCEPTION_XF",
-    [VMEXIT_INTR] = "INTR",
-    [VMEXIT_NMI] = "NMI",
-    [VMEXIT_SMI] = "SMI",
-    [VMEXIT_INIT] = "INIT",
-    [VMEXIT_VINTR] = "VINTR",
-    [VMEXIT_CR0_SEL_WRITE] = "CR0_SEL_WRITE",
-    [VMEXIT_IDTR_READ] = "IDTR_READ",
-    [VMEXIT_GDTR_READ] = "GDTR_READ",
-    [VMEXIT_LDTR_READ] = "LDTR_READ",
-    [VMEXIT_TR_READ] = "TR_READ",
-    [VMEXIT_IDTR_WRITE] = "IDTR_WRITE",
-    [VMEXIT_GDTR_WRITE] = "GDTR_WRITE",
-    [VMEXIT_LDTR_WRITE] = "LDTR_WRITE",
-    [VMEXIT_TR_WRITE] = "TR_WRITE",
-    [VMEXIT_RDTSC] = "RDTSC",
-    [VMEXIT_RDPMC] = "RDPMC",
-    [VMEXIT_PUSHF] = "PUSHF",
-    [VMEXIT_POPF] = "POPF",
-    [VMEXIT_CPUID] = "CPUID",
-    [VMEXIT_RSM] = "RSM",
-    [VMEXIT_IRET] = "IRET",
-    [VMEXIT_SWINT] = "SWINT",
-    [VMEXIT_INVD] = "INVD",
-    [VMEXIT_PAUSE] = "PAUSE",
-    [VMEXIT_HLT] = "HLT",
-    [VMEXIT_INVLPG] = "INVLPG",
-    [VMEXIT_INVLPGA] = "INVLPGA",
-    [VMEXIT_IOIO] = "IOIO",
-    [VMEXIT_MSR] = "MSR",
-    [VMEXIT_TASK_SWITCH] = "TASK_SWITCH",
-    [VMEXIT_FERR_FREEZE] = "FERR_FREEZE",
-    [VMEXIT_SHUTDOWN] = "SHUTDOWN",
-    [VMEXIT_VMRUN] = "VMRUN",
-    [VMEXIT_VMMCALL] = "VMMCALL",
-    [VMEXIT_VMLOAD] = "VMLOAD",
-    [VMEXIT_VMSAVE] = "VMSAVE",
-    [VMEXIT_STGI] = "STGI",
-    [VMEXIT_CLGI] = "CLGI",
-    [VMEXIT_SKINIT] = "SKINIT",
-    [VMEXIT_RDTSCP] = "RDTSCP",
-    [VMEXIT_ICEBP] = "ICEBP",
-    [VMEXIT_NPF] = "NPF"
-};
-#endif /* SVM_EXTRA_DEBUG */
-
-#ifdef SVM_WALK_GUEST_PAGES
-void walk_shadow_and_guest_pt(unsigned long gva)
-{
-    l2_pgentry_t gpde;
-    l2_pgentry_t spde;
-    l1_pgentry_t gpte;
-    l1_pgentry_t spte;
-    struct vcpu        *v    = current;
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    paddr_t gpa;
-
-    gpa = paging_gva_to_gpa(current, gva);
-    printk("gva = %lx, gpa=%"PRIpaddr", gCR3=%x\n", gva, gpa, (u32)vmcb->cr3);
-    if( !svm_paging_enabled(v) || mmio_space(gpa) )
-        return;
-
-    /* let's dump the guest and shadow page info */
-
-    __guest_get_l2e(v, gva, &gpde);
-    printk( "G-PDE = %x, flags=%x\n", gpde.l2, l2e_get_flags(gpde) );
-    __shadow_get_l2e( v, gva, &spde );
-    printk( "S-PDE = %x, flags=%x\n", spde.l2, l2e_get_flags(spde) );
-
-    if ( unlikely(!(l2e_get_flags(gpde) & _PAGE_PRESENT)) )
-        return;
-
-    spte = l1e_empty();
-
-    /* This is actually overkill - we only need to ensure the hl2 is in-sync.*/
-    shadow_sync_va(v, gva);
-
-    gpte.l1 = 0;
-    __copy_from_user(&gpte, &__linear_l1_table[ l1_linear_offset(gva) ],
-                     sizeof(gpte) );
-    printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) );
-
-    BUG(); // need to think about this, and convert usage of
-    // phys_to_machine_mapping to use pagetable format...
-    __copy_from_user( &spte, &phys_to_machine_mapping[ l1e_get_pfn( gpte ) ], 
-                      sizeof(spte) );
-
-    printk( "S-PTE = %x, flags=%x\n", spte.l1, l1e_get_flags(spte));
-}
-#endif /* SVM_WALK_GUEST_PAGES */
-
-
 asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
 {
     unsigned int exit_reason;
     unsigned long eip;
     struct vcpu *v = current;
-    int do_debug = 0;
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    ASSERT(vmcb);
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    int inst_len;
 
     exit_reason = vmcb->exitcode;
     save_svm_cpu_user_regs(v, regs);
 
     HVMTRACE_2D(VMEXIT, v, vmcb->rip, exit_reason);
 
-    if (exit_reason == VMEXIT_INVALID)
+    if ( unlikely(exit_reason == VMEXIT_INVALID) )
     {
         svm_dump_vmcb(__func__, vmcb);
         goto exit_and_crash;
     }
 
-#ifdef SVM_EXTRA_DEBUG
-    {
-#if defined(__i386__)
-#define rip eip
-#endif
-
-        static unsigned long intercepts_counter = 0;
-
-        if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF) 
-        {
-            if (svm_paging_enabled(v) && 
-                !mmio_space(
-                    paging_gva_to_gfn(current, vmcb->exitinfo2) << PAGE_SHIFT))
-            {
-                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
-                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64", "
-                       "gpa=%"PRIx64"\n", intercepts_counter,
-                       exit_reasons[exit_reason], exit_reason, regs->cs,
-                       (u64)regs->rip,
-                       (u64)vmcb->exitinfo1,
-                       (u64)vmcb->exitinfo2,
-                       (u64)vmcb->exitintinfo.bytes,
-                       (((u64)paging_gva_to_gfn(current, vmcb->exitinfo2)
-                        << PAGE_SHIFT) | (vmcb->exitinfo2 & ~PAGE_MASK)));
-            }
-            else 
-            {
-                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
-                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
-                       intercepts_counter,
-                       exit_reasons[exit_reason], exit_reason, regs->cs,
-                       (u64)regs->rip,
-                       (u64)vmcb->exitinfo1,
-                       (u64)vmcb->exitinfo2,
-                       (u64)vmcb->exitintinfo.bytes );
-            }
-        } 
-        else if ( svm_dbg_on 
-                  && exit_reason != VMEXIT_IOIO 
-                  && exit_reason != VMEXIT_INTR) 
-        {
-
-            if (exit_reasons[exit_reason])
-            {
-                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
-                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
-                       intercepts_counter,
-                       exit_reasons[exit_reason], exit_reason, regs->cs,
-                       (u64)regs->rip,
-                       (u64)vmcb->exitinfo1,
-                       (u64)vmcb->exitinfo2,
-                       (u64)vmcb->exitintinfo.bytes);
-            } 
-            else 
-            {
-                printk("I%08ld,ExC=%d(0x%x),IP=%x:%"PRIx64","

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

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