[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Merge with ia64 xen tree.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |