WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] [xen-unstable] Merge with ia64 xen tree.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge with ia64 xen tree.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 27 Jul 2007 02:59:34 -0700
Delivery-date: Fri, 27 Jul 2007 02:57:50 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1184230438 -3600
# Node ID d0477293897c08c7b95257f20212e8a241626dbf
# Parent  f536eb8576eeb7363212911b02fbaff4918172df
# Parent  a9103c71565e69f79458cc19a920cc17fcba9de2
Merge with ia64 xen tree.
---
 docs/xen-api/xenapi-datamodel.tex                |  477 ++++++++++++-----------
 tools/firmware/hvmloader/acpi/dsdt.asl           |   21 -
 tools/firmware/hvmloader/acpi/dsdt.c             |   25 -
 tools/firmware/hvmloader/config.h                |    2 
 tools/firmware/hvmloader/hvmloader.c             |   12 
 tools/firmware/rombios/rombios.c                 |   48 +-
 tools/ioemu/hw/ide.c                             |    3 
 tools/ioemu/target-i386-dm/exec-dm.c             |    6 
 tools/ioemu/vl.c                                 |    5 
 tools/libxc/xc_domain.c                          |   21 +
 tools/libxc/xenctrl.h                            |   14 
 tools/libxen/include/xen/api/xen_acmpolicy.h     |  117 +++++
 tools/libxen/include/xen/api/xen_vdi.h           |   13 
 tools/libxen/include/xen/api/xen_vm.h            |   14 
 tools/libxen/include/xen/api/xen_xspolicy.h      |  271 +++++++++++++
 tools/libxen/include/xen/api/xen_xspolicy_decl.h |   31 +
 tools/libxen/src/xen_acmpolicy.c                 |  234 +++++++++++
 tools/libxen/src/xen_vdi.c                       |   39 +
 tools/libxen/src/xen_vm.c                        |   45 ++
 tools/libxen/src/xen_xspolicy.c                  |  327 +++++++++++++++
 tools/python/xen/xend/XendDomain.py              |    8 
 tools/python/xen/xm/activatepolicy.py            |   86 ++++
 tools/python/xen/xm/addlabel.py                  |  135 ++++--
 tools/python/xen/xm/cfgbootpolicy.py             |   76 ++-
 tools/python/xen/xm/create.dtd                   |    7 
 tools/python/xen/xm/create.py                    |   22 -
 tools/python/xen/xm/getlabel.py                  |   45 +-
 tools/python/xen/xm/getpolicy.py                 |   94 ++++
 tools/python/xen/xm/labels.py                    |   37 +
 tools/python/xen/xm/loadpolicy.py                |   32 +
 tools/python/xen/xm/main.py                      |   72 ++-
 tools/python/xen/xm/makepolicy.py                |   14 
 tools/python/xen/xm/resources.py                 |   33 +
 tools/python/xen/xm/rmlabel.py                   |   65 ++-
 tools/python/xen/xm/setpolicy.py                 |  117 +++++
 tools/python/xen/xm/xenapi_create.py             |   55 ++
 tools/vtpm_manager/util/hashtable_itr.c          |    8 
 tools/xenstore/xsls.c                            |   37 +
 xen/arch/ia64/linux-xen/perfmon.c                |    2 
 xen/arch/ia64/xen/oprofile/perfmon.c             |   11 
 xen/arch/x86/acpi/Makefile                       |    1 
 xen/arch/x86/acpi/power.c                        |  273 +++++++++++++
 xen/arch/x86/acpi/suspend.c                      |   85 ++++
 xen/arch/x86/acpi/wakeup_prot.S                  |  267 ++++++++++++
 xen/arch/x86/apic.c                              |    2 
 xen/arch/x86/boot/Makefile                       |    3 
 xen/arch/x86/boot/head.S                         |    2 
 xen/arch/x86/boot/wakeup.S                       |  212 ++++++++++
 xen/arch/x86/cpu/common.c                        |    8 
 xen/arch/x86/dmi_scan.c                          |    1 
 xen/arch/x86/domain.c                            |   27 +
 xen/arch/x86/e820.c                              |   71 +--
 xen/arch/x86/hvm/hvm.c                           |    3 
 xen/arch/x86/hvm/svm/svm.c                       |    7 
 xen/arch/x86/hvm/vlapic.c                        |    9 
 xen/arch/x86/hvm/vmx/vmcs.c                      |  178 +++++---
 xen/arch/x86/hvm/vmx/vmx.c                       |   20 
 xen/arch/x86/i8259.c                             |    3 
 xen/arch/x86/io_apic.c                           |    3 
 xen/arch/x86/irq.c                               |   33 +
 xen/arch/x86/nmi.c                               |    2 
 xen/arch/x86/oprofile/nmi_int.c                  |   83 +---
 xen/arch/x86/platform_hypercall.c                |   17 
 xen/arch/x86/smpboot.c                           |  336 +++++++++++++++-
 xen/arch/x86/x86_32/traps.c                      |    2 
 xen/arch/x86/x86_64/traps.c                      |    2 
 xen/common/page_alloc.c                          |   20 
 xen/common/sysctl.c                              |   14 
 xen/common/xenoprof.c                            |   52 +-
 xen/drivers/char/ns16550.c                       |    4 
 xen/drivers/char/serial.c                        |    4 
 xen/include/asm-ia64/xenoprof.h                  |    2 
 xen/include/asm-x86/acpi.h                       |    8 
 xen/include/asm-x86/config.h                     |   10 
 xen/include/asm-x86/desc.h                       |    5 
 xen/include/asm-x86/hvm/hvm.h                    |   20 
 xen/include/asm-x86/hvm/vmx/vmcs.h               |    3 
 xen/include/asm-x86/smp.h                        |   13 
 xen/include/asm-x86/system.h                     |    2 
 xen/include/asm-x86/xenoprof.h                   |    4 
 xen/include/public/platform.h                    |   27 +
 xen/include/public/sysctl.h                      |   13 
 xen/include/xen/irq.h                            |   10 
 xen/include/xen/mm.h                             |    2 
 xen/include/xen/xenoprof.h                       |    2 
 85 files changed, 3842 insertions(+), 704 deletions(-)

diff -r f536eb8576ee -r d0477293897c docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Wed Jul 11 11:32:30 2007 -0600
+++ b/docs/xen-api/xenapi-datamodel.tex Thu Jul 12 09:53:58 2007 +0100
@@ -225,6 +225,249 @@ The following enumeration types are used
 \end{longtable}
 
 \vspace{1cm}
+\newpage
+\section{Error Handling}
+When a low-level transport error occurs, or a request is malformed at the HTTP
+or XML-RPC level, the server may send an XML-RPC Fault response, or the client
+may simulate the same.  The client must be prepared to handle these errors,
+though they may be treated as fatal.  On the wire, these are transmitted in a
+form similar to this:
+
+\begin{verbatim}
+    <methodResponse>
+      <fault>
+        <value>
+          <struct>
+            <member>
+                <name>faultCode</name>
+                <value><int>-1</int></value>
+              </member>
+              <member>
+                <name>faultString</name>
+                <value><string>Malformed request</string></value>
+            </member>
+          </struct>
+        </value>
+      </fault>
+    </methodResponse>
+\end{verbatim}
+
+All other failures are reported with a more structured error response, to
+allow better automatic response to failures, proper internationalisation of
+any error message, and easier debugging.  On the wire, these are transmitted
+like this:
+
+\begin{verbatim}
+    <struct>
+      <member>
+        <name>Status</name>
+        <value>Failure</value>
+      </member>
+      <member>
+        <name>ErrorDescription</name>
+        <value>
+          <array>
+            <data>
+              <value>MAP_DUPLICATE_KEY</value>
+              <value>Customer</value>
+              <value>eSpeil Inc.</value>
+              <value>eSpeil Incorporated</value>
+            </data>
+          </array>
+        </value>
+      </member>
+    </struct>
+\end{verbatim}
+
+Note that {\tt ErrorDescription} value is an array of string values. The
+first element of the array is an error code; the remainder of the array are
+strings representing error parameters relating to that code.  In this case,
+the client has attempted to add the mapping {\tt Customer $\rightarrow$
+eSpiel Incorporated} to a Map, but it already contains the mapping
+{\tt Customer $\rightarrow$ eSpiel Inc.}, and so the request has failed.
+
+The reference below lists each possible error returned by each method.
+As well as the errors explicitly listed, any method may return low-level
+errors as described above, or any of the following generic errors:
+
+\begin{itemize}
+\item HANDLE\_INVALID
+\item INTERNAL\_ERROR
+\item MAP\_DUPLICATE\_KEY
+\item MESSAGE\_METHOD\_UNKNOWN
+\item MESSAGE\_PARAMETER\_COUNT\_MISMATCH
+\item OPERATION\_NOT\_ALLOWED
+\item PERMISSION\_DENIED
+\item SESSION\_INVALID
+\end{itemize}
+
+Each possible error code is documented in the following section.
+
+\subsection{Error Codes}
+
+\subsubsection{HANDLE\_INVALID}
+
+You gave an invalid handle.  The object may have recently been deleted. 
+The class parameter gives the type of reference given, and the handle
+parameter echoes the bad value given.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}HANDLE_INVALID(class, handle)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{INTERNAL\_ERROR}
+
+The server failed to handle your request, due to an internal error.  The
+given message may give details useful for debugging the problem.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}INTERNAL_ERROR(message)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{MAP\_DUPLICATE\_KEY}
+
+You tried to add a key-value pair to a map, but that key is already there. 
+The key, current value, and the new value that you tried to set are all
+echoed.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}MAP_DUPLICATE_KEY(key, current value, new value)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{MESSAGE\_METHOD\_UNKNOWN}
+
+You tried to call a method that does not exist.  The method name that you
+used is echoed.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}MESSAGE_METHOD_UNKNOWN(method)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{MESSAGE\_PARAMETER\_COUNT\_MISMATCH}
+
+You tried to call a method with the incorrect number of parameters.  The
+fully-qualified method name that you used, and the number of received and
+expected parameters are returned.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}MESSAGE_PARAMETER_COUNT_MISMATCH(method, expected, 
received)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{NETWORK\_ALREADY\_CONNECTED}
+
+You tried to create a PIF, but the network you tried to attach it to is
+already attached to some other PIF, and so the creation failed.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}NETWORK_ALREADY_CONNECTED(network, connected PIF)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{OPERATION\_NOT\_ALLOWED}
+
+You attempted an operation that was not allowed.
+
+\vspace{0.3cm}
+No parameters.
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{PERMISSION\_DENIED}
+
+You do not have the required permissions to perform the operation.
+
+\vspace{0.3cm}
+No parameters.
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{PIF\_IS\_PHYSICAL}
+
+You tried to destroy a PIF, but it represents an aspect of the physical
+host configuration, and so cannot be destroyed.  The parameter echoes the
+PIF handle you gave.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}PIF_IS_PHYSICAL(PIF)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{SESSION\_AUTHENTICATION\_FAILED}
+
+The credentials given by the user are incorrect, so access has been denied,
+and you have not been issued a session handle.
+
+\vspace{0.3cm}
+No parameters.
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{SESSION\_INVALID}
+
+You gave an invalid session handle.  It may have been invalidated by a
+server restart, or timed out.  You should get a new session handle, using
+one of the session.login\_ calls.  This error does not invalidate the
+current connection.  The handle parameter echoes the bad value given.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\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. 
+The fully-qualified field name and the value that you tried to set are
+returned.  Also returned is a developer-only diagnostic reason.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}VALUE_NOT_SUPPORTED(field, value, reason)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{VLAN\_TAG\_INVALID}
+
+You tried to create a VLAN, but the tag you gave was invalid -- it mmust be
+between 0 and 4095.  The parameter echoes the VLAN tag you gave.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}VLAN_TAG_INVALID(VLAN)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{VM\_BAD\_POWER\_STATE}
+
+You attempted an operation on a VM that was not in an appropriate power
+state at the time; for example, you attempted to start a VM that was
+already running.  The parameters returned are the VM's handle, and the
+expected and actual VM state at the time of the call.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}VM_BAD_POWER_STATE(vm, expected, actual)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
+\subsubsection{VM\_HVM\_REQUIRED}
+
+HVM is required for this operation
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}VM_HVM_REQUIRED(vm)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
 
 \newpage
 \section{Class: session}
@@ -275,6 +518,11 @@ session ref
 
 
 ID of newly created session
+
+\vspace{0.3cm}
+
+\noindent{\bf Possible Error Codes:} {\tt SESSION\_AUTHENTICATION\_FAILED}
+
 \vspace{0.3cm}
 \vspace{0.3cm}
 \vspace{0.3cm}
@@ -7100,7 +7348,9 @@ value of the field
 \subsubsection{RPC name:~get\_flags}
 
 {\bf Overview:} 
-Get the flags field of the given host\_cpu.
+Get the flags field of the given host\_cpu.  As of this version of the
+API, the semantics of the returned string are explicitly unspecified,
+and may change in the future.
 
  \noindent {\bf Signature:} 
 \begin{verbatim} string get_flags (session_id s, host_cpu ref 
self)\end{verbatim}
@@ -7132,7 +7382,9 @@ value of the field
 \subsubsection{RPC name:~get\_features}
 
 {\bf Overview:} 
-Get the features field of the given host\_cpu.
+Get the features field of the given host\_cpu. As of this version of the
+API, the semantics of the returned string are explicitly unspecified,
+and may change in the future.
 
  \noindent {\bf Signature:} 
 \begin{verbatim} string get_features (session_id s, host_cpu ref 
self)\end{verbatim}
@@ -14192,224 +14444,3 @@ all fields from the object
 \vspace{0.3cm}
 \vspace{0.3cm}
 
-\vspace{1cm}
-\newpage
-\section{Error Handling}
-When a low-level transport error occurs, or a request is malformed at the HTTP
-or XML-RPC level, the server may send an XML-RPC Fault response, or the client
-may simulate the same.  The client must be prepared to handle these errors,
-though they may be treated as fatal.  On the wire, these are transmitted in a
-form similar to this:
-
-\begin{verbatim}
-    <methodResponse>
-      <fault>
-        <value>
-          <struct>
-            <member>
-                <name>faultCode</name>
-                <value><int>-1</int></value>
-              </member>
-              <member>
-                <name>faultString</name>
-                <value><string>Malformed request</string></value>
-            </member>
-          </struct>
-        </value>
-      </fault>
-    </methodResponse>
-\end{verbatim}
-
-All other failures are reported with a more structured error response, to
-allow better automatic response to failures, proper internationalisation of
-any error message, and easier debugging.  On the wire, these are transmitted
-like this:
-
-\begin{verbatim}
-    <struct>
-      <member>
-        <name>Status</name>
-        <value>Failure</value>
-      </member>
-      <member>
-        <name>ErrorDescription</name>
-        <value>
-          <array>
-            <data>
-              <value>MAP_DUPLICATE_KEY</value>
-              <value>Customer</value>
-              <value>eSpeil Inc.</value>
-              <value>eSpeil Incorporated</value>
-            </data>
-          </array>
-        </value>
-      </member>
-    </struct>
-\end{verbatim}
-
-Note that {\tt ErrorDescription} value is an array of string values. The
-first element of the array is an error code; the remainder of the array are
-strings representing error parameters relating to that code.  In this case,
-the client has attempted to add the mapping {\tt Customer $\rightarrow$
-eSpiel Incorporated} to a Map, but it already contains the mapping
-{\tt Customer $\rightarrow$ eSpiel Inc.}, and so the request has failed.
-
-Each possible error code is documented in the following section.
-
-\subsection{Error Codes}
-
-\subsubsection{HANDLE\_INVALID}
-
-You gave an invalid handle.  The object may have recently been deleted. 
-The class parameter gives the type of reference given, and the handle
-parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}HANDLE_INVALID(class, handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{INTERNAL\_ERROR}
-
-The server failed to handle your request, due to an internal error.  The
-given message may give details useful for debugging the problem.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}INTERNAL_ERROR(message)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{MAP\_DUPLICATE\_KEY}
-
-You tried to add a key-value pair to a map, but that key is already there. 
-The key, current value, and the new value that you tried to set are all
-echoed.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}MAP_DUPLICATE_KEY(key, current value, new value)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{MESSAGE\_METHOD\_UNKNOWN}
-
-You tried to call a method that does not exist.  The method name that you
-used is echoed.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}MESSAGE_METHOD_UNKNOWN(method)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{MESSAGE\_PARAMETER\_COUNT\_MISMATCH}
-
-You tried to call a method with the incorrect number of parameters.  The
-fully-qualified method name that you used, and the number of received and
-expected parameters are returned.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}MESSAGE_PARAMETER_COUNT_MISMATCH(method, expected, 
received)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{NETWORK\_ALREADY\_CONNECTED}
-
-You tried to create a PIF, but the network you tried to attach it to is
-already attached to some other PIF, and so the creation failed.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}NETWORK_ALREADY_CONNECTED(network, connected PIF)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{OPERATION\_NOT\_ALLOWED}
-
-You attempted an operation that was not allowed.
-
-\vspace{0.3cm}
-No parameters.
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{PIF\_IS\_PHYSICAL}
-
-You tried to destroy a PIF, but it represents an aspect of the physical
-host configuration, and so cannot be destroyed.  The parameter echoes the
-PIF handle you gave.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}PIF_IS_PHYSICAL(PIF)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{SESSION\_AUTHENTICATION\_FAILED}
-
-The credentials given by the user are incorrect, so access has been denied,
-and you have not been issued a session handle.
-
-\vspace{0.3cm}
-No parameters.
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{SESSION\_INVALID}
-
-You gave an invalid session handle.  It may have been invalidated by a
-server restart, or timed out.  You should get a new session handle, using
-one of the session.login\_ calls.  This error does not invalidate the
-current connection.  The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\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. 
-The fully-qualified field name and the value that you tried to set are
-returned.  Also returned is a developer-only diagnostic reason.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VALUE_NOT_SUPPORTED(field, value, reason)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VLAN\_TAG\_INVALID}
-
-You tried to create a VLAN, but the tag you gave was invalid -- it mmust be
-between 0 and 4095.  The parameter echoes the VLAN tag you gave.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VLAN_TAG_INVALID(VLAN)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VM\_BAD\_POWER\_STATE}
-
-You attempted an operation on a VM that was not in an appropriate power
-state at the time; for example, you attempted to start a VM that was
-already running.  The parameters returned are the VM's handle, and the
-expected and actual VM state at the time of the call.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VM_BAD_POWER_STATE(vm, expected, actual)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VM\_HVM\_REQUIRED}
-
-HVM is required for this operation
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VM_HVM_REQUIRED(vm)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
diff -r f536eb8576ee -r d0477293897c tools/firmware/hvmloader/acpi/dsdt.asl
--- a/tools/firmware/hvmloader/acpi/dsdt.asl    Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl    Thu Jul 12 09:53:58 2007 +0100
@@ -123,11 +123,12 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
             }
 
             Name(BUFA, ResourceTemplate() {
-                IRQ(Level, ActiveLow, Shared) { 5, 7, 10, 11 }
+                IRQ(Level, ActiveLow, Shared) { 5, 10, 11 }
             })
 
             Name(BUFB, Buffer() {
-                0x23, 0x00, 0x00, 0x18, 0x79, 0
+                0x23, 0x00, 0x00, 0x18, /* IRQ descriptor */
+                0x79, 0                 /* End tag, null checksum */
             })
 
             CreateWordField(BUFB, 0x01, IRQV)
@@ -643,6 +644,22 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
                         IRQNoFlags () {4}
                     })
                 }
+
+                Device (LTP1)
+                {
+                    Name (_HID, EisaId ("PNP0400"))
+                    Name (_UID, 0x02)
+                    Method (_STA, 0, NotSerialized)
+                    {
+                        Return (0x0F)
+                    }
+
+                    Name (_CRS, ResourceTemplate()
+                    {
+                        IO (Decode16, 0x0378, 0x0378, 0x08, 0x08)
+                        IRQNoFlags () {7}
+                    })
+                } 
             }
         }
     }
diff -r f536eb8576ee -r d0477293897c tools/firmware/hvmloader/acpi/dsdt.c
--- a/tools/firmware/hvmloader/acpi/dsdt.c      Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/firmware/hvmloader/acpi/dsdt.c      Thu Jul 12 09:53:58 2007 +0100
@@ -1,19 +1,19 @@
 /*
  * 
  * Intel ACPI Component Architecture
- * ASL Optimizing Compiler version 20060707 [Dec 30 2006]
+ * ASL Optimizing Compiler version 20060707 [Feb 16 2007]
  * Copyright (C) 2000 - 2006 Intel Corporation
  * Supports ACPI Specification Revision 3.0a
  * 
- * Compilation of "dsdt.asl" - Sat May 12 16:13:55 2007
+ * Compilation of "dsdt.asl" - Wed Jul 11 13:34:30 2007
  * 
  * C source code output
  *
  */
 unsigned char AmlCode[] =
 {
-    0x44,0x53,0x44,0x54,0x67,0x0D,0x00,0x00,  /* 00000000    "DSDTg..." */
-    0x02,0xE0,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
+    0x44,0x53,0x44,0x54,0x9F,0x0D,0x00,0x00,  /* 00000000    "DSDT...." */
+    0x02,0x2E,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
     0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00,  /* 00000010    "HVM....." */
     0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
     0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    "... .PMB" */
@@ -27,7 +27,7 @@ unsigned char AmlCode[] =
     0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08,  /* 00000060    "........" */
     0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F,  /* 00000068    "PICD..._" */
     0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49,  /* 00000070    "PIC.phPI" */
-    0x43,0x44,0x10,0x4C,0xCE,0x5F,0x53,0x42,  /* 00000078    "CD.L._SB" */
+    0x43,0x44,0x10,0x44,0xD2,0x5F,0x53,0x42,  /* 00000078    "CD.D._SB" */
     0x5F,0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D,  /* 00000080    "_[.I.MEM" */
     0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000088    "0._HID.A" */
     0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,  /* 00000090    "...._CRS" */
@@ -37,7 +37,7 @@ unsigned char AmlCode[] =
     0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,  /* 000000B0    "........" */
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000B8    "........" */
     0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,  /* 000000C0    "........" */
-    0x00,0x00,0x79,0x00,0x5B,0x82,0x49,0xC9,  /* 000000C8    "..y.[.I." */
+    0x00,0x00,0x79,0x00,0x5B,0x82,0x41,0xCD,  /* 000000C8    "..y.[.A." */
     0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49,  /* 000000D0    "PCI0._HI" */
     0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,  /* 000000D8    "D.A...._" */
     0x55,0x49,0x44,0x00,0x08,0x5F,0x41,0x44,  /* 000000E0    "UID.._AD" */
@@ -59,7 +59,7 @@ unsigned char AmlCode[] =
     0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,  /* 00000160    "........" */
     0x00,0x00,0x00,0x00,0x00,0x05,0x79,0x00,  /* 00000168    "......y." */
     0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55,  /* 00000170    ".PRT0.BU" */
-    0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0xA0,  /* 00000178    "FA....#." */
+    0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x20,  /* 00000178    "FA....# " */
     0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46,  /* 00000180    "..y..BUF" */
     0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00,  /* 00000188    "B....#.." */
     0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42,  /* 00000190    ".y..BUFB" */
@@ -348,7 +348,7 @@ unsigned char AmlCode[] =
     0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000A68    "........" */
     0x02,0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C,  /* 00000A70    ".../...." */
     0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A,  /* 00000A78    "........" */
-    0x10,0x5B,0x82,0x44,0x2E,0x49,0x53,0x41,  /* 00000A80    ".[.D.ISA" */
+    0x10,0x5B,0x82,0x4C,0x31,0x49,0x53,0x41,  /* 00000A80    ".[.L1ISA" */
     0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,  /* 00000A88    "_._ADR.." */
     0x00,0x01,0x00,0x5B,0x80,0x50,0x49,0x52,  /* 00000A90    "...[.PIR" */
     0x51,0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E,  /* 00000A98    "Q..`...." */
@@ -440,6 +440,13 @@ unsigned char AmlCode[] =
     0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D48    "._STA..." */
     0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10,  /* 00000D50    ".._CRS.." */
     0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03,  /* 00000D58    "..G....." */
-    0x01,0x08,0x22,0x10,0x00,0x79,0x00,
+    0x01,0x08,0x22,0x10,0x00,0x79,0x00,0x5B,  /* 00000D60    ".."..y.[" */
+    0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F,  /* 00000D68    ".6LTP1._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00,  /* 00000D70    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,  /* 00000D78    "._UID..." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D80    "._STA..." */
+    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10,  /* 00000D88    ".._CRS.." */
+    0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03,  /* 00000D90    "..G.x.x." */
+    0x08,0x08,0x22,0x80,0x00,0x79,0x00,
 };
 int DsdtLen=sizeof(AmlCode);
diff -r f536eb8576ee -r d0477293897c tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/firmware/hvmloader/config.h Thu Jul 12 09:53:58 2007 +0100
@@ -9,7 +9,7 @@
 #define LAPIC_ID(vcpu_id)   ((vcpu_id) * 2)
 
 #define PCI_ISA_DEVFN       0x08    /* dev 1, fn 0 */
-#define PCI_ISA_IRQ_MASK    0x0ca0U /* ISA IRQs 5,7,10,11 are PCI connected */
+#define PCI_ISA_IRQ_MASK    0x0c20U /* ISA IRQs 5,10,11 are PCI connected */
 
 #define ROMBIOS_SEG            0xF000
 #define ROMBIOS_BEGIN          0x000F0000
diff -r f536eb8576ee -r d0477293897c tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/firmware/hvmloader/hvmloader.c      Thu Jul 12 09:53:58 2007 +0100
@@ -180,15 +180,13 @@ static void pci_setup(void)
     unsigned int bar, pin, link, isa_irq;
 
     /* Program PCI-ISA bridge with appropriate link routes. */
