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

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



# HG changeset patch
# User 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


 


Rackspace

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