# 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
|