-    link = 0;
-    for ( isa_irq = 0; isa_irq < 15; isa_irq++ )
-    {
-        if ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) )
-            continue;
+    isa_irq = 0;
+    for ( link = 0; link < 4; link++ )
+    {
+        do { isa_irq = (isa_irq + 1) & 15;
+        } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) );
         pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq);
         printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq);
-        if ( link++ == 4 )
-            break;
     }
 
     /* Program ELCR to match PCI-wired IRQs. */
diff -r f536eb8576ee -r d0477293897c tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/firmware/rombios/rombios.c  Thu Jul 12 09:53:58 2007 +0100
@@ -9146,78 +9146,78 @@ pci_routing_table_structure:
   db 0 ;; pci bus number
   db 0x08 ;; pci device number (bit 7-3)
   db 0x61 ;; link value INTA#: pointer into PCI2ISA config space
-  dw 0x0ca0 ;; IRQ bitmap INTA# 
+  dw 0x0c20 ;; IRQ bitmap INTA# 
   db 0x62 ;; link value INTB#
-  dw 0x0ca0 ;; IRQ bitmap INTB# 
+  dw 0x0c20 ;; IRQ bitmap INTB# 
   db 0x63 ;; link value INTC#
-  dw 0x0ca0 ;; IRQ bitmap INTC# 
+  dw 0x0c20 ;; IRQ bitmap INTC# 
   db 0x60 ;; link value INTD#
-  dw 0x0ca0 ;; IRQ bitmap INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
   db 0 ;; physical slot (0 = embedded)
   db 0 ;; reserved
   ;; second slot entry: 1st PCI slot
   db 0 ;; pci bus number
   db 0x10 ;; pci device number (bit 7-3)
   db 0x62 ;; link value INTA#
-  dw 0x0ca0 ;; IRQ bitmap INTA# 
+  dw 0x0c20 ;; IRQ bitmap INTA# 
   db 0x63 ;; link value INTB#
-  dw 0x0ca0 ;; IRQ bitmap INTB# 
+  dw 0x0c20 ;; IRQ bitmap INTB# 
   db 0x60 ;; link value INTC#
-  dw 0x0ca0 ;; IRQ bitmap INTC# 
+  dw 0x0c20 ;; IRQ bitmap INTC# 
   db 0x61 ;; link value INTD#
-  dw 0x0ca0 ;; IRQ bitmap INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
   db 1 ;; physical slot (0 = embedded)
   db 0 ;; reserved
   ;; third slot entry: 2nd PCI slot
   db 0 ;; pci bus number
   db 0x18 ;; pci device number (bit 7-3)
   db 0x63 ;; link value INTA#
-  dw 0x0ca0 ;; IRQ bitmap INTA# 
+  dw 0x0c20 ;; IRQ bitmap INTA# 
   db 0x60 ;; link value INTB#
-  dw 0x0ca0 ;; IRQ bitmap INTB# 
+  dw 0x0c20 ;; IRQ bitmap INTB# 
   db 0x61 ;; link value INTC#
-  dw 0x0ca0 ;; IRQ bitmap INTC# 
+  dw 0x0c20 ;; IRQ bitmap INTC# 
   db 0x62 ;; link value INTD#
-  dw 0x0ca0 ;; IRQ bitmap INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
   db 2 ;; physical slot (0 = embedded)
   db 0 ;; reserved
   ;; 4th slot entry: 3rd PCI slot
   db 0 ;; pci bus number
   db 0x20 ;; pci device number (bit 7-3)
   db 0x60 ;; link value INTA#
-  dw 0x0ca0 ;; IRQ bitmap INTA# 
+  dw 0x0c20 ;; IRQ bitmap INTA# 
   db 0x61 ;; link value INTB#
-  dw 0x0ca0 ;; IRQ bitmap INTB# 
+  dw 0x0c20 ;; IRQ bitmap INTB# 
   db 0x62 ;; link value INTC#
-  dw 0x0ca0 ;; IRQ bitmap INTC# 
+  dw 0x0c20 ;; IRQ bitmap INTC# 
   db 0x63 ;; link value INTD#
-  dw 0x0ca0 ;; IRQ bitmap INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
   db 3 ;; physical slot (0 = embedded)
   db 0 ;; reserved
   ;; 5th slot entry: 4rd PCI slot
   db 0 ;; pci bus number
   db 0x28 ;; pci device number (bit 7-3)
   db 0x61 ;; link value INTA#
-  dw 0x0ca0 ;; IRQ bitmap INTA# 
+  dw 0x0c20 ;; IRQ bitmap INTA# 
   db 0x62 ;; link value INTB#
-  dw 0x0ca0 ;; IRQ bitmap INTB# 
+  dw 0x0c20 ;; IRQ bitmap INTB# 
   db 0x63 ;; link value INTC#
-  dw 0x0ca0 ;; IRQ bitmap INTC# 
+  dw 0x0c20 ;; IRQ bitmap INTC# 
   db 0x60 ;; link value INTD#
-  dw 0x0ca0 ;; IRQ bitmap INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
   db 4 ;; physical slot (0 = embedded)
   db 0 ;; reserved
   ;; 6th slot entry: 5rd PCI slot
   db 0 ;; pci bus number
   db 0x30 ;; pci device number (bit 7-3)
   db 0x62 ;; link value INTA#
-  dw 0x0ca0 ;; IRQ bitmap INTA# 
+  dw 0x0c20 ;; IRQ bitmap INTA# 
   db 0x63 ;; link value INTB#
-  dw 0x0ca0 ;; IRQ bitmap INTB# 
+  dw 0x0c20 ;; IRQ bitmap INTB# 
   db 0x60 ;; link value INTC#
-  dw 0x0ca0 ;; IRQ bitmap INTC# 
+  dw 0x0c20 ;; IRQ bitmap INTC# 
   db 0x61 ;; link value INTD#
-  dw 0x0ca0 ;; IRQ bitmap INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
   db 5 ;; physical slot (0 = embedded)
   db 0 ;; reserved
 #endif // BX_PCIBIOS
diff -r f536eb8576ee -r d0477293897c tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c      Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/ioemu/hw/ide.c      Thu Jul 12 09:53:58 2007 +0100
@@ -596,7 +596,8 @@ static void ide_identify(IDEState *s)
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
     put_le16(p + 84, (1 << 14));
-    put_le16(p + 85, (1 << 14));
+    /* 14=nop 5=write_cache */
+    put_le16(p + 85, (1 << 14) | (1 << 5));
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
     put_le16(p + 87, (1 << 14));
diff -r f536eb8576ee -r d0477293897c tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c      Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/ioemu/target-i386-dm/exec-dm.c      Thu Jul 12 09:53:58 2007 +0100
@@ -446,18 +446,16 @@ extern unsigned long logdirty_bitmap_siz
 #if defined(__x86_64__) || defined(__i386__)
 static void memcpy_words(void *dst, void *src, size_t n)
 {
-    asm (
+    asm volatile (
         "   movl %%edx,%%ecx \n"
 #ifdef __x86_64__
         "   shrl $3,%%ecx    \n"
-        "   andl $7,%%edx    \n"
         "   rep  movsq       \n"
         "   test $4,%%edx    \n"
         "   jz   1f          \n"
         "   movsl            \n"
 #else /* __i386__ */
         "   shrl $2,%%ecx    \n"
-        "   andl $3,%%edx    \n"
         "   rep  movsl       \n"
 #endif
         "1: test $2,%%edx    \n"
@@ -467,7 +465,7 @@ static void memcpy_words(void *dst, void
         "   jz   1f          \n"
         "   movsb            \n"
         "1:                  \n"
-        : : "S" (src), "D" (dst), "d" (n) : "ecx" );
+        : "+S" (src), "+D" (dst) : "d" (n) : "ecx", "memory" );
 }
 #else
 static void memcpy_words(void *dst, void *src, size_t n)
diff -r f536eb8576ee -r d0477293897c tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/ioemu/vl.c  Thu Jul 12 09:53:58 2007 +0100
@@ -7141,13 +7141,8 @@ int main(int argc, char **argv)
         serial_devices[i][0] = '\0';
     serial_device_index = 0;
 
-#ifndef CONFIG_DM
     pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
     for(i = 1; i < MAX_PARALLEL_PORTS; i++)
-#else
-    /* Xen steals IRQ7 for PCI. Disable LPT1 by default. */
-    for(i = 0; i < MAX_PARALLEL_PORTS; i++)
-#endif
         parallel_devices[i][0] = '\0';
     parallel_device_index = 0;
     
diff -r f536eb8576ee -r d0477293897c tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/libxc/xc_domain.c   Thu Jul 12 09:53:58 2007 +0100
@@ -586,6 +586,27 @@ int xc_domain_ioport_permission(int xc_h
     domctl.u.ioport_permission.allow_access = allow_access;
 
     return do_domctl(xc_handle, &domctl);
+}
+
+int xc_availheap(int xc_handle,
+                 int min_width,
+                 int max_width,
+                 int node,
+                 uint64_t *bytes)
+{
+    DECLARE_SYSCTL;
+    int rc;
+
+    sysctl.cmd = XEN_SYSCTL_availheap;
+    sysctl.u.availheap.min_bitwidth = min_width;
+    sysctl.u.availheap.max_bitwidth = max_width;
+    sysctl.u.availheap.node = node;
+
+    rc = xc_sysctl(xc_handle, &sysctl);
+
+    *bytes = sysctl.u.availheap.avail_bytes;
+
+    return rc;
 }
 
 int xc_vcpu_setcontext(int xc_handle,
diff -r f536eb8576ee -r d0477293897c tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/libxc/xenctrl.h     Thu Jul 12 09:53:58 2007 +0100
@@ -628,6 +628,20 @@ int xc_get_pfn_type_batch(int xc_handle,
 /* Get current total pages allocated to a domain. */
 long xc_get_tot_pages(int xc_handle, uint32_t domid);
 
+/**
+ * This function retrieves the the number of bytes available
+ * in the heap in a specific range of address-widths and nodes.
+ * 
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain to query
+ * @parm min_width the smallest address width to query (0 if don't care)
+ * @parm max_width the largest address width to query (0 if don't care)
+ * @parm node the node to query (-1 for all)
+ * @parm *bytes caller variable to put total bytes counted
+ * @return 0 on success, <0 on failure.
+ */
+int xc_availheap(int xc_handle, int min_width, int max_width, int node,
+                 uint64_t *bytes);
 
 /*
  * Trace Buffer Operations
diff -r f536eb8576ee -r d0477293897c 
tools/libxen/include/xen/api/xen_acmpolicy.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen/api/xen_acmpolicy.h      Thu Jul 12 09:53:58 
2007 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2007, IBM Corp.
+ * Copyright (c) 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_ACMPOLICY_H
+#define XEN_ACMPOLICY_H
+
+#include "xen_common.h"
+#include "xen_string_string_map.h"
+#include "xen_xspolicy_decl.h"
+#include "xen_vm_decl.h"
+
+/*
+ * Data structures.
+ */
+
+typedef struct xen_acmpolicy_record
+{
+    xen_xspolicy handle;
+    char *uuid;
+    char *repr;
+    xs_instantiationflags flags;
+    xs_type type;
+} xen_acmpolicy_record;
+
+/**
+ * Allocate a xen_acmpolicy_record.
+ */
+extern xen_acmpolicy_record *
+xen_acmpolicy_record_alloc(void);
+
+/**
+ * Free the given xen_xspolicy_record, and all referenced values.  The
+ * given record must have been allocated by this library.
+ */
+extern void
+xen_acmpolicy_record_free(xen_acmpolicy_record *record);
+
+
+/**
+ * Data structures for the policy's header
+ */
+typedef struct xen_acm_header
+{
+    char *policyname;
+    char *policyurl;
+    char *date;
+    char *reference;
+    char *namespaceurl;
+    char *version;
+} xen_acm_header;
+
+extern xen_acm_header *
+xen_acm_header_alloc(void);
+
+extern void
+xen_acm_header_free(xen_acm_header *hdr);
+
+/**
+ * Get the referenced policy's record.
+ */
+bool
+xen_acmpolicy_get_record(xen_session *session, xen_acmpolicy_record **result,
+                         xen_xspolicy xspolicy);
+
+/**
+ * Get the header of a  policy.
+ */
+extern bool
+xen_acmpolicy_get_header(xen_session *session, xen_acm_header **hdr,
+                         xen_xspolicy xspolicy);
+
+
+/**
+ * Get the XML representation of the policy.
+ */
+extern bool
+xen_acmpolicy_get_xml(xen_session *session, char **xml,
+                      xen_xspolicy xspolicy);
+
+/**
+ * Get the mapping file of the policy.
+ */
+extern bool
+xen_acmpolicy_get_map(xen_session *session, char **map,
+                      xen_xspolicy xspolicy);
+
+/**
+ * Get the binary representation (base64-encoded) of the policy.
+ */
+extern bool
+xen_acmpolicy_get_binary(xen_session *session, char **binary,
+                         xen_xspolicy xspolicy);
+
+/**
+ * Get the UUID filed of the given policy.
+ */
+bool
+xen_acmpolicy_get_uuid(xen_session *session, char **result,
+                       xen_xspolicy xspolicy);
+
+#endif
diff -r f536eb8576ee -r d0477293897c tools/libxen/include/xen/api/xen_vdi.h
--- a/tools/libxen/include/xen/api/xen_vdi.h    Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/libxen/include/xen/api/xen_vdi.h    Thu Jul 12 09:53:58 2007 +0100
@@ -344,4 +344,17 @@ xen_vdi_get_all(xen_session *session, st
 xen_vdi_get_all(xen_session *session, struct xen_vdi_set **result);
 
 
+/**
+ * Set the security label of a VDI.
+ */
+extern bool
+xen_vdi_set_security_label(xen_session *session, int64_t *result, xen_vdi vdi,
+                           char *label, char *oldlabel);
+
+/**
+ * Get the security label of a VDI.
+ */
+extern bool
+xen_vdi_get_security_label(xen_session *session, char **result, xen_vdi vdi);
+
 #endif
diff -r f536eb8576ee -r d0477293897c tools/libxen/include/xen/api/xen_vm.h
--- a/tools/libxen/include/xen/api/xen_vm.h     Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/libxen/include/xen/api/xen_vm.h     Thu Jul 12 09:53:58 2007 +0100
@@ -112,6 +112,7 @@ typedef struct xen_vm_record
     bool is_control_domain;
     struct xen_vm_metrics_record_opt *metrics;
     struct xen_vm_guest_metrics_record_opt *guest_metrics;
+    char *security_label;
 } xen_vm_record;
 
 /**
@@ -891,4 +892,17 @@ xen_vm_get_all(xen_session *session, str
 xen_vm_get_all(xen_session *session, struct xen_vm_set **result);
 
 
+/**
+ * Set the security label of a domain.
+ */
+extern bool
+xen_vm_set_security_label(xen_session *session, int64_t *result, xen_vm vm,
+                          char *label, char *oldlabel);
+
+/**
+ * Get the security label of a domain.
+ */
+extern bool
+xen_vm_get_security_label(xen_session *session, char **result, xen_vm vm);
+
 #endif
diff -r f536eb8576ee -r d0477293897c tools/libxen/include/xen/api/xen_xspolicy.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen/api/xen_xspolicy.h       Thu Jul 12 09:53:58 
2007 +0100
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2007, IBM Corp.
+ * Copyright (c) 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_XSPOLICY_H
+#define XEN_XSPOLICY_H
+
+#include "xen_common.h"
+#include "xen_xspolicy_decl.h"
+#include "xen_string_string_map.h"
+
+
+/*
+ * The XSPolicy and associated data structures.
+ *
+ */
+typedef int64_t xs_type;
+typedef int64_t xs_instantiationflags;
+
+enum xs_type {
+    XS_POLICY_ACM = (1 << 0),
+};
+
+enum xs_instantiationflags {
+    XS_INST_NONE = 0,
+    XS_INST_BOOT = (1 << 0),
+    XS_INST_LOAD = (1 << 1),
+};
+
+
+/* Error codes returned by xend following XSPolicy operations */
+#define XSERR_BASE                       0x1000
+
+#define XSERR_SUCCESS                    0
+#define XSERR_GENERAL_FAILURE            1 + XSERR_BASE
+#define XSERR_BAD_XML                    2 + XSERR_BASE
+#define XSERR_XML_PROCESSING             3 + XSERR_BASE
+#define XSERR_POLICY_INCONSISTENT        4 + XSERR_BASE
+#define XSERR_FILE_ERROR                 5 + XSERR_BASE
+#define XSERR_BAD_RESOURCE_FORMAT        6 + XSERR_BASE
+#define XSERR_BAD_LABEL_FORMAT           7 + XSERR_BASE
+#define XSERR_RESOURCE_NOT_LABELED       8 + XSERR_BASE
+#define XSERR_RESOURCE_ALREADY_LABELED   9 + XSERR_BASE
+#define XSERR_WRONG_POLICY_TYPE         10 + XSERR_BASE
+#define XSERR_BOOTPOLICY_INSTALLED      11 + XSERR_BASE
+#define XSERR_NO_DEFAULT_BOOT_TITLE     12 + XSERR_BASE
+#define XSERR_POLICY_LOAD_FAILED        13 + XSERR_BASE
+#define XSERR_POLICY_LOADED             14 + XSERR_BASE
+#define XSERR_POLICY_TYPE_UNSUPPORTED   15 + XSERR_BASE
+#define XSERR_BAD_CONFLICTSET           20 + XSERR_BASE
+#define XSERR_RESOURCE_IN_USE           21 + XSERR_BASE
+#define XSERR_BAD_POLICY_NAME           22 + XSERR_BASE
+#define XSERR_RESOURCE_ACCESS           23 + XSERR_BASE
+#define XSERR_HV_OP_FAILED              24 + XSERR_BASE
+#define XSERR_BOOTPOLICY_INSTALL_ERROR  25 + XSERR_BASE
+
+
+/**
+ * Free the given xen_xspolicy.  The given handle must have been allocated
+ * by this library.
+ */
+extern void
+xen_xspolicy_free(xen_xspolicy xspolicy);
+
+
+typedef struct xen_xspolicy_set
+{
+    size_t size;
+    xen_xspolicy *contents[];
+} xen_xspolicy_set;
+
+/**
+ * Allocate a xen_xspolicy_set of the given size.
+ */
+extern xen_xspolicy_set *
+xen_xspolicy_set_alloc(size_t size);
+
+/**
+ * Free the given xen_xspolicy_set.  The given set must have been allocated
+ * by this library.
+ */
+extern void
+xen_xspolicy_set_free(xen_xspolicy_set *set);
+
+
+typedef struct xen_xspolicy_record
+{
+    xen_xspolicy handle;
+    char *uuid;
+    char *repr;
+    xs_instantiationflags flags;
+    xs_type type;
+} xen_xspolicy_record;
+
+/**
+ * Allocate a xen_xspolicy_record.
+ */
+extern xen_xspolicy_record *
+xen_xspolicy_record_alloc(void);
+
+/**
+ * Free the given xen_xspolicy_record, and all referenced values.  The
+ * given record must have been allocated by this library.
+ */
+extern void
+xen_xspolicy_record_free(xen_xspolicy_record *record);
+
+
+typedef struct xen_xspolicy_record_opt
+{
+    bool is_record;
+    union
+    {
+        xen_xspolicy handle;
+        xen_xspolicy_record *record;
+    } u;
+} xen_xspolicy_record_opt;
+
+/**
+ * Allocate a xen_xspolicy_record_opt.
+ */
+extern xen_xspolicy_record_opt *
+xen_xspolicy_record_opt_alloc(void);
+
+/**
+ * Free the given xen_xspolicy_record_opt, and all referenced values.  The
+ * given record_opt must have been allocated by this library.
+ */
+extern void
+xen_xspolicy_record_opt_free(xen_xspolicy_record_opt *record_opt);
+
+
+typedef struct xen_xspolicy_record_set
+{
+    size_t size;
+    xen_xspolicy_record *contents[];
+} xen_xspolicy_record_set;
+
+/**
+ * Allocate a xen_xspolicy_record_set of the given size.
+ */
+extern xen_xspolicy_record_set *
+xen_xspolicy_record_set_alloc(size_t size);
+
+/**
+ * Free the given xen_xspolicy_record_set, and all referenced values.  The
+ * given set must have been allocated by this library.
+ */
+extern void
+xen_xspolicy_record_set_free(xen_xspolicy_record_set *set);
+
+/**
+ * Data structures and function declarations for an XS Policy's state
+ * information.
+ */
+typedef struct xen_xs_policystate
+{
+    xen_xspolicy_record_opt *xs_ref;
+    int64_t xserr;
+    char *repr;
+    xs_type type;
+    xs_instantiationflags flags;
+    char *version;
+    char *errors;
+} xen_xs_policystate;
+
+void
+xen_xs_policystate_free(xen_xs_policystate *state);
+
+
+/**
+ * Get the referenced policy's record.
+ */
+bool
+xen_xspolicy_get_record(xen_session *session, xen_xspolicy_record **result,
+                        xen_xspolicy xspolicy);
+
+/**
+ * Get the UUID field of the given policy.
+ */
+bool
+xen_xspolicy_get_uuid(xen_session *session, char **result,
+                      xen_xspolicy xspolicy);
+
+/**
+ * Get a policy given it's UUID
+ */
+bool
+xen_xspolicy_get_by_uuid(xen_session *session, xen_xspolicy *result,
+                         char *uuid);
+
+
+/**
+ * Get the types of policies supported by the system.
+ */
+bool
+xen_xspolicy_get_xstype(xen_session *session, xs_type *result);
+
+
+/**
+ * Get information about the currently managed policy.
+ * (The API allows only one policy to be on the system.)
+ */
+bool
+xen_xspolicy_get_xspolicy(xen_session *session, xen_xs_policystate **result);
+
+/**
+ * Activate the referenced policy by loading it into the hypervisor.
+ */
+bool
+xen_xspolicy_activate_xspolicy(xen_session *session, int64_t *result,
+                               xen_xspolicy xspolicy,
+                               xs_instantiationflags flags);
+
+
+/**
+ * Set the system's policy to the given information comprising
+ * type of policy, the xml representation of the policy, some flags
+ * on whether to load the policy immediately and whether to overwrite
+ * an existing policy on the system.
+ */
+bool
+xen_xspolicy_set_xspolicy(xen_session *session, xen_xs_policystate **result,
+                          xs_type type, char *repr, int64_t flags,
+                          bool overwrite);
+
+
+/**
+ * Remove any policy from having the system booted with.
+ */
+extern bool
+xen_xspolicy_rm_xsbootpolicy(xen_session *session);
+
+/**
+ * Retrieve all labeled resources.
+ */
+extern bool
+xen_xspolicy_get_labeled_resources(xen_session *session,
+                                   xen_string_string_map **resources);
+
+/**
+ * Label a resource such as for example a hard drive partition or file
+ */
+extern bool
+xen_xspolicy_set_resource_label(xen_session *session,
+                                char *resource, char *label,
+                                char *oldlabel);
+
+/**
+ * Get the label of a resource.
+ */
+extern bool
+xen_xspolicy_get_resource_label(xen_session *session, char **label,
+                                char *resource);
+
+#endif
diff -r f536eb8576ee -r d0477293897c 
tools/libxen/include/xen/api/xen_xspolicy_decl.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen/api/xen_xspolicy_decl.h  Thu Jul 12 09:53:58 
2007 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2007, IBM Corp.
+ * Copyright (c) 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_XSPOLICY_DECL_H
+#define XEN_XSPOLICY_DECL_H
+
+typedef void *xen_xspolicy;
+
+struct xen_xspolicy_set;
+struct xen_xspolicy_record;
+struct xen_xspolicy_record_set;
+struct xen_xspolicy_record_opt;
+struct xen_xspolicy_record_opt_set;
+
+#endif
diff -r f536eb8576ee -r d0477293897c tools/libxen/src/xen_acmpolicy.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_acmpolicy.c  Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2007, IBM Corp.
+ * Copyright (c) 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_internal.h"
+#include "xen/api/xen_common.h"
+#include "xen/api/xen_xspolicy.h"
+#include "xen/api/xen_acmpolicy.h"
+
+
+static const struct_member xen_acmpolicy_record_struct_members[] =
+    {
+        { .key = "uuid",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acmpolicy_record, uuid) },
+        { .key = "flags",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_acmpolicy_record, flags) },
+        { .key = "repr",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acmpolicy_record, repr) },
+        { .key = "type",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_acmpolicy_record, type) },
+    };
+
+const abstract_type xen_acmpolicy_record_abstract_type_ =
+    {
+       .typename = STRUCT,
+       .struct_size = sizeof(xen_acmpolicy_record),
+       .member_count =
+          sizeof(xen_acmpolicy_record_struct_members) / sizeof(struct_member),
+       .members = xen_acmpolicy_record_struct_members
+    };
+
+
+static const struct_member xen_acm_header_struct_members[] =
+    {
+        { .key = "policyname",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acm_header, policyname) },
+        { .key = "policyurl",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acm_header, policyurl) },
+        { .key = "date",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acm_header, date) },
+        { .key = "reference",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acm_header, reference) },
+        { .key = "namespaceurl",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acm_header, namespaceurl) },
+        { .key = "version",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_acm_header, version) },
+    };
+
+const abstract_type xen_acm_header_abstract_type_ =
+    {
+        .typename = STRUCT,
+        .struct_size = sizeof(xen_acm_header),
+        .member_count =
+            sizeof(xen_acm_header_struct_members) /
+            sizeof(struct_member),
+        .members = xen_acm_header_struct_members,
+    };
+
+void
+xen_acm_header_free(xen_acm_header *shdr)
+{
+    if (shdr == NULL)
+    {
+        return;
+    }
+    free(shdr->policyname);
+    free(shdr->policyurl);
+    free(shdr->date);
+    free(shdr->reference);
+    free(shdr->namespaceurl);
+    free(shdr->version);
+    free(shdr);
+}
+
+
+void
+xen_acmpolicy_record_free(xen_acmpolicy_record *record)
+{
+    if (record == NULL)
+    {
+        return;
+    }
+    free(record->handle);
+    free(record->uuid);
+    free(record->repr);
+    free(record);
+}
+
+
+
+bool
+xen_acmpolicy_get_record(xen_session *session, xen_acmpolicy_record **result,
+                         xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy }
+        };
+
+    abstract_type result_type = xen_acmpolicy_record_abstract_type_;
+
+    *result = NULL;
+    XEN_CALL_("ACMPolicy.get_record");
+
+    if (session->ok)
+    {
+       (*result)->handle = xen_strdup_((*result)->uuid);
+    }
+
+    return session->ok;
+}
+
+
+bool
+xen_acmpolicy_get_header(xen_session *session,
+                         xen_acm_header **result,
+                         xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy },
+        };
+
+    abstract_type result_type = xen_acm_header_abstract_type_;
+
+    *result = NULL;
+    XEN_CALL_("ACMPolicy.get_header");
+    return session->ok;
+}
+
+
+bool
+xen_acmpolicy_get_xml(xen_session *session,
+                      char **result,
+                      xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy },
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("ACMPolicy.get_xml");
+    return session->ok;
+}
+
+
+bool
+xen_acmpolicy_get_map(xen_session *session,
+                      char **result,
+                      xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy },
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("ACMPolicy.get_map");
+    return session->ok;
+}
+
+
+bool
+xen_acmpolicy_get_binary(xen_session *session, char **result,
+                         xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy },
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("ACMPolicy.get_binary");
+    return session->ok;
+}
+
+
+bool
+xen_acmpolicy_get_uuid(xen_session *session, char **result,
+                       xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("ACMPolicy.get_uuid");
+    return session->ok;
+}
diff -r f536eb8576ee -r d0477293897c tools/libxen/src/xen_vdi.c
--- a/tools/libxen/src/xen_vdi.c        Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/libxen/src/xen_vdi.c        Thu Jul 12 09:53:58 2007 +0100
@@ -534,3 +534,42 @@ xen_vdi_get_uuid(xen_session *session, c
     XEN_CALL_("VDI.get_uuid");
     return session->ok;
 }
