From 07f37608884ec519f6b6c77ad8dc38439e5d4629 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 10:22:41 +0100 Subject: [PATCH 01/21] Xen API specification improvements. Move the error list to be more prominent, and explicitly document which generic error codes can be returned by all methods. Mark host CPU flags/features return value as unspecified. Document PERMISSION_DENIED. Document error returns of session.login_with_password. Signed-off-by: John Levon --- docs/xen-api/xenapi-datamodel.tex | 477 ++++++++++++++++-------------- 1 file changed, 254 insertions(+), 223 deletions(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 78cc917a6e..ea9eeb5f33 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -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} + + + + + + faultCode + -1 + + + faultString + Malformed request + + + + + +\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} + + + Status + Failure + + + ErrorDescription + + + + MAP_DUPLICATE_KEY + Customer + eSpeil Inc. + eSpeil Incorporated + + + + + +\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} - - - - - - faultCode - -1 - - - faultString - Malformed request - - - - - -\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} - - - Status - Failure - - - ErrorDescription - - - - MAP_DUPLICATE_KEY - Customer - eSpeil Inc. - eSpeil Incorporated - - - - - -\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} From ad69a7e407343a7ba173dd48b1c7a0db18ccbe04 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 11:10:38 +0100 Subject: [PATCH 02/21] Re-factor e820 truncation code and reintroduce clipping for 32-on-64 guests (to 166GB). Signed-off-by: Keir Fraser --- xen/arch/x86/e820.c | 65 +++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c index 54ebd32762..797ccc0a7e 100644 --- a/xen/arch/x86/e820.c +++ b/xen/arch/x86/e820.c @@ -310,23 +310,22 @@ static unsigned long __init find_max_pfn(void) return max_pfn; } -#ifdef __i386__ -static void __init clip_4gb(void) +static void __init clip_to_limit(uint64_t limit, char *warnmsg) { - unsigned long long limit = (1ULL << 30) * MACHPHYS_MBYTES; int i; + char _warnmsg[160]; - /* 32-bit systems restricted to a 4GB physical memory map, - * with PAE to 16 GB (with current memory layout) */ 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; @@ -338,34 +337,6 @@ static void __init clip_4gb(void) } } } -#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; - } - } -} static void __init machine_specific_memory_setup( struct e820entry *raw, int *raw_nr) @@ -374,8 +345,22 @@ static void __init machine_specific_memory_setup( 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( From 3432f42875288d2d7e2565f0eed3701f02585d28 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 14:42:23 +0100 Subject: [PATCH 03/21] hvm: Fix memcpy_words() asm in ioemu. Signed-off-by: Keir Fraser --- tools/ioemu/target-i386-dm/exec-dm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/ioemu/target-i386-dm/exec-dm.c b/tools/ioemu/target-i386-dm/exec-dm.c index dc4c227355..6a5eb5eaaa 100644 --- a/tools/ioemu/target-i386-dm/exec-dm.c +++ b/tools/ioemu/target-i386-dm/exec-dm.c @@ -446,18 +446,16 @@ extern unsigned long logdirty_bitmap_size; #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 *src, size_t n) " 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) From 24b297caea90977f3fa9956c81c4c0577cce11cf Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 14:57:04 +0100 Subject: [PATCH 04/21] [libxen] C-bindings for the extensions of the Xen-API for managing security policies Signed-off-by: Stefan Berger --- 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 +++++++++++++++ .../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 ++++++++++++++++++ 9 files changed, 1090 insertions(+), 1 deletion(-) create mode 100644 tools/libxen/include/xen/api/xen_acmpolicy.h create mode 100644 tools/libxen/include/xen/api/xen_xspolicy.h create mode 100644 tools/libxen/include/xen/api/xen_xspolicy_decl.h create mode 100644 tools/libxen/src/xen_acmpolicy.c create mode 100644 tools/libxen/src/xen_xspolicy.c diff --git a/tools/libxen/include/xen/api/xen_acmpolicy.h b/tools/libxen/include/xen/api/xen_acmpolicy.h new file mode 100644 index 0000000000..4ac1cfd8e8 --- /dev/null +++ b/tools/libxen/include/xen/api/xen_acmpolicy.h @@ -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 --git a/tools/libxen/include/xen/api/xen_vdi.h b/tools/libxen/include/xen/api/xen_vdi.h index c40dcfc4be..a6ad3039f4 100644 --- a/tools/libxen/include/xen/api/xen_vdi.h +++ b/tools/libxen/include/xen/api/xen_vdi.h @@ -344,4 +344,17 @@ extern bool 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 --git a/tools/libxen/include/xen/api/xen_vm.h b/tools/libxen/include/xen/api/xen_vm.h index 35448afd9f..07b5f51a24 100644 --- a/tools/libxen/include/xen/api/xen_vm.h +++ b/tools/libxen/include/xen/api/xen_vm.h @@ -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 @@ extern bool 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 --git a/tools/libxen/include/xen/api/xen_xspolicy.h b/tools/libxen/include/xen/api/xen_xspolicy.h new file mode 100644 index 0000000000..3ecdc4b54d --- /dev/null +++ b/tools/libxen/include/xen/api/xen_xspolicy.h @@ -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 --git a/tools/libxen/include/xen/api/xen_xspolicy_decl.h b/tools/libxen/include/xen/api/xen_xspolicy_decl.h new file mode 100644 index 0000000000..08e7252128 --- /dev/null +++ b/tools/libxen/include/xen/api/xen_xspolicy_decl.h @@ -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 --git a/tools/libxen/src/xen_acmpolicy.c b/tools/libxen/src/xen_acmpolicy.c new file mode 100644 index 0000000000..1a6190bfee --- /dev/null +++ b/tools/libxen/src/xen_acmpolicy.c @@ -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 +#include + +#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 --git a/tools/libxen/src/xen_vdi.c b/tools/libxen/src/xen_vdi.c index 9c161a4c8d..f2182ccf6c 100644 --- a/tools/libxen/src/xen_vdi.c +++ b/tools/libxen/src/xen_vdi.c @@ -534,3 +534,42 @@ xen_vdi_get_uuid(xen_session *session, char **result, xen_vdi vdi) 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 --git a/tools/libxen/src/xen_vm.c b/tools/libxen/src/xen_vm.c index d3406ab2ec..2b501e56e3 100644 --- a/tools/libxen/src/xen_vm.c +++ b/tools/libxen/src/xen_vm.c @@ -162,7 +162,10 @@ static const struct_member xen_vm_record_struct_members[] = .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, char **result, xen_vm vm) 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 --git a/tools/libxen/src/xen_xspolicy.c b/tools/libxen/src/xen_xspolicy.c new file mode 100644 index 0000000000..2e04e9faa9 --- /dev/null +++ b/tools/libxen/src/xen_xspolicy.c @@ -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 +#include + +#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; +} From afd3d1854cc3896a78dc3d127fc9f153e98c6de2 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 15:41:26 +0100 Subject: [PATCH 05/21] xenoprof: Fix initialisation. Much can be done at boot-time, as indicated by the fact that the low-level functiosn are marked '__init'. Signed-off-by: Keir Fraser --- xen/arch/ia64/linux-xen/perfmon.c | 2 +- xen/arch/ia64/xen/oprofile/perfmon.c | 11 +--- xen/arch/x86/oprofile/nmi_int.c | 79 ++++++++++++---------------- xen/common/xenoprof.c | 48 ++++++++--------- xen/include/asm-ia64/xenoprof.h | 2 +- xen/include/asm-x86/xenoprof.h | 4 +- xen/include/xen/xenoprof.h | 2 - 7 files changed, 61 insertions(+), 87 deletions(-) diff --git a/xen/arch/ia64/linux-xen/perfmon.c b/xen/arch/ia64/linux-xen/perfmon.c index 778f293e71..3a3b13e85d 100644 --- a/xen/arch/ia64/linux-xen/perfmon.c +++ b/xen/arch/ia64/linux-xen/perfmon.c @@ -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 --git a/xen/arch/ia64/xen/oprofile/perfmon.c b/xen/arch/ia64/xen/oprofile/perfmon.c index 4fce815fb0..f9298e056f 100644 --- a/xen/arch/ia64/xen/oprofile/perfmon.c +++ b/xen/arch/ia64/xen/oprofile/perfmon.c @@ -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 --git a/xen/arch/x86/oprofile/nmi_int.c b/xen/arch/x86/oprofile/nmi_int.c index 518691337c..48ade0b7a5 100644 --- a/xen/arch/x86/oprofile/nmi_int.c +++ b/xen/arch/x86/oprofile/nmi_int.c @@ -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_type) } #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_type) } -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_type) 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_primary, char *cpu_type) 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_primary, char *cpu_type) 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_primary, char *cpu_type) return -ENODEV; } - *num_events = model->num_counters; - *is_primary = prim; - 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; + strlcpy(_cpu_type, cpu_type, XENOPROF_CPU_TYPE_SIZE); + return 0; +} diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c index 13dbdd8a04..9212156f02 100644 --- a/xen/common/xenoprof.c +++ b/xen/common/xenoprof.c @@ -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; +static struct domain *active_domains[MAX_OPROF_DOMAINS]; +static int active_ready[MAX_OPROF_DOMAINS]; +static unsigned int adomains; -struct domain *passive_domains[MAX_OPROF_DOMAINS]; -unsigned int pdomains; +static struct domain *passive_domains[MAX_OPROF_DOMAINS]; +static unsigned int pdomains; -unsigned int activated; -struct domain *xenoprof_primary_profiler; -int xenoprof_state = XENOPROF_IDLE; +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 *vcpu, 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 --git a/xen/include/asm-ia64/xenoprof.h b/xen/include/asm-ia64/xenoprof.h index 159716cf05..1d917532b5 100644 --- a/xen/include/asm-ia64/xenoprof.h +++ b/xen/include/asm-ia64/xenoprof.h @@ -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 --git a/xen/include/asm-x86/xenoprof.h b/xen/include/asm-x86/xenoprof.h index 2ce369dd81..d0bc57b5b6 100644 --- a/xen/include/asm-x86/xenoprof.h +++ b/xen/include/asm-x86/xenoprof.h @@ -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_stop(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 --git a/xen/include/xen/xenoprof.h b/xen/include/xen/xenoprof.h index 83e9ec094e..2e47296c7c 100644 --- a/xen/include/xen/xenoprof.h +++ b/xen/include/xen/xenoprof.h @@ -69,6 +69,4 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg); 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__ */ From 380ef0dc36999fe03a96393a1133e344a894d7ec Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 15:45:44 +0100 Subject: [PATCH 06/21] Simplify vmx host state setup code. Signed-off-by: Xin Li --- xen/arch/x86/hvm/vmx/vmcs.c | 54 ++++++++++--------------------------- xen/include/asm-x86/desc.h | 5 ---- 2 files changed, 14 insertions(+), 45 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index e9bf41f3ab..0636502185 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -247,55 +247,27 @@ void vmx_free_host_vmcs(struct vmcs_struct *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 +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__ ( "sidt (%0) \n" : : "a" (&desc) : "memory" ); + __vmwrite(HOST_IDTR_BASE, desc.address); - __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__ ( "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 @@ -306,6 +278,8 @@ static void vmx_set_host_env(struct vcpu *v) (unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code); } +#define GUEST_SEGMENT_LIMIT 0xffffffff + static void construct_vmcs(struct vcpu *v) { unsigned long cr0, cr4; diff --git a/xen/include/asm-x86/desc.h b/xen/include/asm-x86/desc.h index aa354aac38..8817286f60 100644 --- a/xen/include/asm-x86/desc.h +++ b/xen/include/asm-x86/desc.h @@ -203,11 +203,6 @@ extern struct desc_struct compat_gdt_table[]; # 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); From 907d3e969c58187cfdfa7f28b8b65c147077e96b Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 23:37:42 +0100 Subject: [PATCH 07/21] vmx: Never use physical addresses above 4GB for VMCS state on i386. Thsi requires special allocation of the vlapic regs page, but does let us get rid of some top-half writes to a few VMCS fields. Assert a few more facts about the VMX_BASIC_MSR. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/vlapic.c | 9 ++++++++- xen/arch/x86/hvm/vmx/vmcs.c | 15 ++++++++++----- xen/arch/x86/hvm/vmx/vmx.c | 6 +----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 3075ee58a6..712c7c7523 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -915,10 +915,17 @@ HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, lapic_load_regs, 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 --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 0636502185..aee5b0e517 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -151,6 +151,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) @@ -422,11 +430,8 @@ static void construct_vmcs(struct vcpu *v) 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); } diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index b9e3825377..dbe9577103 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2718,7 +2718,7 @@ static void vmx_free_vlapic_mapping(struct domain *d) 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 +2730,6 @@ static void vmx_install_vlapic_mapping(struct vcpu *v) 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); } From eecace9fdefe6879a4dc0fb8254f01cd05a02b8a Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 10 Jul 2007 23:42:13 +0100 Subject: [PATCH 08/21] vmx: Stupid typo in BUG_ON() stmt. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/vmx/vmcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index aee5b0e517..9d446afb17 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -158,7 +158,7 @@ void vmx_init_vmcs_config(void) #endif /* Require Write-Back (WB) memory type for VMCS accesses. */ - BUG_ON(((vmx_msr_high >> 18) & 15) == 6); + BUG_ON(((vmx_msr_high >> 18) & 15) != 6); } static struct vmcs_struct *vmx_alloc_vmcs(void) From fd0ba51b6e64c22177517966ddaedb1f2a179075 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 11 Jul 2007 10:48:15 +0100 Subject: [PATCH 09/21] Make QEMU consistently report write caching support for emulated IDE drives to fix a hang during SLES 9 HVM guest installation. Without this, the SLES 9 installer kernels (32 and 64 bit) were getting inconsistent information from QEMU as to whether the (emulated) IDE drives support write caching (which they do). So part of the kernel thought write caching was enabled (and enabled the usage of barrier writes) and part of it didn't, which triggered a bug in which the same barrier write is submitted over and over again ... Fixed by setting another bit in the WIN_IDENTIFY (IDE drive "identify" command) response to indicate we really, truly support write caching. Signed-off-by: David Lively Signed-off-by: Ben Guthro --- tools/ioemu/hw/ide.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c index f681236b24..3b138c76e4 100644 --- a/tools/ioemu/hw/ide.c +++ b/tools/ioemu/hw/ide.c @@ -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)); From d7839765dc724623b6c5d23a1416599ab1c2c7c7 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 11 Jul 2007 10:49:43 +0100 Subject: [PATCH 10/21] [XM] Tools support for extensions of the Xen-API for managing security policies This patch adds a couple of new commands for using the Xen-API extensions for security policies. Older tools are converted to support going through the Xen-API for their operations rather than doing the operations directly in their own code. Signed-off-by: Stefan Berger --- tools/python/xen/xm/activatepolicy.py | 86 ++++++++++++++++++ tools/python/xen/xm/addlabel.py | 123 ++++++++++++++++++++------ tools/python/xen/xm/cfgbootpolicy.py | 72 +++++++++++---- 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 | 70 ++++++++++----- 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 ++++++++++++ 15 files changed, 745 insertions(+), 127 deletions(-) create mode 100644 tools/python/xen/xm/activatepolicy.py create mode 100644 tools/python/xen/xm/getpolicy.py create mode 100644 tools/python/xen/xm/setpolicy.py diff --git a/tools/python/xen/xm/activatepolicy.py b/tools/python/xen/xm/activatepolicy.py new file mode 100644 index 0000000000..46b1b920eb --- /dev/null +++ b/tools/python/xen/xm/activatepolicy.py @@ -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 +#============================================================================ + +"""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 --git a/tools/python/xen/xm/addlabel.py b/tools/python/xen/xm/addlabel.py index 2d42d6702d..9e93641284 100644 --- a/tools/python/xen/xm/addlabel.py +++ b/tools/python/xen/xm/addlabel.py @@ -25,17 +25,29 @@ import sys 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