+
+
+bool
+xen_vdi_set_security_label(xen_session *session, int64_t *result, xen_vdi vdi,
+                           char *label, char *oldlabel)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vdi },
+            { .type = &abstract_type_string,
+              .u.string_val = label },
+            { .type = &abstract_type_string,
+              .u.string_val = oldlabel },
+        };
+
+    abstract_type result_type = abstract_type_int;
+
+    *result = 0;
+    XEN_CALL_("VDI.set_security_label");
+    return session->ok;
+}
+
+
+bool
+xen_vdi_get_security_label(xen_session *session, char **result, xen_vdi vdi)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vdi },
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VDI.get_security_label");
+    return session->ok;
+}
diff -r f536eb8576ee -r d0477293897c tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/libxen/src/xen_vm.c Thu Jul 12 09:53:58 2007 +0100
@@ -162,7 +162,10 @@ static const struct_member xen_vm_record
           .offset = offsetof(xen_vm_record, metrics) },
         { .key = "guest_metrics",
           .type = &abstract_type_ref,
-          .offset = offsetof(xen_vm_record, guest_metrics) }
+          .offset = offsetof(xen_vm_record, guest_metrics) },
+        { .key = "security_label",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, security_label) }
     };
 
 const abstract_type xen_vm_record_abstract_type_ =
@@ -206,6 +209,7 @@ xen_vm_record_free(xen_vm_record *record
     xen_string_string_map_free(record->other_config);
     xen_vm_metrics_record_opt_free(record->metrics);
     xen_vm_guest_metrics_record_opt_free(record->guest_metrics);
+    free(record->security_label);
     free(record);
 }
 
@@ -1738,3 +1742,42 @@ xen_vm_get_uuid(xen_session *session, ch
     XEN_CALL_("VM.get_uuid");
     return session->ok;
 }
+
+
+bool
+xen_vm_set_security_label(xen_session *session, int64_t *result, xen_vm vm,
+                          char *label, char *oldlabel)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = label },
+            { .type = &abstract_type_string,
+              .u.string_val = oldlabel },
+        };
+
+    abstract_type result_type = abstract_type_int;
+
+    *result = 0;
+    XEN_CALL_("VM.set_security_label");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_security_label(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_security_label");
+    return session->ok;
+}
diff -r f536eb8576ee -r d0477293897c tools/libxen/src/xen_xspolicy.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_xspolicy.c   Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2007, IBM Corp.
+ * Copyright (c) 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/api/xen_common.h"
+#include "xen/api/xen_internal.h"
+#include "xen/api/xen_xspolicy.h"
+
+
+XEN_FREE(xen_xspolicy)
+XEN_SET_ALLOC_FREE(xen_xspolicy)
+XEN_RECORD_OPT_FREE(xen_xspolicy)
+
+static const struct_member xen_xspolicy_record_struct_members[] =
+    {
+        { .key = "uuid",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_xspolicy_record, uuid) },
+        { .key = "flags",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_xspolicy_record, flags) },
+        { .key = "repr",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_xspolicy_record, repr) },
+        { .key = "type",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_xspolicy_record, type) },
+    };
+
+const abstract_type xen_xspolicy_record_abstract_type_ =
+    {
+       .typename = STRUCT,
+       .struct_size = sizeof(xen_xspolicy_record),
+       .member_count =
+           sizeof(xen_xspolicy_record_struct_members) / sizeof(struct_member),
+       .members = xen_xspolicy_record_struct_members
+    };
+
+
+static const struct_member xen_xs_policystate_struct_members[] =
+    {
+        { .key = "xs_ref",
+          .type = &abstract_type_ref,
+          .offset = offsetof(xen_xs_policystate, xs_ref) },
+        { .key = "xserr",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_xs_policystate, xserr) },
+        { .key = "repr",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_xs_policystate, repr) },
+        { .key = "type",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_xs_policystate, type) },
+        { .key = "flags",
+          .type = &abstract_type_int,
+          .offset = offsetof(xen_xs_policystate, flags) },
+        { .key = "version",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_xs_policystate, version) },
+        { .key = "errors",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_xs_policystate, errors) },
+    };
+
+const abstract_type xen_xs_policystate_abstract_type_ =
+    {
+        .typename = STRUCT,
+        .struct_size = sizeof(xen_xs_policystate),
+        .member_count =
+            sizeof(xen_xs_policystate_struct_members) /
+            sizeof(struct_member),
+        .members = xen_xs_policystate_struct_members,
+    };
+
+
+
+
+void
+xen_xs_policystate_free(xen_xs_policystate *state)
+{
+    if (state == NULL)
+    {
+        return;
+    }
+    xen_xspolicy_record_opt_free(state->xs_ref);
+    free(state->repr);
+    free(state->errors);
+    free(state->version);
+    free(state);
+}
+
+
+void
+xen_xspolicy_record_free(xen_xspolicy_record *record)
+{
+    if (record == NULL)
+    {
+        return;
+    }
+    free(record->handle);
+    free(record->uuid);
+    free(record->repr);
+    free(record);
+}
+
+
+bool
+xen_xspolicy_get_record(xen_session *session, xen_xspolicy_record **result,
+                        xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy }
+        };
+
+    abstract_type result_type = xen_xspolicy_record_abstract_type_;
+
+    *result = NULL;
+    XEN_CALL_("XSPolicy.get_record");
+
+    if (session->ok)
+    {
+       (*result)->handle = xen_strdup_((*result)->uuid);
+    }
+
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_get_uuid(xen_session *session, char **result,
+                      xen_xspolicy xspolicy)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("XSPolicy.get_uuid");
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_get_by_uuid(xen_session *session, xen_xspolicy *result,
+                         char *uuid)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = uuid }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("XSPolicy.get_by_uuid");
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_get_xstype(xen_session *session, xs_type *result)
+{
+    abstract_value param_values[] =
+        {
+        };
+
+    abstract_type result_type = abstract_type_int;
+
+    *result = 0;
+    XEN_CALL_("XSPolicy.get_xstype");
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_set_xspolicy(xen_session *session, xen_xs_policystate **result,
+                          xs_type type, char *repr,
+                          xs_instantiationflags flags,
+                          bool overwrite)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_int,
+              .u.int_val = type },
+            { .type = &abstract_type_string,
+              .u.string_val = repr },
+            { .type = &abstract_type_int,
+              .u.int_val = flags },
+            { .type = &abstract_type_bool,
+              .u.bool_val = overwrite }
+        };
+
+    abstract_type result_type = xen_xs_policystate_abstract_type_;
+
+    *result = NULL;
+    XEN_CALL_("XSPolicy.set_xspolicy");
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_get_xspolicy(xen_session *session, xen_xs_policystate **result)
+{
+    abstract_value param_values[] =
+        {
+        };
+
+    abstract_type result_type = xen_xs_policystate_abstract_type_;
+
+    *result = NULL;
+    XEN_CALL_("XSPolicy.get_xspolicy");
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_get_labeled_resources(xen_session *session,
+                                   xen_string_string_map **result)
+{
+    abstract_value param_values[] =
+        {
+        };
+
+    abstract_type result_type = abstract_type_string_string_map;
+
+    *result = NULL;
+    XEN_CALL_("XSPolicy.get_labeled_resources");
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_set_resource_label(xen_session *session,
+                                char *resource, char *label,
+                                char *oldlabel)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = resource },
+            { .type = &abstract_type_string,
+              .u.string_val = label },
+            { .type = &abstract_type_string,
+              .u.string_val = oldlabel },
+        };
+
+    xen_call_(session, "XSPolicy.set_resource_label", param_values, 3,
+                       NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_get_resource_label(xen_session *session, char **result,
+                                char *resource)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = resource },
+        };
+
+    abstract_type result_type = abstract_type_string;
+    XEN_CALL_("XSPolicy.get_resource_label");
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_rm_xsbootpolicy(xen_session *session)
+{
+    abstract_value param_values[] =
+        {
+        };
+
+    xen_call_(session, "XSPolicy.rm_xsbootpolicy", param_values, 0,
+                       NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_xspolicy_activate_xspolicy(xen_session *session,
+                               xs_instantiationflags *result,
+                               xen_xspolicy xspolicy,
+                               xs_instantiationflags flags)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = xspolicy },
+            { .type = &abstract_type_int,
+              .u.int_val = flags },
+        };
+
+    abstract_type result_type = abstract_type_int;
+
+    *result = 0;
+    XEN_CALL_("XSPolicy.activate_xspolicy");
+    return session->ok;
+}
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xend/XendDomain.py       Thu Jul 12 09:53:58 2007 +0100
@@ -1164,6 +1164,10 @@ class XendDomain:
 
         if dominfo.getDomid() == DOM0_ID:
             raise XendError("Cannot dump core for privileged domain %s" % 
domid)
+        if dominfo._stateGet() not in (DOM_STATE_PAUSED, DOM_STATE_RUNNING):
+            raise VMBadState("Domain '%s' is not started" % domid,
+                             POWER_STATE_NAMES[DOM_STATE_PAUSED],
+                             POWER_STATE_NAMES[dominfo._stateGet()])
 
         try:
             log.info("Domain core dump requested for domain %s (%d) "
@@ -1537,6 +1541,10 @@ class XendDomain:
         dominfo = self.domain_lookup_nr(domid)
         if not dominfo:
             raise XendInvalidDomain(str(domid))
+        if dominfo._stateGet() not in (DOM_STATE_RUNNING, DOM_STATE_PAUSED):
+            raise VMBadState("Domain '%s' is not started" % domid,
+                             POWER_STATE_NAMES[DOM_STATE_RUNNING],
+                             POWER_STATE_NAMES[dominfo._stateGet()])
         if trigger_name.lower() in TRIGGER_TYPE: 
             trigger = TRIGGER_TYPE[trigger_name.lower()]
         else:
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/activatepolicy.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xm/activatepolicy.py     Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,86 @@
+#============================================================================
+# 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 International Business Machines Corp.
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+#============================================================================
+
+"""Activate the managed policy of the system.
+"""
+
+import sys
+from xen.util import xsconstants
+from xml.dom import minidom
+from xen.xm.opts import OptionError
+from xen.xm import getpolicy
+from xen.xm import main as xm_main
+from xen.xm.main import server
+
+def help():
+    return """
+    Usage: xm activatepolicy [options]
+
+    Activate the xend-managed policy.
+
+    The following options are defined:
+      --load     Load the policy into the hypervisor.
+      --boot     Have the system boot with the policy. Changes the default
+                 title in grub.conf.
+      --noboot   Remove the policy from the default entry in grub.conf.
+    """
+
+def activate_policy(flags):
+    policystate = server.xenapi.XSPolicy.get_xspolicy()
+    xs_ref = policystate['xs_ref']
+    if int(policystate['type']) == 0 or xs_ref == "":
+        print "No policy is installed."
+        return
+    rc = int(server.xenapi.XSPolicy.activate_xspolicy(xs_ref, flags))
+    if rc == flags:
+        print "Successfully activated the policy."
+    else:
+        print "An error occurred trying to activate the policy: %s" % \
+              xsconstants.xserr2string(rc)
+
+def remove_bootpolicy():
+    server.xenapi.XSPolicy.rm_xsbootpolicy()
+
+def main(argv):
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+        raise OptionError('xm needs to be configured to use the xen-api.')
+    flags = 0
+    c = 1
+
+    while c < len(argv):
+        if '--boot' == argv[c]:
+            flags |= xsconstants.XS_INST_BOOT
+        elif '--load' == argv[c]:
+            flags |= xsconstants.XS_INST_LOAD
+        elif '--noboot' == argv[c]:
+            remove_bootpolicy()
+        else:
+            raise OptionError("Unknown command line option '%s'" % argv[c])
+        c += 1
+
+    if flags != 0:
+        activate_policy(flags)
+
+    getpolicy.getpolicy(False)
+
+if __name__ == '__main__':
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/addlabel.py
--- a/tools/python/xen/xm/addlabel.py   Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/addlabel.py   Thu Jul 12 09:53:58 2007 +0100
@@ -25,17 +25,29 @@ from xen.util import dictio
 from xen.util import dictio
 from xen.util import security
 from xen.xm.opts import OptionError
+from xen.util import xsconstants
+from xen.xm import main as xm_main
+from xen.xm.main import server
 
 def help():
     return """
     Format: xm addlabel <label> dom <configfile> [<policy>]
-            xm addlabel <label> res <resource> [<policy>]
+            xm addlabel <label> mgt <domain name> [<policy type>:<policy>]
+            xm addlabel <label> res <resource> [[<policy type>:]<policy>]
     
     This program adds an acm_label entry into the 'configfile'
-    for a domain or to the global resource label file for a
-    resource. It derives the policy from the running hypervisor
+    for a domain or allows to label a xend-managed domain.
+    The global resource label file for is extended with labels for
+    resources. It derives the policy from the running hypervisor
     if it is not given (optional parameter). If a label already
-    exists for the given domain or resource, then addlabel fails."""
+    exists for the given domain or resource, then addlabel fails.
+
+    For xend-managed domains, the 'mgt' parameter should be used and
+    the 'xm' tool must have been configured to use the xen-api for
+    communication with xen. If a policy is provided as last parameter,
+    its type must also be given. Currently only one type of policy is
+    supported and identified as 'ACM'. An example for a valid string
+    is 'ACM:xm-test'. """
 
 
 def validate_config_file(configfile):
@@ -66,32 +78,47 @@ def validate_config_file(configfile):
         return 1
 
 
-def add_resource_label(label, resource, policyref):
+def add_resource_label(label, resource, policyref, policy_type):
     """Adds a resource label to the global resource label file.
     """
-    # sanity check: make sure this label can be instantiated later on
-    ssidref = security.label2ssidref(label, policyref, 'res')
-
-    #build canonical resource name
-    resource = security.unify_resname(resource)
-
-    # see if this resource is already in the file
-    access_control = {}
-    file = security.res_label_filename
-    try:
-        access_control = dictio.dict_read("resources", file)
-    except:
-        print "Resource file not found, creating new file at:"
-        print "%s" % (file)
-
-    if access_control.has_key(resource):
-        security.err("This resource is already labeled.")
-
-    # write the data to file
-    new_entry = { resource : tuple([policyref, label]) }
-    access_control.update(new_entry)
-    dictio.dict_write(access_control, "resources", file)
-
+
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+
+        # sanity check: make sure this label can be instantiated later on
+        ssidref = security.label2ssidref(label, policyref, 'res')
+
+        #build canonical resource name
+        resource = security.unify_resname(resource,mustexist=False)
+
+        # see if this resource is already in the file
+        access_control = {}
+        fil = security.res_label_filename
+        try:
+            access_control = dictio.dict_read("resources", fil)
+        except:
+            print "Resource file not found, creating new file at:"
+            print "%s" % (fil)
+
+        if access_control.has_key(resource):
+            security.err("This resource is already labeled.")
+
+        # write the data to file
+        new_entry = { resource : tuple([policy_type, policyref, label]) }
+        access_control.update(new_entry)
+        dictio.dict_write(access_control, "resources", fil)
+    else:
+        res = [ policy_type, policyref, label ]
+        res_xapi = security.format_resource_label(res)
+        old = server.xenapi.XSPolicy.get_resource_label(resource)
+        if old == "":
+            try:
+                server.xenapi.XSPolicy.set_resource_label(resource,
+                                                          res_xapi,
+                                                          "")
+            except Exception, e:
+                security.err("Could not label this resource: %s" % e)
+        else:
+            security.err("'%s' is already labeled with '%s'" % (resource,old))
 
 def add_domain_label(label, configfile, policyref):
     # sanity checks: make sure this label can be instantiated later on
@@ -109,9 +136,35 @@ def add_domain_label(label, configfile, 
     config_fd.write(new_label)
     config_fd.close()
 
+def add_domain_label_xapi(label, domainname, policyref, policy_type):
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+        raise OptionError('Xm must be configured to use the xen-api.')
+    uuids = server.xenapi.VM.get_by_name_label(domainname)
+    if len(uuids) == 0:
+        raise OptionError('A VM with that name does not exist.')
+    if len(uuids) != 1:
+        raise OptionError('There are multiple domains with the same name.')
+    uuid = uuids[0]
+    sec_lab = "%s:%s:%s" % (policy_type, policyref, label)
+    try:
+        old_lab = server.xenapi.VM.get_security_label(uuid)
+        rc = server.xenapi.VM.set_security_label(uuid, sec_lab, old_lab)
+    except:
+        rc = -1
+    if int(rc) < 0:
+        raise OptionError('Could not label domain.')
+    else:
+        ssidref = int(rc)
+        if ssidref != 0:
+            print "Set the label of domain '%s' to '%s'. New ssidref = %08x" % 
\
+                  (domainname,label,ssidref)
+        else:
+            print "Set the label of dormant domain '%s' to '%s'." % \
+                  (domainname,label)
 
 def main(argv):
     policyref = None
+    policy_type = ""
     if len(argv) not in (4, 5):
         raise OptionError('Needs either 2 or 3 arguments')
     
@@ -121,6 +174,7 @@ def main(argv):
         policyref = argv[4]
     elif security.on():
         policyref = security.active_policy
+        policy_type = xsconstants.ACM_POLICY_ID
     else:
         raise OptionError("No active policy. Must specify policy on the "
                           "command line.")
@@ -136,11 +190,27 @@ def main(argv):
             raise OptionError('Invalid config file')
         else:
             add_domain_label(label, configfile, policyref)
+    elif argv[2].lower() == "mgt":
+        domain = argv[3]
+        if policy_type == "":
+            tmp = policyref.split(":")
+            if len(tmp) != 2:
+                raise OptionError("Policy name in wrong format.")
+            policy_type, policyref = tmp
+        add_domain_label_xapi(label, domain, policyref, policy_type)
     elif argv[2].lower() == "res":
         resource = argv[3]
-        add_resource_label(label, resource, policyref)
-    else:
-        raise OptionError('Need to specify either "dom" or "res" as '
+        if policy_type == "":
+            tmp = policyref.split(":")
+            if len(tmp) == 1:
+                policy_type = xsconstants.ACM_POLICY_ID
+            elif len(tmp) == 2:
+                policy_type, policyref = tmp
+            else:
+                raise OptionError("Policy name in wrong format.")
+        add_resource_label(label, resource, policyref, policy_type)
+    else:
+        raise OptionError('Need to specify either "dom", "mgt" or "res" as '
                           'object to add label to.')
             
 if __name__ == '__main__':
@@ -149,6 +219,3 @@ if __name__ == '__main__':
     except Exception, e:
         sys.stderr.write('Error: %s\n' % str(e))
         sys.exit(-1)
-    
-
-
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py      Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/cfgbootpolicy.py      Thu Jul 12 09:53:58 2007 +0100
@@ -31,7 +31,11 @@ from xen.util.security import boot_filen
 from xen.util.security import boot_filename, altboot_filename
 from xen.util.security import any_title_re, xen_kernel_re, any_module_re
 from xen.util.security import empty_line_re, binary_name_re, policy_name_re
+from xen.util import xsconstants
 from xen.xm.opts import OptionError
+from xen.xm import main as xm_main
+from xen.xm.main import server
+from xen.util.acmpolicy import ACMPolicy
 
 def help():
     return """
@@ -144,6 +148,39 @@ def insert_policy(boot_file, alt_boot_fi
         pass
     return extended_titles[0]
 
+def cfgbootpolicy_xapi(policy, user_title=None):
+    xstype = int(server.xenapi.XSPolicy.get_xstype())
+    if xstype & xsconstants.XS_POLICY_ACM == 0:
+        raise OptionError("ACM policy not supported on system.")
+    if user_title:
+        raise OptionError("Only the default title is supported with Xen-API.")
+
+    policystate = server.xenapi.XSPolicy.get_xspolicy()
+    if int(policystate['type']) == 0:
+        print "No policy is installed."
+        return
+
+    if int(policystate['type']) != xsconstants.XS_POLICY_ACM:
+        print "Unknown policy type '%s'." % policystate['type']
+        return
+    else:
+        xml = policystate['repr']
+        xs_ref = policystate['xs_ref']
+        if not xml:
+            OptionError("No policy installed on system?")
+        acmpol = ACMPolicy(xml=xml)
+        if acmpol.get_name() != policy:
+            OptionError("Policy installed on system '%s' does not match the "
+                        "request policy '%s'" % (acmpol.get_name(), policy))
+        flags = int(policystate['flags']) | xsconstants.XS_INST_BOOT
+        rc = int(server.xenapi.XSPolicy.activate_xspolicy(xs_ref, flags))
+        if rc == flags:
+            print "Successfully enabled the policy for having the system" \
+                  " booted with."
+        else:
+            print "An error occurred during the operation: %s" % \
+                  xsconstants.xserr2string(rc)
+
 
 def main(argv):
     user_kver = None
@@ -159,24 +196,27 @@ def main(argv):
     if not policy_name_re.match(policy):
         raise OptionError("Illegal policy name: '%s'" % policy)
 
-    policy_file = '/'.join([policy_dir_prefix] + policy.split('.'))
-    src_binary_policy_file = policy_file + ".bin"
-    #check if .bin exists or if policy file exists
-    if not os.path.isfile(src_binary_policy_file):
-        if not os.path.isfile(policy_file + "-security_policy.xml"):
-            raise OptionError("Unknown policy '%s'" % policy)
-        else:
-            err_msg = "Cannot find binary file for policy '%s'." % policy
-            err_msg += " Please use makepolicy to create binary file."
-            raise OptionError(err_msg)
-    
-    dst_binary_policy_file = "/boot/" + policy + ".bin"
-    shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
-    
-    entryname = insert_policy(boot_filename, altboot_filename,
-                              user_title, policy)
-    print "Boot entry '%s' extended and \'%s\' copied to /boot" \
-          % (entryname, policy + ".bin")
+    if xm_main.serverType == xm_main.SERVER_XEN_API:
+        cfgbootpolicy_xapi(policy)
+    else:
+        policy_file = '/'.join([policy_dir_prefix] + policy.split('.'))
+        src_binary_policy_file = policy_file + ".bin"
+        #check if .bin exists or if policy file exists
+        if not os.path.isfile(src_binary_policy_file):
+            if not os.path.isfile(policy_file + "-security_policy.xml"):
+                raise OptionError("Unknown policy '%s'" % policy)
+            else:
+                err_msg = "Cannot find binary file for policy '%s'." % policy
+                err_msg += " Please use makepolicy to create binary file."
+                raise OptionError(err_msg)
+    
+        dst_binary_policy_file = "/boot/" + policy + ".bin"
+        shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
+    
+        entryname = insert_policy(boot_filename, altboot_filename,
+                                  user_title, policy)
+        print "Boot entry '%s' extended and \'%s\' copied to /boot" \
+              % (entryname, policy + ".bin")
 
 if __name__ == '__main__':
     try:
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/create.dtd
--- a/tools/python/xen/xm/create.dtd    Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/create.dtd    Thu Jul 12 09:53:58 2007 +0100
@@ -38,6 +38,7 @@
                  memory,
                  vbd*,
                  vif*,
+                 vtpm*,
                  console*,
                  platform*,
                  vcpu_param*,
@@ -49,7 +50,8 @@
                  actions_after_shutdown %NORMAL_EXIT; #REQUIRED 
                  actions_after_reboot   %NORMAL_EXIT; #REQUIRED
                  actions_after_crash    %CRASH_BEHAVIOUR; #REQUIRED
-                 PCI_bus                CDATA #REQUIRED> 
+                 PCI_bus                CDATA #REQUIRED
+                 security_label         CDATA #IMPLIED>
 
 <!ELEMENT memory EMPTY> 
 <!ATTLIST memory static_min      CDATA #REQUIRED
@@ -73,6 +75,9 @@
                  device          CDATA       #REQUIRED
                  qos_algorithm_type CDATA    #REQUIRED
                  network         CDATA       #IMPLIED> 
+
+<!ELEMENT vtpm   (name*)>
+<!ATTLIST vtpm   backend         CDATA #REQUIRED>
 
 <!ELEMENT console (other_config*)>
 <!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/create.py     Thu Jul 12 09:53:58 2007 +0100
@@ -643,22 +643,12 @@ def configure_security(config, vals):
                                  ['policy', policy],
                                  ['label', label] ]
 
-        #ssidref cannot be specified together with access_control
-        if sxp.child_value(config, 'ssidref'):
-            err("ERROR: SSIDREF and access_control are mutually exclusive but 
both specified!")
-        #else calculate ssidre from label
+        #calculate ssidref from label
         ssidref = security.label2ssidref(label, policy, 'dom')
         if not ssidref :
             err("ERROR calculating ssidref from access_control.")
         security_label = ['security', [ config_access_control, ['ssidref' , 
ssidref ] ] ]
         config.append(security_label)
-    elif num == 0:
-        if hasattr(vals, 'ssidref'):
-            if not security.on():
-                err("ERROR: Security ssidref specified but no policy active.")
-            ssidref = getattr(vals, 'ssidref')
-            security_label = ['security', [ [ 'ssidref' , int(ssidref) ] ] ]
-            config.append(security_label)
     elif num > 1:
         err("VM config error: Multiple access_control definitions!")
 
@@ -1231,13 +1221,13 @@ def config_security_check(config, verbos
 
         except security.ACMError:
             print "   %s: DENIED" % (resource)
-            (res_label, res_policy) = security.get_res_label(resource)
+            (poltype, res_label, res_policy) = security.get_res_label(resource)
             if not res_label:
                 res_label = ""
-            print "   --> res: %s (%s)" % (str(res_label),
-                                           str(res_policy))
-            print "   --> dom: %s (%s)" % (str(domain_label),
-                                           str(domain_policy))
+            print "   --> res: %s (%s:%s)" % (str(res_label),
+                                           str(poltype), str(res_policy))
+            print "   --> dom: %s (%s:%s)" % (str(domain_label),
+                                           str(poltype), str(domain_policy))
 
             answer = 0
 
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/getlabel.py
--- a/tools/python/xen/xm/getlabel.py   Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/getlabel.py   Thu Jul 12 09:53:58 2007 +0100
@@ -21,14 +21,19 @@ import sys, os, re
 import sys, os, re
 from xen.util import dictio
 from xen.util import security
+from xen.util import xsconstants
 from xen.xm.opts import OptionError
+from xen.xm import main as xm_main
+from xen.xm.main import server
 
 def help():
     return """
     Usage: xm getlabel dom <configfile>
+           xm getlabel mgt <domain name>
            xm getlabel res <resource>
            
-    This program shows the label for a domain or resource."""
+    This program shows the label for a domain, resource or virtual network
+    interface of a Xend-managed domain."""
 
 def get_resource_label(resource):
     """Gets the resource label
@@ -37,17 +42,24 @@ def get_resource_label(resource):
     resource = security.unify_resname(resource)
 
     # read in the resource file
-    file = security.res_label_filename
+    fil = security.res_label_filename
     try:
-        access_control = dictio.dict_read("resources", file)
+        access_control = dictio.dict_read("resources", fil)
     except:
         raise OptionError("Resource label file not found")
 
     # get the entry and print label
     if access_control.has_key(resource):
-        policy = access_control[resource][0]
-        label = access_control[resource][1]
-        print "policy="+policy+",label="+label
+        tmp = access_control[resource]
+        if len(tmp) == 2:
+            policy, label = tmp
+            policytype = xsconstants.ACM_POLICY_ID
+        elif len(tmp) == 3:
+            policytype, policy, label = tmp
+        else:
+            raise security.ACMError("Resource not properly labeled. "
+                                    "Please relabel the resource.")
+        print policytype+":"+policy+":"+label
     else:
         raise security.ACMError("Resource not labeled")
 
@@ -89,8 +101,19 @@ def get_domain_label(configfile):
     data = data.strip()
     data = data.lstrip("[\'")
     data = data.rstrip("\']")
-    print data
+    print "policytype=%s," % xsconstants.ACM_POLICY_ID + data
 
+def get_domain_label_xapi(domainname):
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+        raise OptionError('xm needs to be configure to use the xen-api.')
+    uuids = server.xenapi.VM.get_by_name_label(domainname)
+    if len(uuids) == 0:
+        raise OptionError('A VM with that name does not exist.')
+    if len(uuids) != 1:
+        raise OptionError('There are multiple domains with the same name.')
+    uuid = uuids[0]
+    sec_lab = server.xenapi.VM.get_security_label(uuid)
+    print "%s" %sec_lab
 
 def main(argv):
     if len(argv) != 3:
@@ -99,11 +122,15 @@ def main(argv):
     if argv[1].lower() == "dom":
         configfile = argv[2]
         get_domain_label(configfile)
+    elif argv[1].lower() == "mgt":
+        domainname = argv[2]
+        get_domain_label_xapi(domainname)
     elif argv[1].lower() == "res":
         resource = argv[2]
         get_resource_label(resource)
     else:
-        raise OptionError('First subcommand argument must be "dom" or "res"')
+        raise OptionError('First subcommand argument must be "dom"'
+                          ', "mgt" or "res"')
 
 if __name__ == '__main__':
     try:
@@ -111,6 +138,4 @@ if __name__ == '__main__':
     except Exception, e:
         sys.stderr.write('Error: %s\n' % str(e))
         sys.exit(-1)
-        
 
-
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/getpolicy.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xm/getpolicy.py  Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,94 @@
+#============================================================================
+# 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 International Business Machines Corp.
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+#============================================================================
+
+"""Get the managed policy of the system.
+"""
+
+import sys
+from xen.util import xsconstants
+from xml.dom import minidom
+from xen.xm.opts import OptionError
+from xen.util.acmpolicy import ACMPolicy
+from xen.xm import main as xm_main
+from xen.xm.main import server
+
+def help():
+    return """
+    Usage: xm getpolicy [options]
+
+    The following options are defined
+      --dumpxml     Display the XML of the policy
+
+    Get the policy managed by xend."""
+
+def getpolicy(dumpxml):
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+        raise OptionError('xm needs to be configured to use the xen-api.')
+    types = []
+    xstype = int(server.xenapi.XSPolicy.get_xstype())
+    if xstype & xsconstants.XS_POLICY_ACM:
+        types.append("ACM")
+        xstype ^= xsconstants.XS_POLICY_ACM
+    if xstype != 0:
+        types.append("unsupported (%08x)" % xstype)
+    print "Supported security subsystems   : %s \n" % ", ".join(types)
+
+    policystate = server.xenapi.XSPolicy.get_xspolicy()
+    if int(policystate['type']) == 0:
+        print "No policy is installed."
+        return
+    if int(policystate['type']) != xsconstants.XS_POLICY_ACM:
+        print "Unknown policy type '%s'." % policystate['type']
+    else:
+        xml = policystate['repr']
+        acmpol = None
+        if xml:
+            acmpol = ACMPolicy(xml=xml)
+        print "Policy installed on the system:"
+        if acmpol:
+            print "Policy name           : %s" % acmpol.get_name()
+        print "Policy type           : %s" % xsconstants.ACM_POLICY_ID
+        print "Reference             : %s" % policystate['xs_ref']
+        print "Version of XML policy : %s" % policystate['version']
+        state = []
+        flags = int(policystate['flags'])
+        if flags & xsconstants.XS_INST_LOAD:
+            state.append("loaded")
+        if flags & xsconstants.XS_INST_BOOT:
+            state.append("system booted with")
+        print "State of the policy   : %s" % ", ".join(state)
+        if dumpxml:
+            xml = policystate['repr']
+            if xml:
+                dom = minidom.parseString(xml.encode("utf-8"))
+                print "%s" % dom.toprettyxml(indent="   ",newl="\n")
+
+def main(argv):
+    dumpxml = False
+
+    if '--dumpxml' in argv:
+        dumpxml = True
+
+    getpolicy(dumpxml)
+
+if __name__ == '__main__':
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/labels.py
--- a/tools/python/xen/xm/labels.py     Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/labels.py     Thu Jul 12 09:53:58 2007 +0100
@@ -24,6 +24,10 @@ from xen.util.security import ACMError, 
 from xen.util.security import ACMError, err, list_labels, active_policy
 from xen.util.security import vm_label_re, res_label_re, all_label_re
 from xen.xm.opts import OptionError
+from xen.util.acmpolicy import ACMPolicy
+from xen.util import xsconstants
+from xen.xm.main import server
+from xen.xm import main as xm_main
 
 
 def help():
@@ -48,6 +52,12 @@ def main(argv):
         else:
             raise OptionError('Unrecognised option: %s' % arg)
 
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+        labels(policy, ptype)
+    else:
+        labels_xapi(policy, ptype)
+
+def labels(policy, ptype):
     if not policy:
         policy = active_policy
         if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
@@ -73,7 +83,30 @@ def main(argv):
     except:
         traceback.print_exc(limit = 1)
 
+def labels_xapi(policy, ptype):
+    policystate = server.xenapi.XSPolicy.get_xspolicy()
+    if int(policystate['type']) == xsconstants.XS_POLICY_ACM:
+        acmpol = ACMPolicy(xml=policystate['repr'])
+        if policy and policy != acmpol.get_name():
+            print "Warning: '%s' is not the currently loaded policy." % policy
+            return labels(policy, ptype)
+        names1 = []
+        names2 = []
+        if not ptype or ptype == 'dom' or ptype == 'any':
+            names1 = acmpol.policy_get_virtualmachinelabel_names()
+        if ptype == 'res' or ptype == 'any':
+            names2 = acmpol.policy_get_resourcelabel_names()
+        if len(names1) > 0:
+            names = set(names1)
+            names.union(names2)
+        else:
+            names = set(names2)
+        for n in names:
+            print n
+    elif int(policystate['type']) == 0:
+        print "No policy installed on the system."
+    else:
+        print "Unsupported type of policy installed on the system."
+
 if __name__ == '__main__':
     main(sys.argv)
-
-
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/loadpolicy.py Thu Jul 12 09:53:58 2007 +0100
@@ -22,6 +22,11 @@ import traceback
 import traceback
 from xen.util.security import ACMError, err, load_policy
 from xen.xm.opts import OptionError
+from xen.xm import main as xm_main
+from xen.util import xsconstants
+from xen.xm.activatepolicy import activate_policy
+from xen.xm.main import server
+from xen.util.acmpolicy import ACMPolicy
 
 def help():
     return """Load the compiled binary (.bin) policy into the running
@@ -30,8 +35,31 @@ def main(argv):
 def main(argv):
     if len(argv) != 2:
         raise OptionError('No policy defined')
-    
-    load_policy(argv[1])
+    if xm_main.serverType == xm_main.SERVER_XEN_API:
+        policy = argv[1]
+        print "This command is deprecated for use with Xen-API " \
+              "configuration. Consider using\n'xm activatepolicy'."
+        policystate = server.xenapi.XSPolicy.get_xspolicy()
+        if int(policystate['type']) == 0:
+            print "No policy is installed."
+            return
+
+        if int(policystate['type']) != xsconstants.XS_POLICY_ACM:
+            print "Unknown policy type '%s'." % policystate['type']
+            return
+        else:
+            xml = policystate['repr']
+            xs_ref = policystate['xs_ref']
+            if not xml:
+                OptionError("No policy installed on system?")
+            acmpol = ACMPolicy(xml=xml)
+            if acmpol.get_name() != policy:
+                OptionError("Policy installed on system '%s' does not match"\
+                            " the request policy '%s'" % \
+                            (acmpol.get_name(), policy))
+            activate_policy(xsconstants.XS_INST_LOAD)
+    else:
+        load_policy(argv[1])
 
 if __name__ == '__main__':
     try:
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/main.py       Thu Jul 12 09:53:58 2007 +0100
@@ -50,6 +50,7 @@ from xen.xm.opts import OptionError, Opt
 from xen.xm.opts import OptionError, Opts, wrap, set_true
 from xen.xm import console
 from xen.util.xmlrpcclient import ServerProxy
+from xen.util.security import ACMError
 
 import XenAPI
 
@@ -171,11 +172,12 @@ SUBCOMMAND_HELP = {
 
     # security
 
-    'addlabel'      :  ('<label> {dom <ConfigFile>|res <resource>} [<policy>]',
+    'addlabel'      :  ('<label> {dom <ConfigFile>|res <resource>|mgt <managed 
domain>}\n'
+                        '                   [<policy>]',
                         'Add security label to domain.'),
-    'rmlabel'       :  ('{dom <ConfigFile>|res <Resource>}',
+    'rmlabel'       :  ('{dom <ConfigFile>|res <Resource>|mgt<managed 
domain>}',
                         'Remove a security label from domain.'),
-    'getlabel'      :  ('{dom <ConfigFile>|res <Resource>}',
+    'getlabel'      :  ('{dom <ConfigFile>|res <Resource>|mgt <managed 
domain>}',
                         'Show security label for domain or resource.'),
     'dry-run'       :  ('<ConfigFile>',
                         'Test if a domain can access its resources.'),
@@ -186,6 +188,10 @@ SUBCOMMAND_HELP = {
     'loadpolicy'    :  ('<policy.bin>', 'Load binary policy into hypervisor.'),
     'makepolicy'    :  ('<policy>', 'Build policy and create .bin/.map '
                         'files.'),
+    'setpolicy'     :  ('<policytype> <policyfile> [options]',
+                        'Set the policy of the system.'),
+    'getpolicy'     :  ('[options]', 'Get the policy of the system.'),
+    'activatepolicy':  ('[options]', 'Activate the xend-managed policy.'),
     'labels'        :  ('[policy] [type=dom|res|any]',
                         'List <type> labels for (active) policy.'),
     'serve'         :  ('', 'Proxy Xend XMLRPC over stdio.'),
@@ -343,6 +349,9 @@ acm_commands = [
     "loadpolicy",
     "cfgbootpolicy",
     "dumppolicy",
+    "activatepolicy",
+    "setpolicy",
+    "getpolicy",
     ]
 
 all_commands = (domain_commands + host_commands + scheduler_commands +
@@ -861,13 +870,17 @@ def parse_doms_info(info):
         'up_time'  : up_time
         }
 
-    # We're not supporting security stuff just yet via XenAPI
-
     if serverType != SERVER_XEN_API:
         from xen.util import security
         parsed_info['seclabel'] = security.get_security_printlabel(info)
     else:
-        parsed_info['seclabel'] = ""
+        label = get_info('security_label', unicode, '')
+        tmp = label.split(":")
+        if len(tmp) != 3:
+            label = ""
+        else:
+            label = tmp[2]
+        parsed_info['seclabel'] = label
 
     if serverType == SERVER_XEN_API:
         parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
@@ -925,28 +938,26 @@ def xm_brief_list(doms):
         print format % d
 
 def xm_label_list(doms):
-    print '%-32s %5s %5s %5s %5s %9s %-8s' % \
+    print '%-32s %5s %5s %5s %10s %9s %-8s' % \
           ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
     
     output = []
     format = '%(name)-32s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \
              '%(cpu_time)8.1f %(seclabel)9s'
 
-    if serverType != SERVER_XEN_API:
-        from xen.util import security
+    from xen.util import security
         
-        for dom in doms:
-            d = parse_doms_info(dom)
-
-            if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
-                if not d['seclabel']:
-                    d['seclabel'] = 'ERROR'
-            elif security.active_policy in ['DEFAULT']:
-                d['seclabel'] = 'DEFAULT'
-            else:
-                d['seclabel'] = 'INACTIVE'
-
-            output.append((format % d, d['seclabel']))
+    for dom in doms:
+        d = parse_doms_info(dom)
+        if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
+            if not d['seclabel']:
+                d['seclabel'] = 'ERROR'
+        elif security.active_policy in ['DEFAULT']:
+            d['seclabel'] = 'DEFAULT'
+        else:
+            d['seclabel'] = 'INACTIVE'
+
+        output.append((format % d, d['seclabel']))
         
     #sort by labels
     output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
@@ -1989,16 +2000,24 @@ def xm_block_list(args):
                    % ni)
 
 def xm_vtpm_list(args):
-    xenapi_unsupported()
     (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
 
     dom = params[0]
+
+    if serverType == SERVER_XEN_API:
+        vtpm_refs = server.xenapi.VM.get_VTPMs(get_single_vm(dom))
+        vtpm_properties = \
+            map(server.xenapi.VTPM.get_runtime_properties, vtpm_refs)
+        devs = map(lambda (handle, properties): [handle, map2sxp(properties)],
+                   zip(range(len(vtpm_properties)), vtpm_properties))
+    else:
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
+
     if use_long:
-        devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'):
+        for x in devs:
             if hdr == 0:
                 print 'Idx  BE handle state evt-ch ring-ref BE-path'
                 hdr = 1
@@ -2440,6 +2459,9 @@ IMPORTED_COMMANDS = [
     'getlabel',
     'dry-run',
     'resources',
+    'getpolicy',
+    'setpolicy',
+    'activatepolicy',
     ]
 
 for c in IMPORTED_COMMANDS:
@@ -2563,6 +2585,8 @@ def _run_cmd(cmd, cmd_name, args):
         print e.usage
     except XenAPIUnsupportedException, e:
         err(str(e))
+    except ACMError, e:
+        err(str(e))
     except Exception, e:
         if serverType != SERVER_XEN_API:
            from xen.util import security
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/makepolicy.py Thu Jul 12 09:53:58 2007 +0100
@@ -20,7 +20,10 @@ import sys
 import sys
 import traceback
 from xen.util.security import ACMError, err, make_policy
+from xen.util import xsconstants
 from xen.xm.opts import OptionError
+from xen.xm import main as xm_main
+from xen.xm.setpolicy import setpolicy
 
 def usage():
     print "\nUsage: xm makepolicy <policy>\n"
@@ -32,8 +35,13 @@ def main(argv):
 def main(argv):
     if len(argv) != 2:
         raise OptionError('No XML policy file specified')
-
-    make_policy(argv[1])
+    if xm_main.serverType == xm_main.SERVER_XEN_API:
+        print "This command is deprecated for use with Xen-API " \
+              "configuration. Consider using\n'xm setpolicy'."
+        setpolicy(xsconstants.ACM_POLICY_ID, argv[1],
+                  xsconstants.XS_INST_LOAD, True)
+    else:
+        make_policy(argv[1])
 
 if __name__ == '__main__':
     try:
@@ -41,5 +49,3 @@ if __name__ == '__main__':
     except Exception, e:
         sys.stderr.write('Error: %s\n' % str(e))
         sys.exit(-1)
-
-
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/resources.py
--- a/tools/python/xen/xm/resources.py  Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/resources.py  Thu Jul 12 09:53:58 2007 +0100
@@ -21,7 +21,10 @@ import sys
 import sys
 from xen.util import dictio
 from xen.util import security
+from xen.util import xsconstants
 from xen.xm.opts import OptionError
+from xen.xm import main as xm_main
+from xen.xm.main import server
 
 def help():
     return """
@@ -32,20 +35,32 @@ def print_resource_data(access_control):
     """Prints out a resource dictionary to stdout
     """
     for resource in access_control:
-        (policy, label) = access_control[resource]
+        tmp = access_control[resource]
+        if len(tmp) == 2:
+            policytype = xsconstants.ACM_POLICY_ID
+            (policy, label) = access_control[resource]
+        elif len(tmp) == 3:
+            policytype, policy, label = access_control[resource]
         print resource
-        print "    policy: "+policy
-        print "    label:  "+label
+        print "      type: "+ policytype
+        print "    policy: "+ policy
+        print "    label:  "+ label
 
 def main (argv):
     if len(argv) > 1:
         raise OptionError("No arguments required")
-    
-    try:
-        filename = security.res_label_filename
-        access_control = dictio.dict_read("resources", filename)
-    except:
-        raise OptionError("Resource file not found")
+
+    if xm_main.serverType == xm_main.SERVER_XEN_API:
+        access_control = server.xenapi.XSPolicy.get_labeled_resources()
+        for key, value in access_control.items():
+            access_control[key] = tuple(value.split(':'))
+    else:
+        try:
+            filename = security.res_label_filename
+            access_control = dictio.dict_read("resources", filename)
+            print access_control
+        except:
+            raise OptionError("Resource file not found")
 
     print_resource_data(access_control)
 
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py    Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/rmlabel.py    Thu Jul 12 09:53:58 2007 +0100
@@ -22,35 +22,52 @@ from xen.util import dictio
 from xen.util import dictio
 from xen.util import security
 from xen.xm.opts import OptionError
+from xen.xm import main as xm_main
+from xen.xm.main import server
 
 def help():
     return """
     Example: xm rmlabel dom <configfile>
              xm rmlabel res <resource>
+             xm rmlabel mgt <domain name>
 
     This program removes an acm_label entry from the 'configfile'
-    for a domain or from the global resource label file for a
-    resource. If the label does not exist for the given domain or
-    resource, then rmlabel fails."""
+    for a domain, from a Xend-managed domain, from the global resource label
+    file for a resource or from the virtual network interface of a Xend-managed
+    domain. If the label does not exist for the given domain or resource, then
+    rmlabel fails."""
 
 
 def rm_resource_label(resource):
     """Removes a resource label from the global resource label file.
     """
+    # Try Xen-API first if configured to use it
+    if xm_main.serverType == xm_main.SERVER_XEN_API:
+        try:
+            oldlabel = server.xenapi.XSPolicy.get_resource_label(resource)
+            if oldlabel != "":
+                server.xenapi.XSPolicy.set_resource_label(resource,"",
+                                                          oldlabel)
+            else:
+                raise security.ACMError("Resource not labeled")
+        except Exception, e:
+            print "Could not remove label from resource: %s" % e
+        return
+
     #build canonical resource name
     resource = security.unify_resname(resource)
 
     # read in the resource file
-    file = security.res_label_filename
+    fil = security.res_label_filename
     try:
-        access_control = dictio.dict_read("resources", file)
+        access_control = dictio.dict_read("resources", fil)
     except:
         raise security.ACMError("Resource file not found, cannot remove 
label!")
 
     # remove the entry and update file
     if access_control.has_key(resource):
         del access_control[resource]
-        dictio.dict_write(access_control, "resources", file)
+        dictio.dict_write(access_control, "resources", fil)
     else:
         raise security.ACMError("Resource not labeled")
 
@@ -58,15 +75,15 @@ def rm_domain_label(configfile):
 def rm_domain_label(configfile):
     # open the domain config file
     fd = None
-    file = None
+    fil = None
     if configfile[0] == '/':
-        file = configfile
-        fd = open(file, "rb")
+        fil = configfile
+        fd = open(fil, "rb")
     else:
         for prefix in [".", "/etc/xen"]:
-            file = prefix + "/" + configfile
-            if os.path.isfile(file):
-                fd = open(file, "rb")
+            fil = prefix + "/" + configfile
+            if os.path.isfile(fil):
+                fd = open(fil, "rb")
                 break
     if not fd:
         raise OptionError("Configuration file '%s' not found." % configfile)
@@ -93,9 +110,24 @@ def rm_domain_label(configfile):
         raise security.ACMError('Domain not labeled')
 
     # write the data back out to the file
-    fd = open(file, "wb")
+    fd = open(fil, "wb")
     fd.writelines(file_contents)
     fd.close()
+
+def rm_domain_label_xapi(domainname):
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+        raise OptionError('Need to be configure for using xen-api.')
+    uuids = server.xenapi.VM.get_by_name_label(domainname)
+    if len(uuids) == 0:
+        raise OptionError('A VM with that name does not exist.')
+    if len(uuids) != 1:
+        raise OptionError('Too many domains with the same name.')
+    uuid = uuids[0]
+    try:
+        old_lab = server.xenapi.VM.get_security_label(uuid)
+        server.xenapi.VM.set_security_label(uuid, "", old_lab)
+    except Exception, e:
+        print('Could not remove label from domain: %s' % e)
 
 
 def main (argv):
@@ -103,12 +135,15 @@ def main (argv):
     if len(argv) != 3:
         raise OptionError('Requires 2 arguments')
     
-    if argv[1].lower() not in ('dom', 'res'):
+    if argv[1].lower() not in ('dom', 'mgt', 'res'):
         raise OptionError('Unrecognised type argument: %s' % argv[1])
 
     if argv[1].lower() == "dom":
         configfile = argv[2]
         rm_domain_label(configfile)
+    elif argv[1].lower() == "mgt":
+        domain = argv[2]
+        rm_domain_label_xapi(domain)
     elif argv[1].lower() == "res":
         resource = argv[2]
         rm_resource_label(resource)
@@ -119,5 +154,3 @@ if __name__ == '__main__':
     except Exception, e:
         sys.stderr.write('Error: %s\n' % str(e))
         sys.exit(-1)    
-
-
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/setpolicy.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xm/setpolicy.py  Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,117 @@
+#============================================================================
+# 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 International Business Machines Corp.
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+#============================================================================
+
+"""Get the managed policy of the system.
+"""
+
+import base64
+import struct
+import sys
+import string
+from xen.util import xsconstants
+from xen.xm.opts import OptionError
+from xen.util.security import policy_dir_prefix
+from xen.xm import main as xm_main
+from xen.xm.main import server
+
+def help():
+    return """
+    Usage: xm setpolicy <policytype> <policy> [options]
+
+    Set the policy managed by xend.
+
+    The only policytype that is currently supported is 'ACM'.
+
+    The following options are defined
+      --load     Load the policy immediately
+      --boot     Have the system load the policy during boot
+    """
+
+def setpolicy(policytype, policy_name, flags, overwrite):
+    if xm_main.serverType != xm_main.SERVER_XEN_API:
+        raise OptionError('xm needs to be configured to use the xen-api.')
+    if policytype != xsconstants.ACM_POLICY_ID:
+        raise OptionError("Unsupported policytype '%s'." % policytype)
+    else:
+        xs_type = xsconstants.XS_POLICY_ACM
+
+        policy_file = policy_dir_prefix + "/" + \
+                      string.join(string.split(policy_name, "."), "/")
+        policy_file += "-security_policy.xml"
+
+        try:
+            f = open(policy_file,"r")
+            xml = f.read(-1)
+            f.close()
+        except:
+            raise OptionError("Not a valid policy file")
+
+        try:
+            policystate = server.xenapi.XSPolicy.set_xspolicy(xs_type,
+                                                              xml,
+                                                              flags,
+                                                              overwrite)
+        except Exception, e:
+            print "An error occurred setting the policy: %s" % str(e)
+            return
+        xserr = int(policystate['xserr'])
+        if xserr != 0:
+            print "An error occurred trying to set the policy: %s" % \
+                  xsconstants.xserr2string(abs(xserr))
+            errors = policystate['errors']
+            if len(errors) > 0:
+                print "Hypervisor reported errors:"
+                err = base64.b64decode(errors)
+                i = 0
+                while i + 7 < len(err):
+                    code, data = struct.unpack("!ii", errors[i:i+8])
+                    print "(0x%08x, 0x%08x)" % (code, data)
+                    i += 8
+        else:
+            print "Successfully set the new policy."
+
+
+def main(argv):
+    if len(argv) < 3:
+       raise OptionError("Need at least 3 arguments.")
+
+    if "-?" in argv:
+        help()
+        return
+
+    policytype  = argv[1]
+    policy_name = argv[2]
+
+    flags = 0
+    if '--load' in argv:
+        flags |= xsconstants.XS_INST_LOAD
+    if '--boot' in argv:
+        flags |= xsconstants.XS_INST_BOOT
+
+    overwrite = True
+    if '--nooverwrite' in argv:
+        overwrite = False
+
+    setpolicy(policytype, policy_name, flags, overwrite)
+
+if __name__ == '__main__':
+    try:
+        main(sys.argv)
+    except Exception, e:
+        sys.stderr.write('Error: %s\n' % str(e))
+        sys.exit(-1)
diff -r f536eb8576ee -r d0477293897c tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/python/xen/xm/xenapi_create.py      Thu Jul 12 09:53:58 2007 +0100
@@ -25,6 +25,7 @@ from xen.xend.XendAPIConstants import XE
 from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
      XEN_API_ON_CRASH_BEHAVIOUR
 from xen.xm.opts import OptionError
+from xen.util import xsconstants
 
 import sys
 import os
@@ -308,6 +309,12 @@ class xenapi_create:
                ""
             }
 
+        if vm.attributes.has_key("security_label"):
+            vm_record.update({
+                "security_label":
+                    vm.attributes["security_label"].value
+                })
+
         if len(vm.getElementsByTagName("pv")) > 0:
             vm_record.update({
                 "PV_bootloader":
@@ -348,6 +355,12 @@ class xenapi_create:
 
             self.create_vifs(vm_ref, vifs, networks)
 
+            # Now create vtpms
+
+            vtpms = vm.getElementsByTagName("vtpm")
+
+            self.create_vtpms(vm_ref, vtpms)
+
             # Now create consoles
 
             consoles = vm.getElementsByTagName("console")
@@ -441,6 +454,21 @@ class xenapi_create:
             self._network_refs = server.xenapi.network.get_all()
             return self._network_refs.pop(0)
 
+    def create_vtpms(self, vm_ref, vtpms):
+        if len(vtpms) > 1:
+            vtpms = [ vtpms[0] ]
+        log(DEBUG, "create_vtpms")
+        return map(lambda vtpm: self.create_vtpm(vm_ref, vtpm), vtpms)
+
+    def create_vtpm(self, vm_ref, vtpm):
+        vtpm_record = {
+            "VM":
+                vm_ref,
+            "backend":
+                vtpm.attributes["backend"].value
+        }
+        return server.xenapi.VTPM.create(vtpm_record)
+
     def create_consoles(self, vm_ref, consoles):
         log(DEBUG, "create_consoles")
         return map(lambda console: self.create_console(vm_ref, console),
@@ -482,6 +510,10 @@ class sxp2xml:
 
         vifs_sxp = map(lambda x: x[1], [device for device in devices
                                         if device[1][0] == "vif"])
+
+        vtpms_sxp = map(lambda x: x[1], [device for device in devices
+                                         if device[1][0] == "vtpm"])
+
         # Create XML Document
         
         impl = getDOMImplementation()
@@ -530,6 +562,14 @@ class sxp2xml:
             = str(get_child_by_name(config, "vcpus", 1))
         vm.attributes["vcpus_at_startup"] \
             = str(get_child_by_name(config, "vcpus", 1))
+
+        sec_data = get_child_by_name(config, "security")
+        if sec_data:
+            try :
+                vm.attributes['security_label'] = \
+                      "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, 
sec_data[0][1][1],sec_data[0][2][1])
+            except Exception, e:
+                raise "Invalid security data format: %s" % str(sec_data)
 
         # Make the name tag
 
@@ -601,6 +641,12 @@ class sxp2xml:
 
         map(vm.appendChild, vifs)
 
+        # And now the vTPMs
+
+        vtpms = map(lambda vtpm: self.extract_vtpm(vtpm, document), vtpms_sxp)
+
+        map(vm.appendChild, vtpms)
+
         # Last but not least the consoles...
 
         consoles = self.extract_consoles(image, document)
@@ -707,6 +753,15 @@ class sxp2xml:
                 = get_child_by_name(vif_sxp, "bridge")
         
         return vif
+
+    def extract_vtpm(self, vtpm_sxp, document):
+
+        vtpm = document.createElement("vtpm")
+
+        vtpm.attributes["backend"] \
+             = get_child_by_name(vtpm_sxp, "backend", "0")
+
+        return vtpm
 
     _eths = -1
 
diff -r f536eb8576ee -r d0477293897c tools/vtpm_manager/util/hashtable_itr.c
--- a/tools/vtpm_manager/util/hashtable_itr.c   Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/vtpm_manager/util/hashtable_itr.c   Thu Jul 12 09:53:58 2007 +0100
@@ -225,7 +225,7 @@ hashtable_iterator_search(struct hashtab
     
 egress:
 #ifdef HASHTABLE_THREADED
-    pthread_mutex_lock(&h->mutex);
-#endif 
-    return ret;
-}
+    pthread_mutex_unlock(&h->mutex);
+#endif 
+    return ret;
+}
diff -r f536eb8576ee -r d0477293897c tools/xenstore/xsls.c
--- a/tools/xenstore/xsls.c     Wed Jul 11 11:32:30 2007 -0600
+++ b/tools/xenstore/xsls.c     Thu Jul 12 09:53:58 2007 +0100
@@ -8,6 +8,7 @@
 #include <sys/ioctl.h>
 #include <termios.h>
 
+#define STRING_MAX PATH_MAX
 static int max_width = 80;
 static int desired_width = 60;
 
@@ -19,7 +20,8 @@ void print_dir(struct xs_handle *h, char
 void print_dir(struct xs_handle *h, char *path, int cur_depth, int show_perms)
 {
     char **e;
-    char newpath[512], *val;
+    char newpath[STRING_MAX], *val;
+    int newpath_len;
     int i;
     unsigned int num, len;
 
@@ -33,13 +35,26 @@ void print_dir(struct xs_handle *h, char
         unsigned int nperms;
         int linewid;
 
-        for (linewid=0; linewid<cur_depth; linewid++) putchar(' ');
+        /* Print indent and path basename */
+        for (linewid=0; linewid<cur_depth; linewid++) {
+            putchar(' ');
+        }
         linewid += printf("%.*s",
                           (int) (max_width - TAG_LEN - linewid), e[i]);
-        sprintf(newpath, "%s%s%s", path, 
+
+        /* Compose fullpath and fetch value */
+        newpath_len = snprintf(newpath, sizeof(newpath), "%s%s%s", path, 
                 path[strlen(path)-1] == '/' ? "" : "/", 
                 e[i]);
-        val = xs_read(h, XBT_NULL, newpath, &len);
+        if ( newpath_len < sizeof(newpath) ) {
+            val = xs_read(h, XBT_NULL, newpath, &len);
+        }
+        else {
+            /* Path was truncated and thus invalid */
+            val = NULL;
+        }
+
+        /* Print value */
         if (val == NULL) {
             printf(":\n");
         }
@@ -88,7 +103,7 @@ void print_dir(struct xs_handle *h, char
 
 void usage(int argc, char *argv[])
 {
-    fprintf(stderr, "Usage: %s [-p] [path]\n", argv[0]);
+    fprintf(stderr, "Usage: %s [-w] [-p] [path]\n", argv[0]);
 }
 
 int main(int argc, char *argv[])
@@ -104,11 +119,14 @@ int main(int argc, char *argv[])
     if (!ret)
         max_width = ws.ws_col - PAD;
 
-    while (0 < (c = getopt(argc, argv, "ps"))) {
+    while (0 < (c = getopt(argc, argv, "psw"))) {
         switch (c) {
+        case 'w':
+            max_width= STRING_MAX - PAD;
+            desired_width = 0;
+            break;
         case 'p':
             show_perm = 1;
-            max_width -= 16;
             break;
         case 's':
             socket = 1;
@@ -121,6 +139,11 @@ int main(int argc, char *argv[])
         }
     }
 
+    /* Adjust the width here to avoid argument order dependency */
+    if ( show_perm ) {
+        max_width -= 16;
+    }
+
     xsh = socket ? xs_daemon_open() : xs_domain_open();
     if (xsh == NULL)
         err(1, socket ? "xs_daemon_open" : "xs_domain_open");
diff -r f536eb8576ee -r d0477293897c xen/arch/ia64/linux-xen/perfmon.c
--- a/xen/arch/ia64/linux-xen/perfmon.c Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/ia64/linux-xen/perfmon.c Thu Jul 12 09:53:58 2007 +0100
@@ -7729,7 +7729,7 @@ do_perfmon_op(unsigned long cmd,
 {
        unsigned long error = 0;
 
-       if (!NONPRIV_OP(cmd) && current->domain != xenoprof_primary_profiler) {
+       if (!NONPRIV_OP(cmd) && current->domain->domain_id !=0) {
                gdprintk(XENLOG_INFO, "xen perfmon: "
                         "dom %d denied privileged operation %ld\n",
                         current->domain->domain_id, cmd);
diff -r f536eb8576ee -r d0477293897c xen/arch/ia64/xen/oprofile/perfmon.c
--- a/xen/arch/ia64/xen/oprofile/perfmon.c      Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/ia64/xen/oprofile/perfmon.c      Thu Jul 12 09:53:58 2007 +0100
@@ -119,19 +119,10 @@ __exitcall(xenoprof_perfmon_exit);
 ///////////////////////////////////////////////////////////////////////////
 // glue methods for xenoprof and perfmon.
 int
-xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type)
+xenoprof_arch_init(int *num_events, char *cpu_type)
 {
     *num_events = 0;
     strlcpy(cpu_type, get_cpu_type(), XENOPROF_CPU_TYPE_SIZE);
-
-    *is_primary = 0;
-    if (xenoprof_primary_profiler == NULL) {
-        /* For now, only dom0 can be the primary profiler */
-        if (current->domain->domain_id == 0) {
-            *is_primary = 1;
-        }
-    } else if (xenoprof_primary_profiler == current->domain)
-        *is_primary = 1;
     return 0;
 }
 
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/acpi/Makefile
--- a/xen/arch/x86/acpi/Makefile        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/acpi/Makefile        Thu Jul 12 09:53:58 2007 +0100
@@ -1,1 +1,2 @@ obj-y += boot.o
 obj-y += boot.o
+obj-y += power.o suspend.o wakeup_prot.o
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/acpi/power.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/acpi/power.c Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,273 @@
+/* drivers/acpi/sleep/power.c - PM core functionality for Xen
+ *
+ * Copyrights from Linux side:
+ * Copyright (c) 2000-2003 Patrick Mochel
+ * Copyright (C) 2001-2003 Pavel Machek <pavel@xxxxxxx>
+ * Copyright (c) 2003 Open Source Development Lab
+ * Copyright (c) 2004 David Shaohua Li <shaohua.li@xxxxxxxxx>
+ * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@xxxxxxxxx>
+ *
+ * Slimmed with Xen specific support.
+ */
+
+#include <xen/config.h>
+#include <asm/io.h>
+#include <asm/acpi.h>
+#include <xen/acpi.h>
+#include <xen/errno.h>
+#include <xen/iocap.h>
+#include <xen/sched.h>
+#include <asm/acpi.h>
+#include <asm/irq.h>
+#include <asm/init.h>
+#include <xen/spinlock.h>
+#include <xen/sched.h>
+#include <xen/domain.h>
+#include <xen/console.h>
+#include <public/platform.h>
+
+#define pmprintk(_l, _f, _a...) printk(_l "<PM>" _f, ## _a )
+
+u8 sleep_states[ACPI_S_STATE_COUNT];
+DEFINE_SPINLOCK(pm_lock);
+
+struct acpi_sleep_info {
+    uint16_t pm1a_cnt;
+    uint16_t pm1b_cnt;
+    uint16_t pm1a_evt;
+    uint16_t pm1b_evt;
+    uint16_t pm1a_cnt_val;
+    uint16_t pm1b_cnt_val;
+    uint32_t sleep_state;
+} acpi_sinfo;
+
+extern void do_suspend_lowlevel(void);
+
+static char *acpi_states[ACPI_S_STATE_COUNT] =
+{
+    [ACPI_STATE_S1] = "standby",
+    [ACPI_STATE_S3] = "mem",
+    [ACPI_STATE_S4] = "disk",
+};
+
+unsigned long acpi_video_flags;
+unsigned long saved_videomode;
+
+/* XXX: Add suspend failure recover later */
+static int device_power_down(void)
+{
+    console_suspend();
+
+    time_suspend();
+
+    i8259A_suspend();
+    
+    ioapic_suspend();
+    
+    lapic_suspend();
+
+    return 0;
+}
+
+static void device_power_up(void)
+{
+    lapic_resume();
+    
+    ioapic_resume();
+
+    i8259A_resume();
+    
+    time_resume();
+
+    console_resume();
+}
+
+static void freeze_domains(void)
+{
+    struct domain *d;
+
+    for_each_domain(d)
+        if (d->domain_id != 0)
+            domain_pause(d);
+}
+
+static void thaw_domains(void)
+{
+    struct domain *d;
+
+    for_each_domain(d)
+        if (d->domain_id != 0)
+            domain_unpause(d);
+}
+
+/* Main interface to do xen specific suspend/resume */
+int enter_state(u32 state)
+{
+    unsigned long flags;
+    int error;
+
+    if (state <= ACPI_STATE_S0 || state > ACPI_S_STATES_MAX)
+        return -EINVAL;
+
+    /* Sync lazy state on ths cpu */
+    __sync_lazy_execstate();
+    pmprintk(XENLOG_INFO, "Flush lazy state\n");
+
+    if (!spin_trylock(&pm_lock))
+        return -EBUSY;
+    
+    freeze_domains();
+
+    hvm_suspend_cpu();
+
+    pmprintk(XENLOG_INFO, "PM: Preparing system for %s sleep\n",
+        acpi_states[state]);
+
+    local_irq_save(flags);
+
+    if ((error = device_power_down()))
+    {
+        printk(XENLOG_ERR "Some devices failed to power down\n");
+        goto Done;
+    }
+
+    ACPI_FLUSH_CPU_CACHE();
+
+    switch (state)
+    {
+        case ACPI_STATE_S3:
+            do_suspend_lowlevel();
+            break;
+        default:
+            error = -EINVAL;
+            break;
+    }
+
+    pmprintk(XENLOG_INFO, "Back to C!\n");
+
+    device_power_up();
+
+    pmprintk(XENLOG_INFO, "PM: Finishing wakeup.\n");
+
+ Done:
+    local_irq_restore(flags);
+
+    hvm_resume_cpu();
+
+    thaw_domains();
+    spin_unlock(&pm_lock);
+    return error;
+}
+
+/*
+ * Xen just requires address of pm1x_cnt, and ACPI interpreter
+ * is still kept in dom0. Address of xen wakeup stub will be
+ * returned, and then dom0 writes that address to FACS.
+ */
+int set_acpi_sleep_info(struct xenpf_set_acpi_sleep *info)
+{
+    if (acpi_sinfo.pm1a_cnt)
+        pmprintk(XENLOG_WARNING, "Multiple setting on acpi sleep info\n");
+
+    acpi_sinfo.pm1a_cnt = info->pm1a_cnt_port;
+    acpi_sinfo.pm1b_cnt = info->pm1b_cnt_port;
+    acpi_sinfo.pm1a_evt = info->pm1a_evt_port;
+    acpi_sinfo.pm1b_evt = info->pm1b_evt_port;
+    info->xen_waking_vec = (uint64_t)bootsym_phys(wakeup_start);
+
+    pmprintk(XENLOG_INFO, "pm1a[%x],pm1b[%x],pm1a_e[%x],pm1b_e[%x]"
+                       "wake[%"PRIx64"]",
+                       acpi_sinfo.pm1a_cnt, acpi_sinfo.pm1b_cnt,
+                       acpi_sinfo.pm1a_evt, acpi_sinfo.pm1b_evt,
+                       info->xen_waking_vec);
+    return 0;
+}
+
+/*
+ * Dom0 issues this hypercall in place of writing pm1a_cnt. Xen then
+ * takes over the control and put the system into sleep state really.
+ * Also video flags and mode are passed here, in case user may use
+ * "acpi_sleep=***" for video resume.
+ *
+ * Guest may issue a two-phases write to PM1x_CNT, to work
+ * around poorly implemented hardware. It's better to keep
+ * this logic here. Two writes can be differentiated by 
+ * enable bit setting.
+ */
+int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep)
+{
+    if (!IS_PRIV(current->domain) || !acpi_sinfo.pm1a_cnt)
+        return -EPERM;
+
+    /* Sanity check */
+    if (acpi_sinfo.pm1b_cnt_val &&
+        ((sleep->pm1a_cnt_val ^ sleep->pm1b_cnt_val) &
+        ACPI_BITMASK_SLEEP_ENABLE))
+    {
+        pmprintk(XENLOG_ERR, "Mismatched pm1a/pm1b setting\n");
+        return -EINVAL;
+    }
+
+    /* Write #1 */
+    if (!(sleep->pm1a_cnt_val & ACPI_BITMASK_SLEEP_ENABLE))
+    {
+        outw((u16)sleep->pm1a_cnt_val, acpi_sinfo.pm1a_cnt);
+        if (acpi_sinfo.pm1b_cnt)
+            outw((u16)sleep->pm1b_cnt_val, acpi_sinfo.pm1b_cnt);
+        return 0;
+    }
+
+    /* Write #2 */
+    acpi_sinfo.pm1a_cnt_val = sleep->pm1a_cnt_val;
+    acpi_sinfo.pm1b_cnt_val = sleep->pm1b_cnt_val;
+    acpi_sinfo.sleep_state = sleep->sleep_state;
+    acpi_video_flags = sleep->video_flags;
+    saved_videomode = sleep->video_mode;
+
+    return enter_state(acpi_sinfo.sleep_state);
+}
+
+static int acpi_get_wake_status(void)
+{
+    uint16_t val;
+
+    /* Wake status is the 15th bit of PM1 status register. (ACPI spec 3.0) */
+    val = inw(acpi_sinfo.pm1a_evt) | inw(acpi_sinfo.pm1b_evt);
+    val &= ACPI_BITMASK_WAKE_STATUS;
+    val >>= ACPI_BITPOSITION_WAKE_STATUS;
+    return val;
+}
+
+/* System is really put into sleep state by this stub */
+acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
+{
+    ACPI_FLUSH_CPU_CACHE();
+
+    outw((u16)acpi_sinfo.pm1a_cnt_val, acpi_sinfo.pm1a_cnt);
+    if (acpi_sinfo.pm1b_cnt)
+        outw((u16)acpi_sinfo.pm1b_cnt_val, acpi_sinfo.pm1b_cnt);
+    
+    /* Wait until we enter sleep state, and spin until we wake */
+    while (!acpi_get_wake_status());
+    return_ACPI_STATUS(AE_OK);
+}
+
+static int __init acpi_sleep_init(void)
+{
+    int i = 0; 
+
+    pmprintk(XENLOG_INFO, "ACPI (supports");
+    for (i = 0; i < ACPI_S_STATE_COUNT; i++)
+    {
+        if (i == ACPI_STATE_S3)
+        {
+            sleep_states[i] = 1;
+            printk(" S%d", i);
+        }
+        else
+            sleep_states[i] = 0;
+    }
+    printk(")\n");
+    return 0;
+}
+__initcall(acpi_sleep_init);
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/acpi/suspend.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/acpi/suspend.c       Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,85 @@
+/*
+ * Suspend support specific for i386.
+ *
+ * Distribute under GPLv2
+ *
+ * Copyright (c) 2002 Pavel Machek <pavel@xxxxxxx>
+ * Copyright (c) 2001 Patrick Mochel <mochel@xxxxxxxx>
+ */
+#include <xen/config.h>
+#include <xen/acpi.h>
+#include <xen/smp.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/flushtlb.h>
+#include <asm/hvm/hvm.h>
+#include <asm/hvm/support.h>
+#include <asm/i387.h>
+
+/* Following context save/restore happens on the real context
+ * of current vcpu, with a lazy state sync forced earlier. 
+ */
+#if defined(CONFIG_X86_64)
+unsigned long saved_lstar, saved_cstar;
+#endif
+void save_rest_processor_state(void)
+{
+    /*
+     * Net effect of unlazy_fpu is to set cr0.ts and thus there's no
+     * need to restore fpu after resume.
+     */
+    if (!is_idle_vcpu(current))
+        unlazy_fpu(current);
+
+#if defined(CONFIG_X86_64)
+    rdmsrl(MSR_CSTAR, saved_cstar);
+    rdmsrl(MSR_LSTAR, saved_lstar);
+#endif
+
+    bootsym(video_flags) = acpi_video_flags;
+    bootsym(video_mode) = saved_videomode;
+}
+
+#define loaddebug(_v,_reg) \
+    __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
+
+void restore_rest_processor_state(void)
+{
+    int cpu = smp_processor_id();
+    struct tss_struct *t = &init_tss[cpu];
+    struct vcpu *v = current;
+
+    /* Really scared by suffixed comment from Linux, and keep it for safe */
+    set_tss_desc(cpu, t);    /* This just modifies memory; should not be 
necessary. But... This is necessary, because 386 hardware has concept of busy 
TSS or some similar stupidity. */
+
+    load_TR(cpu);
+
+#if defined(CONFIG_X86_64)
+    /* Recover syscall MSRs */
+    wrmsrl(MSR_LSTAR, saved_lstar);
+    wrmsrl(MSR_CSTAR, saved_cstar);
+    wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
+    wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);    
+#else /* !defined(CONFIG_X86_64) */
+    if (supervisor_mode_kernel && cpu_has_sep)
+        wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0);
+#endif
+
+    /* Maybe load the debug registers. */
+    if ( !is_idle_vcpu(v) && unlikely(v->arch.guest_context.debugreg[7]) )
+    {
+        loaddebug(&v->arch.guest_context, 0);
+        loaddebug(&v->arch.guest_context, 1);
+        loaddebug(&v->arch.guest_context, 2);
+        loaddebug(&v->arch.guest_context, 3);
+        /* no 4 and 5 */
+        loaddebug(&v->arch.guest_context, 6);
+        loaddebug(&v->arch.guest_context, 7);
+    }
+
+    /* Do we start fpu really? Just set cr0.ts to monitor it */
+    stts();
+
+    mtrr_ap_init();
+    mcheck_init(&boot_cpu_data);
+}
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/acpi/wakeup_prot.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/acpi/wakeup_prot.S   Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,267 @@
+        .text
+
+#include <xen/config.h>
+#include <xen/multiboot.h>
+#include <public/xen.h>
+#include <asm/asm_defns.h>
+#include <asm/desc.h>
+#include <asm/page.h>
+#include <asm/msr.h>
+
+#if defined(__x86_64__)
+
+        .code64
+
+#define GREG(x)         %r##x
+#define SAVED_GREG(x)   saved_r##x(%rip)
+#define DECLARE_GREG(x) saved_r##x:     .quad   0
+#define SAVE_GREG(x)    movq GREG(x), SAVED_GREG(x)
+#define LOAD_GREG(x)    movq SAVED_GREG(x), GREG(x)
+
+#define REF(x)          x(%rip)
+
+#define RDMSR(ind, m)                   \
+        xorq    %rdx, %rdx;             \
+        mov     $ind, %ecx;             \
+        rdmsr;                          \
+        shlq    $0x20, %rdx;              \
+        orq     %rax, %rdx;             \
+        movq    %rdx, m(%rip);
+
+#define WRMSR(ind, m)                   \
+        mov     $ind, %ecx;             \
+        movq    m(%rip), %rdx;          \
+        mov     %edx, %eax;             \
+        shrq    $0x20, %rdx;              \
+        wrmsr;
+
+#else /* !defined(__x86_64__) */
+
+        .code32
+
+#define GREG(x)         %e##x
+#define SAVED_GREG(x)   saved_e##x
+#define DECLARE_GREG(x) saved_e##x:     .long   0
+#define SAVE_GREG(x)    movl GREG(x), SAVED_GREG(x)
+#define LOAD_GREG(x)    movl SAVED_GREG(x), GREG(x)
+
+#define REF(x)          x
+
+#endif
+
+ENTRY(do_suspend_lowlevel)
+
+        SAVE_GREG(sp)
+        SAVE_GREG(ax)
+        SAVE_GREG(bx)
+        SAVE_GREG(cx)
+        SAVE_GREG(dx)
+        SAVE_GREG(bp)
+        SAVE_GREG(si)
+        SAVE_GREG(di)
+
+#if defined(__x86_64__)
+
+        SAVE_GREG(8)     # save r8...r15
+        SAVE_GREG(9)
+        SAVE_GREG(10)
+        SAVE_GREG(11)
+        SAVE_GREG(12)
+        SAVE_GREG(13)
+        SAVE_GREG(14)
+        SAVE_GREG(15)
+        pushfq;
+        popq    SAVED_GREG(flags)
+
+        mov     %cr8, GREG(ax)
+        mov     GREG(ax), REF(saved_cr8)
+
+        RDMSR(MSR_FS_BASE, saved_fs_base)
+        RDMSR(MSR_GS_BASE, saved_gs_base)
+        RDMSR(MSR_SHADOW_GS_BASE, saved_kernel_gs_base)
+
+#else /* !defined(__x86_64__) */
+
+        pushfl;
+        popl    SAVED_GREG(flags)
+
+#endif
+
+        mov     %ds, REF(saved_ds)
+        mov     %es, REF(saved_es)
+        mov     %fs, REF(saved_fs)
+        mov     %gs, REF(saved_gs)
+        mov     %ss, REF(saved_ss)
+
+        sgdt    REF(saved_gdt)
+        sidt    REF(saved_idt)
+        sldt    REF(saved_ldt)
+
+        mov     %cr0, GREG(ax)
+        mov     GREG(ax), REF(saved_cr0)
+
+        mov     %cr3, GREG(ax)
+        mov     GREG(ax), REF(saved_cr3)
+
+        call    save_rest_processor_state
+
+#if defined(__x86_64__)
+
+        mov     $3, %rdi
+        xor     %eax, %eax
+
+#else /* !defined(__x86_64__) */
+
+        push    $3
+
+#endif
+
+        /* enter sleep state physically */
+        call    acpi_enter_sleep_state
+        jmp     __ret_point
+
+        .align  16
+        .globl  __ret_point
+__ret_point:
+
+        /* mmu_cr4_features contains latest cr4 setting */
+        mov     REF(mmu_cr4_features), GREG(ax)
+        mov     GREG(ax), %cr4
+
+        mov     REF(saved_cr3), GREG(ax)
+        mov     GREG(ax), %cr3
+
+        mov     REF(saved_cr0), GREG(ax)
+        mov     GREG(ax), %cr0
+
+        lgdt    REF(saved_gdt)
+        lidt    REF(saved_idt)
+        lldt    REF(saved_ldt)
+
+        mov     REF(saved_ss), %ss
+        LOAD_GREG(sp)
+
+#if defined(__x86_64__)
+
+        mov     REF(saved_cr8), %rax
+        mov     %rax, %cr8
+
+        pushq   SAVED_GREG(flags)
+        popfq
+
+        /* Idle vcpu doesn't need segment selectors reload, since
+         * those may contain stale value from other domains and 
+         * reload may result page fault due to no matched gdt entry
+         */
+        mov     $(STACK_SIZE - 8), %rax
+        or      %rsp, %rax
+        and     $~7, %rax
+        mov     (%rax), %rax
+        mov     0x10(%rax), %rax
+        cmpw    $0x7fff, (%rax)
+        je      1f
+
+        /* These selectors are from guest, and thus need reload */
+        mov     REF(saved_ds), %ds
+        mov     REF(saved_es), %es
+        mov     REF(saved_fs), %fs
+
+        /* gs load is special */
+        mov     REF(saved_gs), %rsi
+        mov     $3, %rdi        # SEGBASE_GS_USER_SEL
+        call    do_set_segment_base
+
+1:
+        # MSR restore
+        WRMSR(MSR_FS_BASE, saved_fs_base)
+        WRMSR(MSR_GS_BASE, saved_gs_base)
+        WRMSR(MSR_SHADOW_GS_BASE, saved_kernel_gs_base)
+
+#else /* !defined(__x86_64__) */
+
+        pushl   SAVED_GREG(flags)
+        popfl
+
+        /* No reload to fs/gs, which is saved in bottom stack already */
+        mov     REF(saved_ds), %ds
+        mov     REF(saved_es), %es
+
+#endif
+
+        call restore_rest_processor_state
+
+        LOAD_GREG(bp)
+        LOAD_GREG(ax)
+        LOAD_GREG(bx)
+        LOAD_GREG(cx)
+        LOAD_GREG(dx)
+        LOAD_GREG(si)
+        LOAD_GREG(di)
+#if defined(__x86_64__)
+        LOAD_GREG(8)     # save r8...r15
+        LOAD_GREG(9)
+        LOAD_GREG(10)
+        LOAD_GREG(11)
+        LOAD_GREG(12)
+        LOAD_GREG(13)
+        LOAD_GREG(14)
+        LOAD_GREG(15)
+#endif
+        ret 
+
+.data
+        .align 16
+saved_ds:        .word   0
+saved_es:        .word   0
+saved_ss:        .word   0
+saved_gs:        .word   0
+saved_fs:        .word   0
+
+        .align 4
+        .globl   saved_magic
+saved_magic:     .long   0x9abcdef0
+
+        .align 8
+DECLARE_GREG(sp)
+DECLARE_GREG(bp)
+DECLARE_GREG(ax)
+DECLARE_GREG(bx)
+DECLARE_GREG(cx)
+DECLARE_GREG(dx)
+DECLARE_GREG(si)
+DECLARE_GREG(di)
+DECLARE_GREG(flags)
+
+#if defined(__x86_64__)
+
+DECLARE_GREG(8)
+DECLARE_GREG(9)
+DECLARE_GREG(10)
+DECLARE_GREG(11)
+DECLARE_GREG(12)
+DECLARE_GREG(13)
+DECLARE_GREG(14)
+DECLARE_GREG(15)
+
+saved_gdt:      .quad   0,0
+saved_idt:      .quad   0,0
+saved_ldt:      .quad   0,0
+
+saved_cr0:      .quad   0
+saved_cr3:      .quad   0
+saved_cr8:      .quad   0
+
+saved_gs_base:  .quad   0
+saved_fs_base:  .quad   0
+saved_kernel_gs_base:   .quad   0
+
+#else /* !defined(__x86_64__) */
+
+saved_gdt:      .long   0,0
+saved_idt:      .long   0,0
+saved_ldt:      .long   0
+
+saved_cr0:      .long   0
+saved_cr3:      .long   0
+
+#endif 
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/apic.c       Thu Jul 12 09:53:58 2007 +0100
@@ -957,7 +957,7 @@ void __setup_APIC_LVTT(unsigned int cloc
     apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
 }
 
-static void __init setup_APIC_timer(unsigned int clocks)
+static void __devinit setup_APIC_timer(unsigned int clocks)
 {
     unsigned long flags;
     local_irq_save(flags);
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/boot/Makefile
--- a/xen/arch/x86/boot/Makefile        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/boot/Makefile        Thu Jul 12 09:53:58 2007 +0100
@@ -1,3 +1,4 @@ obj-y += head.o
 obj-y += head.o
 
-head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S cmdline.S edd.S
+head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S \
+       cmdline.S edd.S wakeup.S
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/boot/head.S
--- a/xen/arch/x86/boot/head.S  Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/boot/head.S  Thu Jul 12 09:53:58 2007 +0100
@@ -175,9 +175,11 @@ 1:      stosl   /* low mappings cover up
 
 #include "cmdline.S"
 
+        .align 16
         .globl trampoline_start, trampoline_end
 trampoline_start:
 #include "trampoline.S"
+#include "wakeup.S"
 trampoline_end:
 
         .text
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/boot/wakeup.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/boot/wakeup.S        Thu Jul 12 09:53:58 2007 +0100
@@ -0,0 +1,212 @@
+        .code16
+
+#undef wakesym
+/* Used in real mode, to cal offset in current segment */
+#define wakesym(sym) (sym - wakeup_start)
+
+ENTRY(wakeup_start)
+        wakeup_code_start = .
+
+        cli
+        cld
+
+        # setup data segment
+        movw    %cs, %ax
+        movw    %ax, %ds
+        movw    %ax, %ss        # A stack required for BIOS call
+        movw    $wakesym(wakeup_stack), %sp
+
+        pushl   $0              # Kill dangerous flag early
+        popfl
+
+        # check magic number
+        movl    wakesym(real_magic), %eax
+        cmpl    $0x12345678, %eax
+        jne     bogus_real_magic
+
+        # for acpi_sleep=s3_bios
+        testl   $1, wakesym(video_flags)
+        jz      1f
+        lcall   $0xc000, $3
+        movw    %cs, %ax        # In case messed by BIOS
+        movw    %ax, %ds
+        movw    %ax, %ss        # Need this? How to ret if clobbered?
+
+1:      # for acpi_sleep=s3_mode
+        testl   $2, wakesym(video_flags)
+        jz      1f
+        movl    wakesym(video_mode), %eax
+        call    mode_setw
+
+1:      # Show some progress if VGA is resumed
+        movw    $0xb800, %ax
+        movw    %ax, %fs
+        movw    $0x0e00 + 'L', %fs:(0x10)
+
+        # boot trampoline is under 1M, and shift its start into
+        # %fs to reference symbols in that area
+        movl    $BOOT_TRAMPOLINE, %eax
+        shrl    $4, %eax
+        movl    %eax, %fs
+        lidt    %fs:bootsym(idt_48)
+        lgdt    %fs:bootsym(gdt_48)
+
+        movw    $1, %ax
+        lmsw    %ax             # Turn on CR0.PE 
+        jmp     1f
+1:      ljmpl   $BOOT_CS32, $bootsym_phys(wakeup_32)
+
+/* This code uses an extended set of video mode numbers. These include:
+ * Aliases for standard modes
+ *      NORMAL_VGA (-1)
+ *      EXTENDED_VGA (-2)
+ *      ASK_VGA (-3)
+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+ * of compatibility when extending the table. These are between 0x00 and 0xff.
+ */
+#define VIDEO_FIRST_MENU 0x0000
+
+/* Standard BIOS video modes (BIOS number + 0x0100) */
+#define VIDEO_FIRST_BIOS 0x0100
+
+/* VESA BIOS video modes (VESA number + 0x0200) */
+#define VIDEO_FIRST_VESA 0x0200
+
+/* Video7 special modes (BIOS number + 0x0900) */
+#define VIDEO_FIRST_V7 0x0900
+
+# Setting of user mode (AX=mode ID) => CF=success
+mode_setw:
+        movw    %ax, %bx
+        cmpb    $VIDEO_FIRST_VESA>>8, %ah
+        jnc     check_vesaw
+        decb    %ah
+
+setbadw: clc
+        ret
+
+check_vesaw:
+        subb    $VIDEO_FIRST_VESA>>8, %bh
+        orw     $0x4000, %bx                    # Use linear frame buffer
+        movw    $0x4f02, %ax                    # VESA BIOS mode set call
+        int     $0x10
+        cmpw    $0x004f, %ax                    # AL=4f if implemented
+        jnz     _setbadw                        # AH=0 if OK
+
+        stc
+        ret
+
+_setbadw: jmp    setbadw
+
+bogus_real_magic:
+        movw    $0x0e00 + 'B', %fs:(0x12)
+        jmp     bogus_real_magic
+
+        .align 4
+real_magic:     .long 0x12345678
+         .globl video_mode, video_flags
+video_mode:     .long 0
+video_flags:    .long 0
+
+        .code32
+
+        # Now in protect mode, with paging disabled
+        # Add offset for any reference to xen specific symbols
+
+wakeup_32:
+        mov     $BOOT_DS, %eax
+        mov     %eax, %ds
+        mov     %eax, %ss
+        mov     $bootsym_phys(wakeup_stack), %esp
+
+        # check saved magic again
+        mov     $sym_phys(saved_magic), %eax
+        add     bootsym_phys(trampoline_xen_phys_start), %eax
+        mov     (%eax), %eax
+        cmp     $0x9abcdef0, %eax
+        jne     bogus_saved_magic
+        
+        /* fpu init? */
+
+        /* Initialise CR4. */
+#if CONFIG_PAGING_LEVELS == 2
+        mov     $X86_CR4_PSE, %ecx
+#else
+        mov     $X86_CR4_PAE, %ecx
+#endif
+        mov     %ecx, %cr4
+
+        /* Load pagetable base register */
+        mov     $sym_phys(idle_pg_table),%eax
+        add     bootsym_phys(trampoline_xen_phys_start),%eax
+        mov     %eax,%cr3
+
+        /* Will cpuid feature change after resume? */
+#if CONFIG_PAGING_LEVELS != 2
+        /* Set up EFER (Extended Feature Enable Register). */
+        mov     bootsym_phys(cpuid_ext_features),%edi
+        test    $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
+        jz      .Lskip_eferw
+        movl    $MSR_EFER,%ecx
+        rdmsr
+#if CONFIG_PAGING_LEVELS == 4
+        btsl    $_EFER_LME,%eax /* Long Mode      */
+        btsl    $_EFER_SCE,%eax /* SYSCALL/SYSRET */
+#endif
+        btl     $20,%edi        /* No Execute?    */
+        jnc     1f
+        btsl    $_EFER_NX,%eax  /* No Execute     */
+1:      wrmsr
+.Lskip_eferw:
+#endif
+
+        wbinvd
+
+        mov     $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
+        mov     %eax,%cr0
+        jmp     1f
+1:
+
+#if defined(__x86_64__)
+
+        /* Now in compatibility mode. Long-jump to 64-bit mode */
+        ljmp    $BOOT_CS64, $bootsym_phys(wakeup_64)
+
+        .code64
+        .align  8
+        .word   0,0,0
+lgdt_descr:
+        .word   LAST_RESERVED_GDT_BYTE
+        .quad   gdt_table - FIRST_RESERVED_GDT_BYTE
+        
+wakeup_64:
+        lgdt    lgdt_descr(%rip)
+        mov     $(__HYPERVISOR_DS64), %eax
+        mov     %eax, %ds
+
+        # long jump to return point, with cs reload
+        rex64 ljmp    *ret_point(%rip)
+
+        .align 8
+ret_point:
+        .quad   __ret_point
+        .word   __HYPERVISOR_CS64
+
+#else /* !defined(__x86_64__) */
+        lgdt    gdt_descr
+        mov     $(__HYPERVISOR_DS), %eax
+        mov     %eax, %ds
+
+        ljmp    $(__HYPERVISOR_CS), $__ret_point
+#endif
+
+bogus_saved_magic:
+        movw    $0x0e00 + 'S', 0xb8014
+        jmp     bogus_saved_magic
+
+        .align  16
+wakeup_stack_begin:     # Stack grows down
+
+        .fill   PAGE_SIZE,1,0
+wakeup_stack:           # Just below end of first page in this section
+ENTRY(wakeup_end)
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/cpu/common.c Thu Jul 12 09:53:58 2007 +0100
@@ -594,3 +594,11 @@ void __devinit cpu_init(void)
        /* Install correct page table. */
        write_ptbase(current);
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+void __cpuinit cpu_uninit(void)
+{
+       int cpu = raw_smp_processor_id();
+       cpu_clear(cpu, cpu_initialized);
+}
+#endif
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/dmi_scan.c
--- a/xen/arch/x86/dmi_scan.c   Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/dmi_scan.c   Thu Jul 12 09:53:58 2007 +0100
@@ -184,7 +184,6 @@ static __init int reset_videomode_after_
 static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
 {
        /* See acpi_wakeup.S */
-       extern long acpi_video_flags;
        acpi_video_flags |= 2;
        return 0;
 }
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/domain.c     Thu Jul 12 09:53:58 2007 +0100
@@ -76,10 +76,37 @@ static void default_idle(void)
         local_irq_enable();
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+#include <asm/nmi.h>
+/* We don't actually take CPU down, just spin without interrupts. */
+static inline void play_dead(void)
+{
+    __cpu_disable();
+    /* This must be done before dead CPU ack */
+    cpu_exit_clear();
+    wbinvd();
+    mb();
+    /* Ack it */
+    __get_cpu_var(cpu_state) = CPU_DEAD;
+
+    /* With physical CPU hotplug, we should halt the cpu. */
+    local_irq_disable();
+    for ( ; ; )
+        halt();
+}
+#else
+static inline void play_dead(void)
+{
+    BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
 void idle_loop(void)
 {
     for ( ; ; )
     {
+        if (cpu_is_offline(smp_processor_id()))
+            play_dead();
         page_scrub_schedule_work();
         default_idle();
         do_softirq();
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/e820.c
--- a/xen/arch/x86/e820.c       Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/e820.c       Thu Jul 12 09:53:58 2007 +0100
@@ -310,23 +310,22 @@ static unsigned long __init find_max_pfn
     return max_pfn;
 }
 
-#ifdef __i386__
-static void __init clip_4gb(void)
-{
-    unsigned long long limit = (1ULL << 30) * MACHPHYS_MBYTES;
-    int i;
-
-    /* 32-bit systems restricted to a 4GB physical memory map,
-     * with PAE to 16 GB (with current memory layout) */
+static void __init clip_to_limit(uint64_t limit, char *warnmsg)
+{
+    int i;
+    char _warnmsg[160];
+
     for ( i = 0; i < e820.nr_map; i++ )
     {
         if ( (e820.map[i].addr + e820.map[i].size) <= limit )
             continue;
-        printk("WARNING: Only the first %d GB of the physical memory map "
-               "can be accessed\n"
-               "         by Xen in 32-bit mode. "
-               "Truncating the memory map...\n",
-              MACHPHYS_MBYTES);
+        if ( warnmsg )
+        {
+            snprintf(_warnmsg, sizeof(_warnmsg), warnmsg, (int)(limit>>30));
+            printk("WARNING: %s\n", _warnmsg);
+        }
+        printk("Truncating memory map to %lukB\n",
+               (unsigned long)(limit >> 10));
         if ( e820.map[i].addr >= limit )
         {
             e820.nr_map = i;
@@ -336,34 +335,6 @@ static void __init clip_4gb(void)
             e820.map[i].size = limit - e820.map[i].addr;
             e820.nr_map = i + 1;                
         }            
-    }
-}
-#else
-#define clip_4gb() ((void)0)
-#endif
-
-static void __init clip_mem(void)
-{
-    int i;
-
-    if ( !opt_mem )
-        return;
-
-    for ( i = 0; i < e820.nr_map; i++ )
-    {
-        if ( (e820.map[i].addr + e820.map[i].size) <= opt_mem )
-            continue;
-        printk("Truncating memory map to %lukB\n",
-               (unsigned long)(opt_mem >> 10));
-        if ( e820.map[i].addr >= opt_mem )
-        {
-            e820.nr_map = i;
-        }
-        else
-        {
-            e820.map[i].size = opt_mem - e820.map[i].addr;
-            e820.nr_map = i + 1;          
-        }
     }
 }
 
@@ -374,8 +345,22 @@ static void __init machine_specific_memo
     sanitize_e820_map(raw, &nr);
     *raw_nr = nr;
     (void)copy_e820_map(raw, nr);
-    clip_4gb();
-    clip_mem();
+
+    if ( opt_mem )
+        clip_to_limit(opt_mem, NULL);
+
+#ifdef __i386__
+    clip_to_limit((1ULL << 30) * MACHPHYS_MBYTES,
+                  "Only the first %u GB of the physical memory map "
+                  "can be accessed by Xen in 32-bit mode.");
+#endif
+
+#ifdef __x86_64__
+    clip_to_limit((uint64_t)(MACH2PHYS_COMPAT_VIRT_END -
+                             __HYPERVISOR_COMPAT_VIRT_START) << 10,
+                  "Only the first %u GB of the physical memory map "
+                  "can be accessed by 32-on-64 guests.");
+#endif
 }
 
 unsigned long __init init_e820(
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Thu Jul 12 09:53:58 2007 +0100
@@ -78,8 +78,7 @@ void hvm_enable(struct hvm_function_tabl
 
 void hvm_disable(void)
 {
-    if ( hvm_enabled )
-        hvm_funcs.disable();
+    hvm_suspend_cpu();
 }
 
 void hvm_stts(struct vcpu *v)
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Jul 12 09:53:58 2007 +0100
@@ -94,9 +94,8 @@ static void svm_inject_exception(struct 
     vmcb->eventinj = event;
 }
 
-static void stop_svm(void)
-{
-    /* We turn off the EFER_SVME bit. */
+static void svm_suspend_cpu(void)
+{
     write_efer(read_efer() & ~EFER_SVME);
 }
 
@@ -974,7 +973,7 @@ static int svm_event_injection_faulted(s
 
 static struct hvm_function_table svm_function_table = {
     .name                 = "SVM",
-    .disable              = stop_svm,
+    .suspend_cpu          = svm_suspend_cpu,
     .domain_initialise    = svm_domain_initialise,
     .domain_destroy       = svm_domain_destroy,
     .vcpu_initialise      = svm_vcpu_initialise,
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/hvm/vlapic.c Thu Jul 12 09:53:58 2007 +0100
@@ -915,10 +915,17 @@ int vlapic_init(struct vcpu *v)
 int vlapic_init(struct vcpu *v)
 {
     struct vlapic *vlapic = vcpu_vlapic(v);
+    unsigned int memflags = 0;
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id);
 
-    vlapic->regs_page = alloc_domheap_page(NULL);
+#ifdef __i386__
+    /* 32-bit VMX may be limited to 32-bit physical addresses. */
+    if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+        memflags = MEMF_bits(32);
+#endif
+
+    vlapic->regs_page = alloc_domheap_pages(NULL, 0, memflags);
     if ( vlapic->regs_page == NULL )
     {
         dprintk(XENLOG_ERR, "alloc vlapic regs error: %d/%d\n",
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Thu Jul 12 09:53:58 2007 +0100
@@ -45,7 +45,9 @@ u32 vmx_vmentry_control __read_mostly;
 u32 vmx_vmentry_control __read_mostly;
 bool_t cpu_has_vmx_ins_outs_instr_info __read_mostly;
 
+static DEFINE_PER_CPU(struct vmcs_struct *, host_vmcs);
 static DEFINE_PER_CPU(struct vmcs_struct *, current_vmcs);
+static DEFINE_PER_CPU(struct list_head, active_vmcs_list);
 
 static u32 vmcs_revision_id __read_mostly;
 
@@ -151,6 +153,14 @@ void vmx_init_vmcs_config(void)
 
     /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
     BUG_ON((vmx_msr_high & 0x1fff) > PAGE_SIZE);
+
+#ifdef __x86_64__
+    /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */
+    BUG_ON(vmx_msr_high & (1u<<16));
+#endif
+
+    /* Require Write-Back (WB) memory type for VMCS accesses. */
+    BUG_ON(((vmx_msr_high >> 18) & 15) != 6);
 }
 
 static struct vmcs_struct *vmx_alloc_vmcs(void)
@@ -177,34 +187,81 @@ static void __vmx_clear_vmcs(void *info)
 static void __vmx_clear_vmcs(void *info)
 {
     struct vcpu *v = info;
-
-    __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
-
-    v->arch.hvm_vmx.active_cpu = -1;
-    v->arch.hvm_vmx.launched   = 0;
-
-    if ( v->arch.hvm_vmx.vmcs == this_cpu(current_vmcs) )
-        this_cpu(current_vmcs) = NULL;
+    struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
+
+    /* Otherwise we can nest (vmx_suspend_cpu() vs. vmx_clear_vmcs()). */
+    ASSERT(!local_irq_is_enabled());
+
+    if ( arch_vmx->active_cpu == smp_processor_id() )
+    {
+        __vmpclear(virt_to_maddr(arch_vmx->vmcs));
+
+        arch_vmx->active_cpu = -1;
+        arch_vmx->launched   = 0;
+
+        list_del(&arch_vmx->active_list);
+
+        if ( arch_vmx->vmcs == this_cpu(current_vmcs) )
+            this_cpu(current_vmcs) = NULL;
+    }
 }
 
 static void vmx_clear_vmcs(struct vcpu *v)
 {
     int cpu = v->arch.hvm_vmx.active_cpu;
 
-    if ( cpu == -1 )
-        return;
-
-    if ( cpu == smp_processor_id() )
-        return __vmx_clear_vmcs(v);
-
-    on_selected_cpus(cpumask_of_cpu(cpu), __vmx_clear_vmcs, v, 1, 1);
+    if ( cpu != -1 )
+        on_selected_cpus(cpumask_of_cpu(cpu), __vmx_clear_vmcs, v, 1, 1);
 }
 
 static void vmx_load_vmcs(struct vcpu *v)
 {
+    unsigned long flags;
+
+    local_irq_save(flags);
+
+    if ( v->arch.hvm_vmx.active_cpu == -1 )
+    {
+        list_add(&v->arch.hvm_vmx.active_list, &this_cpu(active_vmcs_list));
+        v->arch.hvm_vmx.active_cpu = smp_processor_id();
+    }
+
+    ASSERT(v->arch.hvm_vmx.active_cpu == smp_processor_id());
+
     __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
-    v->arch.hvm_vmx.active_cpu = smp_processor_id();
     this_cpu(current_vmcs) = v->arch.hvm_vmx.vmcs;
+
+    local_irq_restore(flags);
+}
+
+void vmx_suspend_cpu(void)
+{
+    struct list_head *active_vmcs_list = &this_cpu(active_vmcs_list);
+    unsigned long flags;
+
+    local_irq_save(flags);
+
+    while ( !list_empty(active_vmcs_list) )
+        __vmx_clear_vmcs(list_entry(active_vmcs_list->next,
+                                    struct vcpu, arch.hvm_vmx.active_list));
+
+    if ( read_cr4() & X86_CR4_VMXE )
+    {
+        __vmxoff();
+        clear_in_cr4(X86_CR4_VMXE);
+    }
+
+    local_irq_restore(flags);
+}
+
+void vmx_resume_cpu(void)
+{
+    if ( !read_cr4() & X86_CR4_VMXE )
+    {
+        set_in_cr4(X86_CR4_VMXE);
+        if ( __vmxon(virt_to_maddr(this_cpu(host_vmcs))) )
+            BUG();
+    }
 }
 
 void vmx_vmcs_enter(struct vcpu *v)
@@ -239,63 +296,40 @@ void vmx_vmcs_exit(struct vcpu *v)
 
 struct vmcs_struct *vmx_alloc_host_vmcs(void)
 {
-    return vmx_alloc_vmcs();
+    ASSERT(this_cpu(host_vmcs) == NULL);
+    this_cpu(host_vmcs) = vmx_alloc_vmcs();
+    INIT_LIST_HEAD(&this_cpu(active_vmcs_list));
+    return this_cpu(host_vmcs);
 }
 
 void vmx_free_host_vmcs(struct vmcs_struct *vmcs)
 {
+    ASSERT(vmcs == this_cpu(host_vmcs));
     vmx_free_vmcs(vmcs);
-}
-
-#define GUEST_SEGMENT_LIMIT     0xffffffff
-
-struct host_execution_env {
-    /* selectors */
-    unsigned short ldtr_selector;
-    unsigned short tr_selector;
-    unsigned short ds_selector;
-    unsigned short cs_selector;
-    /* limits */
-    unsigned short gdtr_limit;
-    unsigned short ldtr_limit;
-    unsigned short idtr_limit;
-    unsigned short tr_limit;
-    /* base */
-    unsigned long gdtr_base;
-    unsigned long ldtr_base;
-    unsigned long idtr_base;
-    unsigned long tr_base;
-    unsigned long ds_base;
-    unsigned long cs_base;
-#ifdef __x86_64__
-    unsigned long fs_base;
-    unsigned long gs_base;
-#endif
+    this_cpu(host_vmcs) = NULL;
+}
+
+struct xgt_desc {
+    unsigned short size;
+    unsigned long address __attribute__((packed));
 };
 
 static void vmx_set_host_env(struct vcpu *v)
 {
     unsigned int tr, cpu;
-    struct host_execution_env host_env;
-    struct Xgt_desc_struct desc;
+    struct xgt_desc desc;
 
     cpu = smp_processor_id();
-    __asm__ __volatile__ ("sidt  (%0) \n" :: "a"(&desc) : "memory");
-    host_env.idtr_limit = desc.size;
-    host_env.idtr_base = desc.address;
-    __vmwrite(HOST_IDTR_BASE, host_env.idtr_base);
-
-    __asm__ __volatile__ ("sgdt  (%0) \n" :: "a"(&desc) : "memory");
-    host_env.gdtr_limit = desc.size;
-    host_env.gdtr_base = desc.address;
-    __vmwrite(HOST_GDTR_BASE, host_env.gdtr_base);
-
-    __asm__ __volatile__ ("str  (%0) \n" :: "a"(&tr) : "memory");
-    host_env.tr_selector = tr;
-    host_env.tr_limit = sizeof(struct tss_struct);
-    host_env.tr_base = (unsigned long) &init_tss[cpu];
-    __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
-    __vmwrite(HOST_TR_BASE, host_env.tr_base);
+
+    __asm__ __volatile__ ( "sidt (%0) \n" : : "a" (&desc) : "memory" );
+    __vmwrite(HOST_IDTR_BASE, desc.address);
+
+    __asm__ __volatile__ ( "sgdt (%0) \n" : : "a" (&desc) : "memory" );
+    __vmwrite(HOST_GDTR_BASE, desc.address);
+
+    __asm__ __volatile__ ( "str (%0) \n" : : "a" (&tr) : "memory" );
+    __vmwrite(HOST_TR_SELECTOR, tr);
+    __vmwrite(HOST_TR_BASE, (unsigned long)&init_tss[cpu]);
 
     /*
      * Skip end of cpu_user_regs when entering the hypervisor because the
@@ -305,6 +339,8 @@ static void vmx_set_host_env(struct vcpu
     __vmwrite(HOST_RSP,
               (unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code);
 }
+
+#define GUEST_SEGMENT_LIMIT     0xffffffff
 
 static void construct_vmcs(struct vcpu *v)
 {
@@ -448,11 +484,8 @@ static void construct_vmcs(struct vcpu *
 
     if ( cpu_has_vmx_tpr_shadow )
     {
-        paddr_t virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
-        __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
-#if defined (CONFIG_X86_PAE)
-        __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
-#endif
+        __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
+                  page_to_maddr(vcpu_vlapic(v)->regs_page));
         __vmwrite(TPR_THRESHOLD, 0);
     }
 
@@ -472,12 +505,17 @@ static void construct_vmcs(struct vcpu *
 
 int vmx_create_vmcs(struct vcpu *v)
 {
-    if ( v->arch.hvm_vmx.vmcs == NULL )
-    {
-        if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL )
+    struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
+
+    if ( arch_vmx->vmcs == NULL )
+    {
+        if ( (arch_vmx->vmcs = vmx_alloc_vmcs()) == NULL )
             return -ENOMEM;
 
-        __vmx_clear_vmcs(v);
+        INIT_LIST_HEAD(&arch_vmx->active_list);
+        __vmpclear(virt_to_maddr(arch_vmx->vmcs));
+        arch_vmx->active_cpu = -1;
+        arch_vmx->launched   = 0;
     }
 
     construct_vmcs(v);
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Jul 12 09:53:58 2007 +0100
@@ -907,15 +907,6 @@ static void vmx_ctxt_switch_to(struct vc
     vmx_restore_dr(v);
 }
 
-static void stop_vmx(void)
-{
-    if ( !(read_cr4() & X86_CR4_VMXE) )
-        return;
-
-    __vmxoff();
-    clear_in_cr4(X86_CR4_VMXE);
-}
-
 static void vmx_store_cpu_guest_regs(
     struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
 {
@@ -1244,7 +1235,6 @@ static void disable_intercept_for_msr(u3
 
 static struct hvm_function_table vmx_function_table = {
     .name                 = "VMX",
-    .disable              = stop_vmx,
     .domain_initialise    = vmx_domain_initialise,
     .domain_destroy       = vmx_domain_destroy,
     .vcpu_initialise      = vmx_vcpu_initialise,
@@ -1271,7 +1261,9 @@ static struct hvm_function_table vmx_fun
     .inject_exception     = vmx_inject_exception,
     .init_ap_context      = vmx_init_ap_context,
     .init_hypercall_page  = vmx_init_hypercall_page,
-    .event_injection_faulted = vmx_event_injection_faulted
+    .event_injection_faulted = vmx_event_injection_faulted,
+    .suspend_cpu          = vmx_suspend_cpu,
+    .resume_cpu           = vmx_resume_cpu,
 };
 
 int start_vmx(void)
@@ -2718,7 +2710,7 @@ static void vmx_free_vlapic_mapping(stru
 
 static void vmx_install_vlapic_mapping(struct vcpu *v)
 {
-    paddr_t virt_page_ma, apic_page_ma;
+    unsigned long virt_page_ma, apic_page_ma;
 
     if ( !cpu_has_vmx_virtualize_apic_accesses )
         return;
@@ -2730,10 +2722,6 @@ static void vmx_install_vlapic_mapping(s
     vmx_vmcs_enter(v);
     __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
     __vmwrite(APIC_ACCESS_ADDR, apic_page_ma);
-#if defined (CONFIG_X86_PAE)
-    __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
-    __vmwrite(APIC_ACCESS_ADDR_HIGH, apic_page_ma >> 32);
-#endif
     vmx_vmcs_exit(v);
 }
 
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c      Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/i8259.c      Thu Jul 12 09:53:58 2007 +0100
@@ -336,7 +336,7 @@ int i8259A_suspend(void)
     return 0;
 }
 
-void __init init_8259A(int auto_eoi)
+void __devinit init_8259A(int auto_eoi)
 {
     unsigned long flags;
 
@@ -396,6 +396,7 @@ void __init init_IRQ(void)
         irq_desc[i].action  = NULL;
         irq_desc[i].depth   = 1;
         spin_lock_init(&irq_desc[i].lock);
+        cpus_setall(irq_desc[i].affinity);
         set_intr_gate(i, interrupt[i]);
     }
 
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/io_apic.c    Thu Jul 12 09:53:58 2007 +0100
@@ -34,9 +34,6 @@
 #include <asm/desc.h>
 #include <mach_apic.h>
 #include <io_ports.h>
-
-#define set_irq_info(irq, mask) ((void)0)
-#define set_native_irq_info(irq, mask) ((void)0)
 
 /* Different to Linux: our implementation can be simpler. */
 #define make_8259A_irq(irq) (io_apic_irqs &= ~(1<<(irq)))
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/irq.c        Thu Jul 12 09:53:58 2007 +0100
@@ -654,3 +654,36 @@ static int __init setup_dump_irqs(void)
     return 0;
 }
 __initcall(setup_dump_irqs);
+
+#ifdef CONFIG_HOTPLUG_CPU
+#include <asm/mach-generic/mach_apic.h>
+#include <xen/delay.h>
+
+void fixup_irqs(cpumask_t map)
+{
+    unsigned int irq;
+    static int warned;
+
+    for ( irq = 0; irq < NR_IRQS; irq++ )
+    {
+        cpumask_t mask;
+        if ( irq == 2 )
+            continue;
+
+        cpus_and(mask, irq_desc[irq].affinity, map);
+        if ( any_online_cpu(mask) == NR_CPUS )
+        {
+            printk("Breaking affinity for irq %i\n", irq);
+            mask = map;
+        }
+        if ( irq_desc[irq].handler->set_affinity )
+            irq_desc[irq].handler->set_affinity(irq, mask);
+        else if ( irq_desc[irq].action && !(warned++) )
+            printk("Cannot set affinity for irq %i\n", irq);
+    }
+
+    local_irq_enable();
+    mdelay(1);
+    local_irq_disable();
+}
+#endif
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/nmi.c        Thu Jul 12 09:53:58 2007 +0100
@@ -202,7 +202,7 @@ void release_lapic_nmi(void)
         enable_lapic_nmi_watchdog();
 }
 
-#define __pminit __init
+#define __pminit __devinit
 
 /*
  * Activate the NMI watchdog via the local APIC.
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/oprofile/nmi_int.c   Thu Jul 12 09:53:58 2007 +0100
@@ -27,20 +27,15 @@
 #include "op_counter.h"
 #include "op_x86_model.h"
  
+struct op_counter_config counter_config[OP_MAX_COUNTER];
+
 static struct op_x86_model_spec const * model;
 static struct op_msrs cpu_msrs[NR_CPUS];
 static unsigned long saved_lvtpc[NR_CPUS];
 
-#define VIRQ_BITMASK_SIZE (MAX_OPROF_DOMAINS/32 + 1)
-extern int active_domains[MAX_OPROF_DOMAINS];
-extern unsigned int adomains;
-extern struct domain *adomain_ptrs[MAX_OPROF_DOMAINS];
-extern unsigned long virq_ovf_pending[VIRQ_BITMASK_SIZE];
+static char *cpu_type;
+
 extern int is_active(struct domain *d);
-extern int active_id(struct domain *d);
-extern int is_profiled(struct domain *d);
-
-
 
 static int nmi_callback(struct cpu_user_regs *regs, int cpu)
 {
@@ -262,9 +257,7 @@ void nmi_stop(void)
 }
 
 
-struct op_counter_config counter_config[OP_MAX_COUNTER];
-
-static int __init p4_init(char * cpu_type)
+static int __init p4_init(char ** cpu_type)
 { 
        __u8 cpu_model = current_cpu_data.x86_model;
 
@@ -276,20 +269,18 @@ static int __init p4_init(char * cpu_typ
        }
 
 #ifndef CONFIG_SMP
-       strlcpy (cpu_type, "i386/p4", XENOPROF_CPU_TYPE_SIZE);
+       *cpu_type = "i386/p4", XENOPROF_CPU_TYPE_SIZE);
        model = &op_p4_spec;
        return 1;
 #else
        switch (smp_num_siblings) {
                case 1:
-                       strlcpy (cpu_type, "i386/p4", 
-                                XENOPROF_CPU_TYPE_SIZE);
+                       *cpu_type = "i386/p4";
                        model = &op_p4_spec;
                        return 1;
 
                case 2:
-                       strlcpy (cpu_type, "i386/p4-ht", 
-                                XENOPROF_CPU_TYPE_SIZE);
+                       *cpu_type = "i386/p4-ht";
                        model = &op_p4_ht2_spec;
                        return 1;
        }
@@ -300,7 +291,7 @@ static int __init p4_init(char * cpu_typ
 }
 
 
-static int __init ppro_init(char *cpu_type)
+static int __init ppro_init(char ** cpu_type)
 {
        __u8 cpu_model = current_cpu_data.x86_model;
 
@@ -311,41 +302,32 @@ static int __init ppro_init(char *cpu_ty
                return 0;
        }
        else if (cpu_model == 15)
-               strlcpy (cpu_type, "i386/core_2", XENOPROF_CPU_TYPE_SIZE);
+               *cpu_type = "i386/core_2";
        else if (cpu_model == 14)
-               strlcpy (cpu_type, "i386/core", XENOPROF_CPU_TYPE_SIZE);
+               *cpu_type = "i386/core";
        else if (cpu_model == 9)
-               strlcpy (cpu_type, "i386/p6_mobile", XENOPROF_CPU_TYPE_SIZE);
+               *cpu_type = "i386/p6_mobile";
        else if (cpu_model > 5)
-               strlcpy (cpu_type, "i386/piii", XENOPROF_CPU_TYPE_SIZE);
+               *cpu_type = "i386/piii";
        else if (cpu_model > 2)
-               strlcpy (cpu_type, "i386/pii", XENOPROF_CPU_TYPE_SIZE);
+               *cpu_type = "i386/pii";
        else
-               strlcpy (cpu_type, "i386/ppro", XENOPROF_CPU_TYPE_SIZE);
+               *cpu_type = "i386/ppro";
 
        model = &op_ppro_spec;
        return 1;
 }
 
-int nmi_init(int *num_events, int *is_primary, char *cpu_type)
+static int __init nmi_init(void)
 {
        __u8 vendor = current_cpu_data.x86_vendor;
        __u8 family = current_cpu_data.x86;
-       int prim = 0;
  
        if (!cpu_has_apic) {
-               printk("xenoprof: Initialization failed. No apic.\n");
+               printk("xenoprof: Initialization failed. No APIC\n");
                return -ENODEV;
        }
 
-       if (xenoprof_primary_profiler == NULL) {
-               /* For now, only dom0 can be the primary profiler */
-               if (current->domain->domain_id == 0) {
-                       xenoprof_primary_profiler = current->domain;
-                       prim = 1;
-               }
-       }
- 
        switch (vendor) {
                case X86_VENDOR_AMD:
                        /* Needs to be at least an Athlon (or hammer in 32bit 
mode) */
@@ -358,15 +340,13 @@ int nmi_init(int *num_events, int *is_pr
                                return -ENODEV;
                        case 6:
                                model = &op_athlon_spec;
-                               strlcpy (cpu_type, "i386/athlon", 
-                                        XENOPROF_CPU_TYPE_SIZE);
+                               cpu_type = "i386/athlon";
                                break;
                        case 0xf:
                                model = &op_athlon_spec;
-                               /* Actually it could be i386/hammer too, but 
give
-                                  user space an consistent name. */
-                               strlcpy (cpu_type, "x86-64/hammer", 
-                                        XENOPROF_CPU_TYPE_SIZE);
+                               /* Actually it could be i386/hammer too, but
+                                  give user space an consistent name. */
+                               cpu_type = "x86-64/hammer";
                                break;
                        }
                        break;
@@ -375,13 +355,13 @@ int nmi_init(int *num_events, int *is_pr
                        switch (family) {
                                /* Pentium IV */
                                case 0xf:
-                                       if (!p4_init(cpu_type))
+                                       if (!p4_init(&cpu_type))
                                                return -ENODEV;
                                        break;
 
                                /* A P6-class processor */
                                case 6:
-                                       if (!ppro_init(cpu_type))
+                                       if (!ppro_init(&cpu_type))
                                                return -ENODEV;
                                        break;
 
@@ -400,9 +380,16 @@ int nmi_init(int *num_events, int *is_pr
                        return -ENODEV;
        }
 
+       return 0;
+}
+
+__initcall(nmi_init);
+
+int xenoprof_arch_init(int *num_events, char *_cpu_type)
+{
+       if (cpu_type == NULL)
+               return -ENODEV;
        *num_events = model->num_counters;
-       *is_primary = prim;
-
-       return 0;
-}
-
+       strlcpy(_cpu_type, cpu_type, XENOPROF_CPU_TYPE_SIZE);
+       return 0;
+}
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/platform_hypercall.c Thu Jul 12 09:53:58 2007 +0100
@@ -18,6 +18,7 @@
 #include <xen/console.h>
 #include <xen/iocap.h>
 #include <xen/guest_access.h>
+#include <xen/acpi.h>
 #include <asm/current.h>
 #include <public/platform.h>
 #include <asm/edd.h>
@@ -247,6 +248,22 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
         }
         break;
 
+#if 0
+    case XENPF_set_acpi_sleep:
+    {
+        ret = set_acpi_sleep_info(&op->u.set_acpi_sleep);
+        if (!ret && copy_to_guest(u_xenpf_op, op, 1))
+            ret = -EFAULT;
+    }
+    break;
+
+    case XENPF_enter_acpi_sleep:
+    {
+        ret = acpi_enter_sleep(&op->u.enter_acpi_sleep);
+    }
+    break;
+#endif
+
     default:
         ret = -ENOSYS;
         break;
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/smpboot.c    Thu Jul 12 09:53:58 2007 +0100
@@ -110,6 +110,11 @@ EXPORT_SYMBOL(x86_cpu_to_apicid);
 EXPORT_SYMBOL(x86_cpu_to_apicid);
 
 static void map_cpu_to_logical_apicid(void);
+/* State of each CPU. */
+DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
+static void *stack_base[NR_CPUS] __cacheline_aligned;
+spinlock_t cpu_add_remove_lock;
 
 /*
  * The bootstrap kernel entry code has set these up. Save them for
@@ -396,9 +401,11 @@ void __devinit smp_callin(void)
        /*
         *      Synchronize the TSC with the BP
         */
-       if (cpu_has_tsc && cpu_khz && !tsc_sync_disabled)
+       if (cpu_has_tsc && cpu_khz && !tsc_sync_disabled) {
                synchronize_tsc_ap();
-       calibrate_tsc_ap();
+               /* No sync for same reason as above */
+               calibrate_tsc_ap();
+       }
 }
 
 static int cpucount, booting_cpu;
@@ -464,8 +471,12 @@ static void construct_percpu_idt(unsigne
 {
        unsigned char idt_load[10];
 
-       idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
-       memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES*sizeof(idt_entry_t));
+       /* If IDT table exists since last hotplug, reuse it */
+       if (!idt_tables[cpu]) {
+               idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
+               memcpy(idt_tables[cpu], idt_table,
+                               IDT_ENTRIES*sizeof(idt_entry_t));
+       }
 
        *(unsigned short *)(&idt_load[0]) = (IDT_ENTRIES*sizeof(idt_entry_t))-1;
        *(unsigned long  *)(&idt_load[2]) = (unsigned long)idt_tables[cpu];
@@ -488,7 +499,7 @@ void __devinit start_secondary(void *unu
 
        set_processor_id(cpu);
        set_current(idle_vcpu[cpu]);
-        this_cpu(curr_vcpu) = idle_vcpu[cpu];
+       this_cpu(curr_vcpu) = idle_vcpu[cpu];
 
        percpu_traps_init();
 
@@ -516,23 +527,13 @@ void __devinit start_secondary(void *unu
        set_cpu_sibling_map(raw_smp_processor_id());
        wmb();
 
-       /*
-        * We need to hold call_lock, so there is no inconsistency
-        * between the time smp_call_function() determines number of
-        * IPI receipients, and the time when the determination is made
-        * for which cpus receive the IPI. Holding this
-        * lock helps us to not include this cpu in a currently in progress
-        * smp_call_function().
-        */
-       /*lock_ipi_call_lock();*/
        cpu_set(smp_processor_id(), cpu_online_map);
-       /*unlock_ipi_call_lock();*/
-       /*per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;*/
+       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+
+       init_percpu_time();
 
        /* We can take interrupts now: we're officially "up". */
        local_irq_enable();
-
-        init_percpu_time();
 
        wmb();
        startup_cpu_idle_loop();
@@ -794,6 +795,22 @@ static inline int alloc_cpu_id(void)
        return cpu;
 }
 
+static struct vcpu *prepare_idle_vcpu(unsigned int cpu)
+{
+       if (idle_vcpu[cpu])
+               return idle_vcpu[cpu];
+
+       return alloc_idle_vcpu(cpu);
+}
+
+static void *prepare_idle_stack(unsigned int cpu)
+{
+       if (!stack_base[cpu])
+               stack_base[cpu] = alloc_xenheap_pages(STACK_ORDER);
+
+       return stack_base[cpu];
+}
+
 static int __devinit do_boot_cpu(int apicid, int cpu)
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
@@ -811,7 +828,7 @@ static int __devinit do_boot_cpu(int api
 
        booting_cpu = cpu;
 
-       v = alloc_idle_vcpu(cpu);
+       v = prepare_idle_vcpu(cpu);
        BUG_ON(v == NULL);
 
        /* start_eip had better be page-aligned! */
@@ -820,7 +837,7 @@ static int __devinit do_boot_cpu(int api
        /* So we see what's up   */
        printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
 
-       stack_start.esp = alloc_xenheap_pages(STACK_ORDER);
+       stack_start.esp = prepare_idle_stack(cpu);
 
        /* Debug build: detect stack overflow by setting up a guard page. */
        memguard_guard_stack(stack_start.esp);
@@ -897,6 +914,51 @@ static int __devinit do_boot_cpu(int api
        return boot_error;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static void idle_task_exit(void)
+{
+       /* Give up lazy state borrowed by this idle vcpu */
+       __sync_lazy_execstate();
+}
+
+void cpu_exit_clear(void)
+{
+       int cpu = raw_smp_processor_id();
+
+       idle_task_exit();
+
+       cpucount --;
+       cpu_uninit();
+
+       cpu_clear(cpu, cpu_callout_map);
+       cpu_clear(cpu, cpu_callin_map);
+
+       cpu_clear(cpu, smp_commenced_mask);
+       unmap_cpu_to_logical_apicid(cpu);
+}
+
+static int __cpuinit __smp_prepare_cpu(int cpu)
+{
+       int     apicid, ret;
+
+       apicid = x86_cpu_to_apicid[cpu];
+       if (apicid == BAD_APICID) {
+               ret = -ENODEV;
+               goto exit;
+       }
+
+       tsc_sync_disabled = 1;
+
+       do_boot_cpu(apicid, cpu);
+
+       tsc_sync_disabled = 0;
+
+       ret = 0;
+exit:
+       return ret;
+}
+#endif
+
 /*
  * Cycle through the processors sending APIC IPIs to boot each.
  */
@@ -923,6 +985,8 @@ static void __init smp_boot_cpus(unsigne
 
        boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
        x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
+
+       stack_base[0] = stack_start.esp;
 
        /*current_thread_info()->cpu = 0;*/
        /*smp_tune_scheduling();*/
@@ -1094,11 +1158,238 @@ void __devinit smp_prepare_boot_cpu(void
        cpu_set(smp_processor_id(), cpu_callout_map);
        cpu_set(smp_processor_id(), cpu_present_map);
        cpu_set(smp_processor_id(), cpu_possible_map);
-       /*per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;*/
-}
+       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+       spin_lock_init(&cpu_add_remove_lock);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void
+remove_siblinginfo(int cpu)
+{
+       int sibling;
+       struct cpuinfo_x86 *c = cpu_data;
+
+       for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
+               cpu_clear(cpu, cpu_core_map[sibling]);
+               /*
+                * last thread sibling in this cpu core going down
+                */
+               if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+                       c[sibling].booted_cores--;
+       }
+                       
+       for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
+               cpu_clear(cpu, cpu_sibling_map[sibling]);
+       cpus_clear(cpu_sibling_map[cpu]);
+       cpus_clear(cpu_core_map[cpu]);
+       phys_proc_id[cpu] = BAD_APICID;
+       cpu_core_id[cpu] = BAD_APICID;
+       cpu_clear(cpu, cpu_sibling_setup_map);
+}
+
+extern void fixup_irqs(cpumask_t map);
+int __cpu_disable(void)
+{
+       cpumask_t map = cpu_online_map;
+       int cpu = smp_processor_id();
+
+       /*
+        * Perhaps use cpufreq to drop frequency, but that could go
+        * into generic code.
+        *
+        * We won't take down the boot processor on i386 due to some
+        * interrupts only being able to be serviced by the BSP.
+        * Especially so if we're not using an IOAPIC   -zwane
+        */
+       if (cpu == 0)
+               return -EBUSY;
+
+       local_irq_disable();
+       clear_local_APIC();
+       /* Allow any queued timer interrupts to get serviced */
+       local_irq_enable();
+       mdelay(1);
+       local_irq_disable();
+
+       time_suspend();
+
+       remove_siblinginfo(cpu);
+
+       cpu_clear(cpu, map);
+       fixup_irqs(map);
+       /* It's now safe to remove this processor from the online map */
+       cpu_clear(cpu, cpu_online_map);
+       return 0;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+       /* We don't do anything here: idle task is faking death itself. */
+       unsigned int i;
+
+       for (i = 0; i < 10; i++) {
+               /* They ack this in play_dead by setting CPU_DEAD */
+               if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
+                       printk ("CPU %d is now offline\n", cpu);
+                       return;
+               }
+               mdelay(100);
+               mb();
+               process_pending_timers();
+       }
+       printk(KERN_ERR "CPU %u didn't die...\n", cpu);
+}
+
+/* 
+ * XXX: One important thing missed here is to migrate vcpus
+ * from dead cpu to other online ones and then put whole
+ * system into a stop state. It assures a safe environment
+ * for a cpu hotplug/remove at normal running state.
+ *
+ * However for xen PM case, at this point:
+ *     -> All other domains should be notified with PM event,
+ *        and then in following states:
+ *             * Suspend state, or
+ *             * Paused state, which is a force step to all
+ *               domains if they do nothing to suspend
+ *     -> All vcpus of dom0 (except vcpu0) have already beem
+ *        hot removed
+ * with the net effect that all other cpus only have idle vcpu
+ * running. In this special case, we can avoid vcpu migration
+ * then and system can be considered in a stop state.
+ *
+ * So current cpu hotplug is a special version for PM specific
+ * usage, and need more effort later for full cpu hotplug.
+ * (ktian1)
+ */
+int cpu_down(unsigned int cpu)
+{
+       int err = 0;
+       cpumask_t mask;
+
+       spin_lock(&cpu_add_remove_lock);
+       if (num_online_cpus() == 1) {
+               err = -EBUSY;
+               goto out;
+       }
+
+       if (!cpu_online(cpu)) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       printk("Prepare to bring CPU%d down...\n", cpu);
+       /* Send notification to remote idle vcpu */
+       cpus_clear(mask);
+       cpu_set(cpu, mask);
+       per_cpu(cpu_state, cpu) = CPU_DYING;
+       smp_send_event_check_mask(mask);
+
+       __cpu_die(cpu);
+
+       if (cpu_online(cpu)) {
+               printk("Bad state (DEAD, but in online map) on CPU%d\n", cpu);
+               err = -EBUSY;
+       }
+out:
+       spin_unlock(&cpu_add_remove_lock);
+       return err;
+}
+
+int cpu_up(unsigned int cpu)
+{
+       int err = 0;
+
+       spin_lock(&cpu_add_remove_lock);
+       if (cpu_online(cpu)) {
+               printk("Bring up a online cpu. Bogus!\n");
+               err = -EBUSY;
+               goto out;
+       }
+
+       err = __cpu_up(cpu);
+       if (err < 0)
+               goto out;
+
+out:
+       spin_unlock(&cpu_add_remove_lock);
+       return err;
+}
+
+/* From kernel/power/main.c */
+/* This is protected by pm_sem semaphore */
+static cpumask_t frozen_cpus;
+
+void disable_nonboot_cpus(void)
+{
+       int cpu, error;
+
+       error = 0;
+       cpus_clear(frozen_cpus);
+       printk("Freezing cpus ...\n");
+       for_each_online_cpu(cpu) {
+               if (cpu == 0)
+                       continue;
+               error = cpu_down(cpu);
+               if (!error) {
+                       cpu_set(cpu, frozen_cpus);
+                       printk("CPU%d is down\n", cpu);
+                       continue;
+               }
+               printk("Error taking cpu %d down: %d\n", cpu, error);
+       }
+       BUG_ON(raw_smp_processor_id() != 0);
+       if (error)
+               panic("cpus not sleeping");
+}
+
+void enable_nonboot_cpus(void)
+{
+       int cpu, error;
+
+       printk("Thawing cpus ...\n");
+       for_each_cpu_mask(cpu, frozen_cpus) {
+               error = cpu_up(cpu);
+               if (!error) {
+                       printk("CPU%d is up\n", cpu);
+                       continue;
+               }
+               printk("Error taking cpu %d up: %d\n", cpu, error);
+               panic("Not enough cpus");
+       }
+       cpus_clear(frozen_cpus);
+}
+#else /* ... !CONFIG_HOTPLUG_CPU */
+int __cpu_disable(void)
+{
+       return -ENOSYS;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+       /* We said "no" in __cpu_disable */
+       BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
 
 int __devinit __cpu_up(unsigned int cpu)
 {
+#ifdef CONFIG_HOTPLUG_CPU
+       int ret=0;
+
+       /*
+        * We do warm boot only on cpus that had booted earlier
+        * Otherwise cold boot is all handled from smp_boot_cpus().
+        * cpu_callin_map is set during AP kickstart process. Its reset
+        * when a cpu is taken offline from cpu_exit_clear().
+        */
+       if (!cpu_isset(cpu, cpu_callin_map))
+               ret = __smp_prepare_cpu(cpu);
+
+       if (ret)
+               return -EIO;
+#endif
+
        /* In case one didn't come up */
        if (!cpu_isset(cpu, cpu_callin_map)) {
                printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
@@ -1117,6 +1408,7 @@ int __devinit __cpu_up(unsigned int cpu)
        return 0;
 }
 
+
 void __init smp_cpus_done(unsigned int max_cpus)
 {
 #ifdef CONFIG_X86_IO_APIC
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/x86_32/traps.c       Thu Jul 12 09:53:58 2007 +0100
@@ -232,7 +232,7 @@ unsigned long do_iret(void)
     return 0;
 }
 
-void __init percpu_traps_init(void)
+void __devinit percpu_traps_init(void)
 {
     struct tss_struct *tss = &doublefault_tss;
     asmlinkage int hypercall(void);
diff -r f536eb8576ee -r d0477293897c xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/arch/x86/x86_64/traps.c       Thu Jul 12 09:53:58 2007 +0100
@@ -285,7 +285,7 @@ static int write_stack_trampoline(
     return 34;
 }
 
-void __init percpu_traps_init(void)
+void __devinit percpu_traps_init(void)
 {
     char *stack_bottom, *stack;
     int   cpu = smp_processor_id();
diff -r f536eb8576ee -r d0477293897c xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/common/page_alloc.c   Thu Jul 12 09:53:58 2007 +0100
@@ -936,6 +936,21 @@ void free_domheap_pages(struct page_info
         put_domain(d);
 }
 
+unsigned long avail_domheap_pages_region(
+    unsigned int node, unsigned int min_width, unsigned int max_width)
+{
+    int zone_lo, zone_hi;
+
+    zone_lo = min_width ? (min_width - (PAGE_SHIFT + 1)) : (MEMZONE_XEN + 1);
+    zone_lo = max_t(int, MEMZONE_XEN + 1, zone_lo);
+    zone_lo = min_t(int, NR_ZONES - 1, zone_lo);
+
+    zone_hi = max_width ? (max_width - (PAGE_SHIFT + 1)) : (NR_ZONES - 1);
+    zone_hi = max_t(int, MEMZONE_XEN + 1, zone_hi);
+    zone_hi = min_t(int, NR_ZONES - 1, zone_hi);
+
+    return avail_heap_pages(zone_lo, zone_hi, node);
+}
 
 unsigned long avail_domheap_pages(void)
 {
@@ -955,11 +970,6 @@ unsigned long avail_domheap_pages(void)
         avail_dma = 0;
 
     return avail_nrm + avail_dma;
-}
-
-unsigned long avail_nodeheap_pages(int node)
-{
-    return avail_heap_pages(0, NR_ZONES - 1, node);
 }
 
 static void pagealloc_keyhandler(unsigned char key)
diff -r f536eb8576ee -r d0477293897c xen/common/sysctl.c
--- a/xen/common/sysctl.c       Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/common/sysctl.c       Thu Jul 12 09:53:58 2007 +0100
@@ -21,6 +21,8 @@
 #include <xen/keyhandler.h>
 #include <asm/current.h>
 #include <public/sysctl.h>
+#include <asm/numa.h>
+#include <xen/nodemask.h>
 
 extern long arch_do_sysctl(
     struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
@@ -166,6 +168,18 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
 
         if ( copy_to_guest(u_sysctl, op, 1) )
             ret = -EFAULT;
+    }
+    break;
+
+    case XEN_SYSCTL_availheap:
+    { 
+        op->u.availheap.avail_bytes = avail_domheap_pages_region(
+            op->u.availheap.node,
+            op->u.availheap.min_bitwidth,
+            op->u.availheap.max_bitwidth);
+        op->u.availheap.avail_bytes <<= PAGE_SHIFT;
+
+        ret = copy_to_guest(u_sysctl, op, 1) ? -EFAULT : 0;
     }
     break;
 
diff -r f536eb8576ee -r d0477293897c xen/common/xenoprof.c
--- a/xen/common/xenoprof.c     Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/common/xenoprof.c     Thu Jul 12 09:53:58 2007 +0100
@@ -21,26 +21,26 @@
 /* Lock protecting the following global state */
 static DEFINE_SPINLOCK(xenoprof_lock);
 
-struct domain *active_domains[MAX_OPROF_DOMAINS];
-int active_ready[MAX_OPROF_DOMAINS];
-unsigned int adomains;
-
-struct domain *passive_domains[MAX_OPROF_DOMAINS];
-unsigned int pdomains;
-
-unsigned int activated;
-struct domain *xenoprof_primary_profiler;
-int xenoprof_state = XENOPROF_IDLE;
+static struct domain *active_domains[MAX_OPROF_DOMAINS];
+static int active_ready[MAX_OPROF_DOMAINS];
+static unsigned int adomains;
+
+static struct domain *passive_domains[MAX_OPROF_DOMAINS];
+static unsigned int pdomains;
+
+static unsigned int activated;
+static struct domain *xenoprof_primary_profiler;
+static int xenoprof_state = XENOPROF_IDLE;
 static unsigned long backtrace_depth;
 
-u64 total_samples;
-u64 invalid_buffer_samples;
-u64 corrupted_buffer_samples;
-u64 lost_samples;
-u64 active_samples;
-u64 passive_samples;
-u64 idle_samples;
-u64 others_samples;
+static u64 total_samples;
+static u64 invalid_buffer_samples;
+static u64 corrupted_buffer_samples;
+static u64 lost_samples;
+static u64 active_samples;
+static u64 passive_samples;
+static u64 idle_samples;
+static u64 others_samples;
 
 int is_active(struct domain *d)
 {
@@ -48,13 +48,13 @@ int is_active(struct domain *d)
     return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_ACTIVE));
 }
 
-int is_passive(struct domain *d)
+static int is_passive(struct domain *d)
 {
     struct xenoprof *x = d->xenoprof;
     return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_PASSIVE));
 }
 
-int is_profiled(struct domain *d)
+static int is_profiled(struct domain *d)
 {
     return (is_active(d) || is_passive(d));
 }
@@ -543,24 +543,24 @@ void xenoprof_log_event(struct vcpu *vcp
 
 static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
 {
+    struct domain *d = current->domain;
     struct xenoprof_init xenoprof_init;
     int ret;
 
     if ( copy_from_guest(&xenoprof_init, arg, 1) )
         return -EFAULT;
 
-    if ( (ret = xenoprof_arch_init(&xenoprof_init.num_events, 
-                                   &xenoprof_init.is_primary, 
+    if ( (ret = xenoprof_arch_init(&xenoprof_init.num_events,
                                    xenoprof_init.cpu_type)) )
         return ret;
 
-    if ( copy_to_guest(arg, &xenoprof_init, 1) )
-        return -EFAULT;
-
+    xenoprof_init.is_primary = 
+        ((xenoprof_primary_profiler == d) ||
+         ((xenoprof_primary_profiler == NULL) && (d->domain_id == 0)));
     if ( xenoprof_init.is_primary )
         xenoprof_primary_profiler = current->domain;
 
-    return 0;
+    return (copy_to_guest(arg, &xenoprof_init, 1) ? -EFAULT : 0);
 }
 
 #endif /* !COMPAT */
diff -r f536eb8576ee -r d0477293897c xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/drivers/char/ns16550.c        Thu Jul 12 09:53:58 2007 +0100
@@ -170,7 +170,7 @@ static int ns16550_getc(struct serial_po
     return 1;
 }
 
-static void __init ns16550_init_preirq(struct serial_port *port)
+static void __devinit ns16550_init_preirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
     unsigned char lcr;
@@ -214,7 +214,7 @@ static void __init ns16550_init_preirq(s
         port->tx_fifo_size = 16;
 }
 
-static void __init ns16550_init_postirq(struct serial_port *port)
+static void __devinit ns16550_init_postirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
     int rc, bits;
diff -r f536eb8576ee -r d0477293897c xen/drivers/char/serial.c
--- a/xen/drivers/char/serial.c Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/drivers/char/serial.c Thu Jul 12 09:53:58 2007 +0100
@@ -348,7 +348,7 @@ int serial_tx_space(int handle)
     return SERIAL_TXBUFSZ - (port->txbufp - port->txbufc);
 }
 
-void __init serial_init_preirq(void)
+void __devinit serial_init_preirq(void)
 {
     int i;
     for ( i = 0; i < ARRAY_SIZE(com); i++ )
@@ -356,7 +356,7 @@ void __init serial_init_preirq(void)
             com[i].driver->init_preirq(&com[i]);
 }
 
-void __init serial_init_postirq(void)
+void __devinit serial_init_postirq(void)
 {
     int i;
     for ( i = 0; i < ARRAY_SIZE(com); i++ )
diff -r f536eb8576ee -r d0477293897c xen/include/asm-ia64/xenoprof.h
--- a/xen/include/asm-ia64/xenoprof.h   Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-ia64/xenoprof.h   Thu Jul 12 09:53:58 2007 +0100
@@ -24,7 +24,7 @@
 #ifndef __ASM_XENOPROF_H__
 #define __ASM_XENOPROF_H__
 
-int xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type);
+int xenoprof_arch_init(int *num_events, char *cpu_type);
 int xenoprof_arch_reserve_counters(void);
 int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
 int xenoprof_arch_setup_events(void);
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/acpi.h
--- a/xen/include/asm-x86/acpi.h        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/acpi.h        Thu Jul 12 09:53:58 2007 +0100
@@ -173,6 +173,14 @@ extern unsigned long acpi_wakeup_address
 /* early initialization routine */
 extern void acpi_reserve_bootmem(void);
 
+extern unsigned long acpi_video_flags;
+extern unsigned long saved_videomode;
+struct xenpf_set_acpi_sleep;
+struct xenpf_enter_acpi_sleep;
+extern int set_acpi_sleep_info(struct xenpf_set_acpi_sleep *info);
+extern int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep);
+extern int acpi_enter_state(u32 state);
+
 #endif /*CONFIG_ACPI_SLEEP*/
 
 extern u8 x86_acpiid_to_apicid[];
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h      Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/config.h      Thu Jul 12 09:53:58 2007 +0100
@@ -25,9 +25,7 @@
 #define CONFIG_X86_PM_TIMER 1
 #define CONFIG_HPET_TIMER 1
 #define CONFIG_X86_MCE_P4THERMAL 1
-#define CONFIG_ACPI_NUMA 1
 #define CONFIG_NUMA 1
-#define CONFIG_ACPI_SRAT 1
 #define CONFIG_DISCONTIGMEM 1
 #define CONFIG_NUMA_EMU 1
 
@@ -36,8 +34,14 @@
 
 #define CONFIG_ACPI 1
 #define CONFIG_ACPI_BOOT 1
+#define CONFIG_ACPI_SLEEP 1
+#define CONFIG_ACPI_NUMA 1
+#define CONFIG_ACPI_SRAT 1
 
 #define CONFIG_VGA 1
+
+#define CONFIG_HOTPLUG 1
+#define CONFIG_HOTPLUG_CPU 1
 
 #define HZ 100
 
@@ -100,6 +104,8 @@ extern char trampoline_realmode_entry[];
 extern char trampoline_realmode_entry[];
 extern unsigned int trampoline_xen_phys_start;
 extern unsigned char trampoline_cpu_started;
+extern char wakeup_start[];
+extern unsigned int video_mode, video_flags;
 #endif
 
 #if defined(__x86_64__)
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/desc.h
--- a/xen/include/asm-x86/desc.h        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/desc.h        Thu Jul 12 09:53:58 2007 +0100
@@ -203,11 +203,6 @@ extern struct desc_struct compat_gdt_tab
 # define compat_gdt_table gdt_table
 #endif
 
-struct Xgt_desc_struct {
-    unsigned short size;
-    unsigned long address __attribute__((packed));
-};
-
 extern void set_intr_gate(unsigned int irq, void * addr);
 extern void set_system_gate(unsigned int n, void *addr);
 extern void set_task_gate(unsigned int n, unsigned int sel);
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/hvm/hvm.h     Thu Jul 12 09:53:58 2007 +0100
@@ -72,11 +72,6 @@ struct hvm_function_table {
     char *name;
 
     /*
-     *  Disable HVM functionality
-     */
-    void (*disable)(void);
-
-    /*
      * Initialise/destroy HVM domain/vcpu resources
      */
     int  (*domain_initialise)(struct domain *d);
@@ -160,6 +155,9 @@ struct hvm_function_table {
     void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
 
     int  (*event_injection_faulted)(struct vcpu *v);
+
+    void (*suspend_cpu)(void);
+    void (*resume_cpu)(void);
 };
 
 extern struct hvm_function_table hvm_funcs;
@@ -316,4 +314,16 @@ static inline int hvm_event_injection_fa
 /* These exceptions must always be intercepted. */
 #define HVM_TRAP_MASK (1U << TRAP_machine_check)
 
+static inline void hvm_suspend_cpu(void)
+{
+    if ( hvm_funcs.suspend_cpu )
+        hvm_funcs.suspend_cpu();
+}
+
+static inline void hvm_resume_cpu(void)
+{
+    if ( hvm_funcs.resume_cpu )
+        hvm_funcs.resume_cpu();
+}
+
 #endif /* __ASM_X86_HVM_HVM_H__ */
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Jul 12 09:53:58 2007 +0100
@@ -28,6 +28,8 @@ extern void vmcs_dump_vcpu(void);
 extern void vmcs_dump_vcpu(void);
 extern void vmx_init_vmcs_config(void);
 extern void setup_vmcs_dump(void);
+extern void vmx_suspend_cpu(void);
+extern void vmx_resume_cpu(void);
 
 struct vmcs_struct {
     u32 vmcs_revision_id;
@@ -59,6 +61,7 @@ struct arch_vmx_struct {
      *  - Activated on a CPU by VMPTRLD. Deactivated by VMCLEAR.
      *  - Launched on active CPU by VMLAUNCH when current VMCS.
      */
+    struct list_head     active_list;
     int                  active_cpu;
     int                  launched;
 
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/smp.h
--- a/xen/include/asm-x86/smp.h Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/smp.h Thu Jul 12 09:53:58 2007 +0100
@@ -50,9 +50,22 @@ extern u8 x86_cpu_to_apicid[];
 
 #define cpu_physical_id(cpu)   x86_cpu_to_apicid[cpu]
 
+/* State of each CPU. */
+#define CPU_ONLINE     0x0002  /* CPU is up */
+#define CPU_DYING      0x0003  /* CPU is requested to die */
+#define CPU_DEAD       0x0004  /* CPU is dead */
+DECLARE_PER_CPU(int, cpu_state);
+
 #ifdef CONFIG_HOTPLUG_CPU
+#define cpu_is_offline(cpu) unlikely(per_cpu(cpu_state,cpu) == CPU_DYING)
+extern int cpu_down(unsigned int cpu);
+extern int cpu_up(unsigned int cpu);
 extern void cpu_exit_clear(void);
 extern void cpu_uninit(void);
+extern void disable_nonboot_cpus(void);
+extern void enable_nonboot_cpus(void);
+#else
+static inline int cpu_is_offline(int cpu) {return 0;}
 #endif
 
 /*
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/system.h
--- a/xen/include/asm-x86/system.h      Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/system.h      Thu Jul 12 09:53:58 2007 +0100
@@ -313,6 +313,8 @@ static always_inline unsigned long long 
 #define __sti()                        __asm__ __volatile__("sti": : :"memory")
 /* used in the idle loop; sti takes one instruction cycle to complete */
 #define safe_halt()            __asm__ __volatile__("sti; hlt": : :"memory")
+/* used when interrupts are already enabled or to shutdown the processor */
+#define halt()                 __asm__ __volatile__("hlt": : :"memory")
 
 /* For spinlocks etc */
 #if defined(__i386__)
diff -r f536eb8576ee -r d0477293897c xen/include/asm-x86/xenoprof.h
--- a/xen/include/asm-x86/xenoprof.h    Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/asm-x86/xenoprof.h    Thu Jul 12 09:53:58 2007 +0100
@@ -23,7 +23,6 @@
 #ifndef __ASM_X86_XENOPROF_H__
 #define __ASM_X86_XENOPROF_H__
 
-int nmi_init(int *num_events, int *is_primary, char *cpu_type);
 int nmi_reserve_counters(void);
 int nmi_setup_events(void);
 int nmi_enable_virq(void);
@@ -32,8 +31,7 @@ void nmi_disable_virq(void);
 void nmi_disable_virq(void);
 void nmi_release_counters(void);
 
-#define xenoprof_arch_init(num_events, is_primary, cpu_type)    \
-    nmi_init(num_events, is_primary, cpu_type)
+int xenoprof_arch_init(int *num_events, char *cpu_type);
 #define xenoprof_arch_reserve_counters()        nmi_reserve_counters()
 #define xenoprof_arch_setup_events()            nmi_setup_events()
 #define xenoprof_arch_enable_virq()             nmi_enable_virq()
diff -r f536eb8576ee -r d0477293897c xen/include/public/platform.h
--- a/xen/include/public/platform.h     Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/public/platform.h     Thu Jul 12 09:53:58 2007 +0100
@@ -153,6 +153,31 @@ typedef struct xenpf_firmware_info xenpf
 typedef struct xenpf_firmware_info xenpf_firmware_info_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_firmware_info_t);
 
+#define XENPF_set_acpi_sleep      51
+struct xenpf_set_acpi_sleep {
+    /* IN variables. */
+    uint16_t pm1a_cnt_port;
+    uint16_t pm1b_cnt_port;
+    uint16_t pm1a_evt_port;
+    uint16_t pm1b_evt_port;
+    /* OUT variables */
+    uint64_t xen_waking_vec;   /* Tell dom0 to set FACS waking vector */
+};
+typedef struct xenpf_set_acpi_sleep xenpf_set_acpi_sleep_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_set_acpi_sleep_t);
+
+#define XENPF_enter_acpi_sleep    52
+struct xenpf_enter_acpi_sleep {
+    /* IN variables */
+    uint16_t pm1a_cnt_val;
+    uint16_t pm1b_cnt_val;
+    uint32_t sleep_state;       /* Which state to enter */
+    uint32_t video_flags;       /* S3_bios or s3_mode */
+    uint32_t video_mode;        /* Mode setting for s3_mode */
+};
+typedef struct xenpf_enter_acpi_sleep xenpf_enter_acpi_sleep_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_enter_acpi_sleep_t);
+
 struct xen_platform_op {
     uint32_t cmd;
     uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -164,6 +189,8 @@ struct xen_platform_op {
         struct xenpf_microcode_update  microcode;
         struct xenpf_platform_quirk    platform_quirk;
         struct xenpf_firmware_info     firmware_info;
+        struct xenpf_set_acpi_sleep    set_acpi_sleep;
+        struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
         uint8_t                        pad[128];
     } u;
 };
diff -r f536eb8576ee -r d0477293897c xen/include/public/sysctl.h
--- a/xen/include/public/sysctl.h       Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/public/sysctl.h       Thu Jul 12 09:53:58 2007 +0100
@@ -185,6 +185,18 @@ typedef struct xen_sysctl_getcpuinfo xen
 typedef struct xen_sysctl_getcpuinfo xen_sysctl_getcpuinfo_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getcpuinfo_t); 
 
+#define XEN_SYSCTL_availheap         9
+struct xen_sysctl_availheap {
+    /* IN variables. */
+    uint32_t min_bitwidth;  /* Smallest address width (zero if don't care). */
+    uint32_t max_bitwidth;  /* Largest address width (zero if don't care). */
+    int32_t  node;          /* NUMA node of interest (-1 for all nodes). */
+    /* OUT variables. */
+    uint64_t avail_bytes;   /* Bytes available in the specified region. */
+};
+typedef struct xen_sysctl_availheap xen_sysctl_availheap_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_availheap_t);
+ 
 struct xen_sysctl {
     uint32_t cmd;
     uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
@@ -197,6 +209,7 @@ struct xen_sysctl {
         struct xen_sysctl_getdomaininfolist getdomaininfolist;
         struct xen_sysctl_debug_keys        debug_keys;
         struct xen_sysctl_getcpuinfo        getcpuinfo;
+        struct xen_sysctl_availheap         availheap;
         uint8_t                             pad[128];
     } u;
 };
diff -r f536eb8576ee -r d0477293897c xen/include/xen/irq.h
--- a/xen/include/xen/irq.h     Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/xen/irq.h     Thu Jul 12 09:53:58 2007 +0100
@@ -57,6 +57,7 @@ typedef struct {
     struct irqaction *action;  /* IRQ action list */
     unsigned int depth;                /* nested irq disables */
     spinlock_t lock;
+    cpumask_t affinity;
 } __cacheline_aligned irq_desc_t;
 
 extern irq_desc_t irq_desc[NR_IRQS];
@@ -74,4 +75,13 @@ extern int pirq_guest_bind(struct vcpu *
 extern int pirq_guest_bind(struct vcpu *v, int irq, int will_share);
 extern int pirq_guest_unbind(struct domain *d, int irq);
 
+static inline void set_native_irq_info(int irq, cpumask_t mask)
+{
+       irq_desc[irq].affinity = mask;
+}
+
+static inline void set_irq_info(int irq, cpumask_t mask)
+{
+       set_native_irq_info(irq, mask);
+}
 #endif /* __XEN_IRQ_H__ */
diff -r f536eb8576ee -r d0477293897c xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/xen/mm.h      Thu Jul 12 09:53:58 2007 +0100
@@ -61,6 +61,8 @@ struct page_info *__alloc_domheap_pages(
     struct domain *d, unsigned int cpu, unsigned int order, 
     unsigned int memflags);
 void free_domheap_pages(struct page_info *pg, unsigned int order);
+unsigned long avail_domheap_pages_region(
+    unsigned int node, unsigned int min_width, unsigned int max_width);
 unsigned long avail_domheap_pages(void);
 #define alloc_domheap_page(d) (alloc_domheap_pages(d,0,0))
 #define free_domheap_page(p)  (free_domheap_pages(p,0))
diff -r f536eb8576ee -r d0477293897c xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Wed Jul 11 11:32:30 2007 -0600
+++ b/xen/include/xen/xenoprof.h        Thu Jul 12 09:53:58 2007 +0100
@@ -69,6 +69,4 @@ int xenoprof_add_trace(struct domain *d,
 int xenoprof_add_trace(struct domain *d, struct vcpu *v, 
                        unsigned long eip, int mode);
 
-extern struct domain *xenoprof_primary_profiler;
-
 #endif  /* __XEN__XENOPROF_H__ */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Merge with ia64 xen tree., Xen patchbot-unstable <=