ia64/xen-unstable

changeset 14679:fc9e2f7920c9

merge with xen-unstable.hg
author Alex Williamson <alex.williamson@hp.com>
date Fri Mar 30 17:18:42 2007 -0600 (2007-03-30)
parents e7da2fcb7a22 b0b20a09d253
children f378c424e0ce
files xen/arch/ia64/vmx/vmmu.c xen/arch/ia64/vmx/vmx_process.c xen/arch/ia64/xen/domain.c
line diff
     1.1 --- a/.hgignore	Fri Mar 30 10:27:15 2007 -0600
     1.2 +++ b/.hgignore	Fri Mar 30 17:18:42 2007 -0600
     1.3 @@ -126,6 +126,7 @@
     1.4  ^tools/ioemu/qemu\.pod$
     1.5  ^tools/libxc/xen/.*$
     1.6  ^tools/libxen/test/test_bindings$
     1.7 +^tools/libxen/test/test_event_handling$
     1.8  ^tools/libaio/src/.*\.ol$
     1.9  ^tools/libaio/src/.*\.os$
    1.10  ^tools/misc/cpuperf/cpuperf-perfcntr$
     2.1 --- a/Config.mk	Fri Mar 30 10:27:15 2007 -0600
     2.2 +++ b/Config.mk	Fri Mar 30 17:18:42 2007 -0600
     2.3 @@ -31,17 +31,27 @@ EXTRA_INCLUDES += $(EXTRA_PREFIX)/includ
     2.4  EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
     2.5  endif
     2.6  
     2.7 -# cc-option
     2.8 +# cc-option: Check if compiler supports first option, else fall back to second.
     2.9  # Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
    2.10  cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
    2.11                /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
    2.12  
    2.13 -# cc-ver
    2.14 +# cc-ver: Check compiler is at least specified version. Return boolean 'y'/'n'.
    2.15  # Usage: ifeq ($(call cc-ver,$(CC),0x030400),y)
    2.16  cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
    2.17             '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \
    2.18             then echo y; else echo n; fi ;)
    2.19  
    2.20 +# cc-ver-check: Check compiler is at least specified version, else fail.
    2.21 +# Usage: $(call cc-ver-check,CC,0x030400,"Require at least gcc-3.4")
    2.22 +cc-ver-check = $(eval $(call cc-ver-check-closure,$(1),$(2),$(3)))
    2.23 +define cc-ver-check-closure
    2.24 +    ifeq ($$(call cc-ver,$$($(1)),$(2)),n)
    2.25 +        override $(1) = echo "*** FATAL BUILD ERROR: "$(3) >&2; exit 1;
    2.26 +        cc-option := n
    2.27 +    endif
    2.28 +endef
    2.29 +
    2.30  ifneq ($(debug),y)
    2.31  CFLAGS += -DNDEBUG
    2.32  else
     3.1 --- a/docs/xen-api/xenapi-datamodel.tex	Fri Mar 30 10:27:15 2007 -0600
     3.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Fri Mar 30 17:18:42 2007 -0600
     3.3 @@ -24,6 +24,7 @@ Name & Description \\
     3.4  \hline
     3.5  {\tt session} & A session \\
     3.6  {\tt task} & A long-running asynchronous task \\
     3.7 +{\tt event} & Asynchronous event registration and handling \\
     3.8  {\tt VM} & A virtual machine (or 'guest') \\
     3.9  {\tt VM\_metrics} & The metrics associated with a VM \\
    3.10  {\tt VM\_guest\_metrics} & The metrics reported by the guest (as opposed to inferred from outside) \\
    3.11 @@ -112,6 +113,17 @@ The following enumeration types are used
    3.12  
    3.13  \begin{longtable}{|ll|}
    3.14  \hline
    3.15 +{\tt enum event\_operation} & \\
    3.16 +\hline
    3.17 +\hspace{0.5cm}{\tt add} & An object has been created \\
    3.18 +\hspace{0.5cm}{\tt del} & An object has been deleted \\
    3.19 +\hspace{0.5cm}{\tt mod} & An object has been modified \\
    3.20 +\hline
    3.21 +\end{longtable}
    3.22 +
    3.23 +\vspace{1cm}
    3.24 +\begin{longtable}{|ll|}
    3.25 +\hline
    3.26  {\tt enum console\_protocol} & \\
    3.27  \hline
    3.28  \hspace{0.5cm}{\tt vt100} & VT100 terminal \\
    3.29 @@ -1016,6 +1028,116 @@ references to objects with match names
    3.30  
    3.31  \vspace{1cm}
    3.32  \newpage
    3.33 +\section{Class: event}
    3.34 +\subsection{Fields for class: event}
    3.35 +\begin{longtable}{|lllp{0.38\textwidth}|}
    3.36 +\hline
    3.37 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf event} \\
    3.38 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em
    3.39 +Asynchronous event registration and handling.}} \\
    3.40 +\hline
    3.41 +Quals & Field & Type & Description \\
    3.42 +\hline
    3.43 +$\mathit{RO}_\mathit{ins}$ &  {\tt id} & int & An ID, monotonically increasing, and local to the current session \\
    3.44 +$\mathit{RO}_\mathit{ins}$ &  {\tt timestamp} & datetime & The time at which the event occurred \\
    3.45 +$\mathit{RO}_\mathit{ins}$ &  {\tt class} & string & The name of the class of the object that changed \\
    3.46 +$\mathit{RO}_\mathit{ins}$ &  {\tt operation} & event\_operation & The operation that was performed \\
    3.47 +$\mathit{RO}_\mathit{ins}$ &  {\tt ref} & string & A reference to the object that changed \\
    3.48 +$\mathit{RO}_\mathit{ins}$ &  {\tt obj\_uuid} & string & The uuid of the object that changed \\
    3.49 +\hline
    3.50 +\end{longtable}
    3.51 +\subsection{RPCs associated with class: event}
    3.52 +\subsubsection{RPC name:~register}
    3.53 +
    3.54 +{\bf Overview:} 
    3.55 +Registers this session with the event system.  Specifying the empty list
    3.56 +will register for all classes.
    3.57 +
    3.58 + \noindent {\bf Signature:} 
    3.59 +\begin{verbatim} void register (session_id s, string Set classes)\end{verbatim}
    3.60 +
    3.61 +
    3.62 +\noindent{\bf Arguments:}
    3.63 +
    3.64 + 
    3.65 +\vspace{0.3cm}
    3.66 +\begin{tabular}{|c|c|p{7cm}|}
    3.67 + \hline
    3.68 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    3.69 +{\tt string Set } & classes & register for events for the indicated classes \\ \hline 
    3.70 +
    3.71 +\end{tabular}
    3.72 +
    3.73 +\vspace{0.3cm}
    3.74 +
    3.75 + \noindent {\bf Return Type:} 
    3.76 +{\tt 
    3.77 +void
    3.78 +}
    3.79 +
    3.80 +
    3.81 +
    3.82 +\vspace{0.3cm}
    3.83 +\vspace{0.3cm}
    3.84 +\vspace{0.3cm}
    3.85 +\subsubsection{RPC name:~unregister}
    3.86 +
    3.87 +{\bf Overview:} 
    3.88 +Unregisters this session with the event system.
    3.89 +
    3.90 + \noindent {\bf Signature:} 
    3.91 +\begin{verbatim} void unregister (session_id s, string Set classes)\end{verbatim}
    3.92 +
    3.93 +
    3.94 +\noindent{\bf Arguments:}
    3.95 +
    3.96 + 
    3.97 +\vspace{0.3cm}
    3.98 +\begin{tabular}{|c|c|p{7cm}|}
    3.99 + \hline
   3.100 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   3.101 +{\tt string Set } & classes & remove this session's registration for the indicated classes \\ \hline 
   3.102 +
   3.103 +\end{tabular}
   3.104 +
   3.105 +\vspace{0.3cm}
   3.106 +
   3.107 + \noindent {\bf Return Type:} 
   3.108 +{\tt 
   3.109 +void
   3.110 +}
   3.111 +
   3.112 +
   3.113 +
   3.114 +\vspace{0.3cm}
   3.115 +\vspace{0.3cm}
   3.116 +\vspace{0.3cm}
   3.117 +\subsubsection{RPC name:~next}
   3.118 +
   3.119 +{\bf Overview:} 
   3.120 +Blocking call which returns a (possibly empty) batch of events.
   3.121 +
   3.122 + \noindent {\bf Signature:} 
   3.123 +\begin{verbatim} ((event record) Set) next (session_id s)\end{verbatim}
   3.124 +
   3.125 +
   3.126 +\vspace{0.3cm}
   3.127 +
   3.128 + \noindent {\bf Return Type:} 
   3.129 +{\tt 
   3.130 +(event record) Set
   3.131 +}
   3.132 +
   3.133 +
   3.134 +the batch of events
   3.135 +\vspace{0.3cm}
   3.136 +
   3.137 +\noindent{\bf Possible Error Codes:} {\tt SESSION\_NOT\_REGISTERED}
   3.138 +
   3.139 +\vspace{0.6cm}
   3.140 +
   3.141 +\vspace{1cm}
   3.142 +\newpage
   3.143  \section{Class: VM}
   3.144  \subsection{Fields for class: VM}
   3.145  \begin{longtable}{|lllp{0.38\textwidth}|}
   3.146 @@ -6549,6 +6671,7 @@ Quals & Field & Type & Description \\
   3.147  $\mathit{RW}$ &  {\tt name/description} & string & a notes field containg human-readable description \\
   3.148  $\mathit{RO}_\mathit{run}$ &  {\tt VIFs} & (VIF ref) Set & list of connected vifs \\
   3.149  $\mathit{RO}_\mathit{run}$ &  {\tt PIFs} & (PIF ref) Set & list of connected pifs \\
   3.150 +$\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
   3.151  \hline
   3.152  \end{longtable}
   3.153  \subsection{RPCs associated with class: network}
   3.154 @@ -6801,6 +6924,145 @@ value of the field
   3.155  \vspace{0.3cm}
   3.156  \vspace{0.3cm}
   3.157  \vspace{0.3cm}
   3.158 +\subsubsection{RPC name:~get\_other\_config}
   3.159 +
   3.160 +{\bf Overview:} 
   3.161 +Get the other\_config field of the given network.
   3.162 +
   3.163 + \noindent {\bf Signature:} 
   3.164 +\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, network ref self)\end{verbatim}
   3.165 +
   3.166 +
   3.167 +\noindent{\bf Arguments:}
   3.168 +
   3.169 + 
   3.170 +\vspace{0.3cm}
   3.171 +\begin{tabular}{|c|c|p{7cm}|}
   3.172 + \hline
   3.173 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   3.174 +{\tt network ref } & self & reference to the object \\ \hline 
   3.175 +
   3.176 +\end{tabular}
   3.177 +
   3.178 +\vspace{0.3cm}
   3.179 +
   3.180 + \noindent {\bf Return Type:} 
   3.181 +{\tt 
   3.182 +(string $\rightarrow$ string) Map
   3.183 +}
   3.184 +
   3.185 +
   3.186 +value of the field
   3.187 +\vspace{0.3cm}
   3.188 +\vspace{0.3cm}
   3.189 +\vspace{0.3cm}
   3.190 +\subsubsection{RPC name:~set\_other\_config}
   3.191 +
   3.192 +{\bf Overview:} 
   3.193 +Set the other\_config field of the given network.
   3.194 +
   3.195 + \noindent {\bf Signature:} 
   3.196 +\begin{verbatim} void set_other_config (session_id s, network ref self, (string -> string) Map value)\end{verbatim}
   3.197 +
   3.198 +
   3.199 +\noindent{\bf Arguments:}
   3.200 +
   3.201 + 
   3.202 +\vspace{0.3cm}
   3.203 +\begin{tabular}{|c|c|p{7cm}|}
   3.204 + \hline
   3.205 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   3.206 +{\tt network ref } & self & reference to the object \\ \hline 
   3.207 +
   3.208 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
   3.209 +
   3.210 +\end{tabular}
   3.211 +
   3.212 +\vspace{0.3cm}
   3.213 +
   3.214 + \noindent {\bf Return Type:} 
   3.215 +{\tt 
   3.216 +void
   3.217 +}
   3.218 +
   3.219 +
   3.220 +
   3.221 +\vspace{0.3cm}
   3.222 +\vspace{0.3cm}
   3.223 +\vspace{0.3cm}
   3.224 +\subsubsection{RPC name:~add\_to\_other\_config}
   3.225 +
   3.226 +{\bf Overview:} 
   3.227 +Add the given key-value pair to the other\_config field of the given
   3.228 +network.
   3.229 +
   3.230 + \noindent {\bf Signature:} 
   3.231 +\begin{verbatim} void add_to_other_config (session_id s, network ref self, string key, string value)\end{verbatim}
   3.232 +
   3.233 +
   3.234 +\noindent{\bf Arguments:}
   3.235 +
   3.236 + 
   3.237 +\vspace{0.3cm}
   3.238 +\begin{tabular}{|c|c|p{7cm}|}
   3.239 + \hline
   3.240 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   3.241 +{\tt network ref } & self & reference to the object \\ \hline 
   3.242 +
   3.243 +{\tt string } & key & Key to add \\ \hline 
   3.244 +
   3.245 +{\tt string } & value & Value to add \\ \hline 
   3.246 +
   3.247 +\end{tabular}
   3.248 +
   3.249 +\vspace{0.3cm}
   3.250 +
   3.251 + \noindent {\bf Return Type:} 
   3.252 +{\tt 
   3.253 +void
   3.254 +}
   3.255 +
   3.256 +
   3.257 +
   3.258 +\vspace{0.3cm}
   3.259 +\vspace{0.3cm}
   3.260 +\vspace{0.3cm}
   3.261 +\subsubsection{RPC name:~remove\_from\_other\_config}
   3.262 +
   3.263 +{\bf Overview:} 
   3.264 +Remove the given key and its corresponding value from the other\_config
   3.265 +field of the given network.  If the key is not in that Map, then do
   3.266 +nothing.
   3.267 +
   3.268 + \noindent {\bf Signature:} 
   3.269 +\begin{verbatim} void remove_from_other_config (session_id s, network ref self, string key)\end{verbatim}
   3.270 +
   3.271 +
   3.272 +\noindent{\bf Arguments:}
   3.273 +
   3.274 + 
   3.275 +\vspace{0.3cm}
   3.276 +\begin{tabular}{|c|c|p{7cm}|}
   3.277 + \hline
   3.278 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   3.279 +{\tt network ref } & self & reference to the object \\ \hline 
   3.280 +
   3.281 +{\tt string } & key & Key to remove \\ \hline 
   3.282 +
   3.283 +\end{tabular}
   3.284 +
   3.285 +\vspace{0.3cm}
   3.286 +
   3.287 + \noindent {\bf Return Type:} 
   3.288 +{\tt 
   3.289 +void
   3.290 +}
   3.291 +
   3.292 +
   3.293 +
   3.294 +\vspace{0.3cm}
   3.295 +\vspace{0.3cm}
   3.296 +\vspace{0.3cm}
   3.297  \subsubsection{RPC name:~create}
   3.298  
   3.299  {\bf Overview:} 
   3.300 @@ -13576,6 +13838,17 @@ current connection.  The handle paramete
   3.301  \begin{verbatim}SESSION_INVALID(handle)\end{verbatim}
   3.302  \begin{center}\rule{10em}{0.1pt}\end{center}
   3.303  
   3.304 +\subsubsection{SESSION\_NOT\_REGISTERED}
   3.305 +
   3.306 +This session is not registered to receive events.  You must call
   3.307 +event.register before event.next.  The session handle you are using is
   3.308 +echoed.
   3.309 +
   3.310 +\vspace{0.3cm}
   3.311 +{\bf Signature:}
   3.312 +\begin{verbatim}SESSION_NOT_REGISTERED(handle)\end{verbatim}
   3.313 +\begin{center}\rule{10em}{0.1pt}\end{center}
   3.314 +
   3.315  \subsubsection{VALUE\_NOT\_SUPPORTED}
   3.316  
   3.317  You attempted to set a value that is not supported by this implementation. 
     4.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Fri Mar 30 10:27:15 2007 -0600
     4.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Fri Mar 30 17:18:42 2007 -0600
     4.3 @@ -148,11 +148,11 @@ NMI_MASK = 0x80000000
     4.4  	.endm
     4.5  
     4.6          /*
     4.7 -         * Must be consistent with the definition in arch-x86_64.h:    
     4.8 +         * Must be consistent with the definition in arch-x86/xen-x86_64.h:
     4.9           *     struct iret_context {
    4.10           *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
    4.11           *     };
    4.12 -         * #define VGCF_IN_SYSCALL (1<<8) 
    4.13 +         * with rax, r11, and rcx being taken care of in the hypercall stub.
    4.14           */
    4.15  	.macro HYPERVISOR_IRET flag
    4.16  	testb $3,1*8(%rsp)
    4.17 @@ -164,22 +164,16 @@ NMI_MASK = 0x80000000
    4.18  	jnz   1f
    4.19  
    4.20  	/* Direct iret to kernel space. Correct CS and SS. */
    4.21 -	orb   $3,1*8(%rsp)
    4.22 -	orb   $3,4*8(%rsp)
    4.23 +	orl   $3,1*8(%rsp)
    4.24 +	orl   $3,4*8(%rsp)
    4.25  1:	iretq
    4.26  
    4.27  2:	/* Slow iret via hypervisor. */
    4.28 -	andl  $~NMI_MASK, 16(%rsp)
    4.29 +	andl  $~NMI_MASK, 2*8(%rsp)
    4.30  	pushq $\flag
    4.31  	jmp  hypercall_page + (__HYPERVISOR_iret * 32)
    4.32  	.endm
    4.33  
    4.34 -        .macro SWITCH_TO_KERNEL ssoff,adjust=0
    4.35 -	jc  1f
    4.36 -	orb  $1,\ssoff-\adjust+4(%rsp)
    4.37 -1:
    4.38 -        .endm
    4.39 -
    4.40  /*
    4.41   * A newly forked process directly context switches into this.
    4.42   */ 	
     5.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c	Fri Mar 30 10:27:15 2007 -0600
     5.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c	Fri Mar 30 17:18:42 2007 -0600
     5.3 @@ -104,6 +104,8 @@ void __init x86_64_start_kernel(char * r
     5.4  	char *s;
     5.5  	int i;
     5.6  
     5.7 +	setup_xen_features();
     5.8 +
     5.9  	xen_start_info = (struct start_info *)real_mode_data;
    5.10  	if (!xen_feature(XENFEAT_auto_translated_physmap))
    5.11  		phys_to_machine_mapping =
     6.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Fri Mar 30 10:27:15 2007 -0600
     6.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Fri Mar 30 17:18:42 2007 -0600
     6.3 @@ -625,8 +625,6 @@ void __init setup_arch(char **cmdline_p)
     6.4  
     6.5  #endif
     6.6  
     6.7 -	setup_xen_features();
     6.8 -
     6.9  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
    6.10  			     VMASST_TYPE_writable_pagetables);
    6.11  
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Fri Mar 30 10:27:15 2007 -0600
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Fri Mar 30 17:18:42 2007 -0600
     7.3 @@ -43,6 +43,7 @@
     7.4  #include <linux/bootmem.h>
     7.5  #include <linux/highmem.h>
     7.6  #include <linux/vmalloc.h>
     7.7 +#include <linux/mutex.h>
     7.8  #include <xen/xen_proc.h>
     7.9  #include <asm/hypervisor.h>
    7.10  #include <xen/balloon.h>
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Fri Mar 30 10:27:15 2007 -0600
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Fri Mar 30 17:18:42 2007 -0600
     8.3 @@ -123,7 +123,7 @@ static void post_suspend(int suspend_can
     8.4  static int take_machine_down(void *p_fast_suspend)
     8.5  {
     8.6  	int fast_suspend = *(int *)p_fast_suspend;
     8.7 -	int suspend_cancelled, err, cpu;
     8.8 +	int suspend_cancelled, err;
     8.9  	extern void time_resume(void);
    8.10  
    8.11  	if (fast_suspend) {
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Fri Mar 30 10:27:15 2007 -0600
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Fri Mar 30 17:18:42 2007 -0600
     9.3 @@ -33,7 +33,24 @@ static DECLARE_WORK(shutdown_work, __shu
     9.4  #ifdef CONFIG_XEN
     9.5  int __xen_suspend(int fast_suspend);
     9.6  #else
     9.7 -#define __xen_suspend(fast_suspend) 0
     9.8 +extern void xenbus_suspend(void);
     9.9 +extern void xenbus_resume(void);
    9.10 +extern void platform_pci_suspend(void);
    9.11 +extern void platform_pci_resume(void);
    9.12 +int __xen_suspend(int fast_suspend)
    9.13 +{
    9.14 +	xenbus_suspend();
    9.15 +	platform_pci_suspend();
    9.16 +
    9.17 +	/* pvdrv sleep in this hyper-call when save */
    9.18 +	HYPERVISOR_shutdown(SHUTDOWN_suspend);
    9.19 +
    9.20 +	platform_pci_resume();
    9.21 +	xenbus_resume();
    9.22 +	printk("PV stuff on HVM resume successfully!\n");
    9.23 +
    9.24 +	return 0;
    9.25 +}
    9.26  #endif
    9.27  
    9.28  static int shutdown_process(void *__unused)
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Fri Mar 30 10:27:15 2007 -0600
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Fri Mar 30 17:18:42 2007 -0600
    10.3 @@ -47,6 +47,7 @@
    10.4  #include <linux/irq.h>
    10.5  #include <linux/init.h>
    10.6  #include <linux/gfp.h>
    10.7 +#include <linux/mutex.h>
    10.8  #include <xen/evtchn.h>
    10.9  #include <xen/public/evtchn.h>
   10.10  
   10.11 @@ -56,6 +57,7 @@ struct per_user_data {
   10.12  #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
   10.13  	evtchn_port_t *ring;
   10.14  	unsigned int ring_cons, ring_prod, ring_overflow;
   10.15 +	struct mutex ring_cons_mutex; /* protect against concurrent readers */
   10.16  
   10.17  	/* Processes wait on this queue when ring is empty. */
   10.18  	wait_queue_head_t evtchn_wait;
   10.19 @@ -108,12 +110,17 @@ static ssize_t evtchn_read(struct file *
   10.20  		count = PAGE_SIZE;
   10.21  
   10.22  	for (;;) {
   10.23 +		mutex_lock(&u->ring_cons_mutex);
   10.24 +
   10.25 +		rc = -EFBIG;
   10.26  		if (u->ring_overflow)
   10.27 -			return -EFBIG;
   10.28 +			goto unlock_out;
   10.29  
   10.30  		if ((c = u->ring_cons) != (p = u->ring_prod))
   10.31  			break;
   10.32  
   10.33 +		mutex_unlock(&u->ring_cons_mutex);
   10.34 +
   10.35  		if (file->f_flags & O_NONBLOCK)
   10.36  			return -EAGAIN;
   10.37  
   10.38 @@ -141,20 +148,24 @@ static ssize_t evtchn_read(struct file *
   10.39  		bytes2 = count - bytes1;
   10.40  	}
   10.41  
   10.42 +	rc = -EFAULT;
   10.43  	if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
   10.44  	    ((bytes2 != 0) &&
   10.45  	     copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
   10.46 -		return -EFAULT;
   10.47 +		goto unlock_out;
   10.48  
   10.49  	u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
   10.50 +	rc = bytes1 + bytes2;
   10.51  
   10.52 -	return bytes1 + bytes2;
   10.53 + unlock_out:
   10.54 +	mutex_unlock(&u->ring_cons_mutex);
   10.55 +	return rc;
   10.56  }
   10.57  
   10.58  static ssize_t evtchn_write(struct file *file, const char __user *buf,
   10.59  			    size_t count, loff_t *ppos)
   10.60  {
   10.61 -	int  rc, i;
   10.62 +	int rc, i;
   10.63  	evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
   10.64  	struct per_user_data *u = file->private_data;
   10.65  
   10.66 @@ -164,18 +175,16 @@ static ssize_t evtchn_write(struct file 
   10.67  	/* Whole number of ports. */
   10.68  	count &= ~(sizeof(evtchn_port_t)-1);
   10.69  
   10.70 -	if (count == 0) {
   10.71 -		rc = 0;
   10.72 +	rc = 0;
   10.73 +	if (count == 0)
   10.74  		goto out;
   10.75 -	}
   10.76  
   10.77  	if (count > PAGE_SIZE)
   10.78  		count = PAGE_SIZE;
   10.79  
   10.80 -	if (copy_from_user(kbuf, buf, count) != 0) {
   10.81 -		rc = -EFAULT;
   10.82 +	rc = -EFAULT;
   10.83 +	if (copy_from_user(kbuf, buf, count) != 0)
   10.84  		goto out;
   10.85 -	}
   10.86  
   10.87  	spin_lock_irq(&port_user_lock);
   10.88  	for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
   10.89 @@ -321,9 +330,11 @@ static int evtchn_ioctl(struct inode *in
   10.90  
   10.91  	case IOCTL_EVTCHN_RESET: {
   10.92  		/* Initialise the ring to empty. Clear errors. */
   10.93 +		mutex_lock(&u->ring_cons_mutex);
   10.94  		spin_lock_irq(&port_user_lock);
   10.95  		u->ring_cons = u->ring_prod = u->ring_overflow = 0;
   10.96  		spin_unlock_irq(&port_user_lock);
   10.97 +		mutex_unlock(&u->ring_cons_mutex);
   10.98  		rc = 0;
   10.99  		break;
  10.100  	}
  10.101 @@ -371,6 +382,8 @@ static int evtchn_open(struct inode *ino
  10.102  		return -ENOMEM;
  10.103  	}
  10.104  
  10.105 +	mutex_init(&u->ring_cons_mutex);
  10.106 +
  10.107  	filp->private_data = u;
  10.108  
  10.109  	return 0;
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c	Fri Mar 30 10:27:15 2007 -0600
    11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c	Fri Mar 30 17:18:42 2007 -0600
    11.3 @@ -32,19 +32,19 @@ static int pm_ctrl_write(struct pci_dev 
    11.4  			 void *data)
    11.5  {
    11.6  	int err;
    11.7 -	u16 cur_value;
    11.8 -	pci_power_t new_state;
    11.9 +	u16 old_value;
   11.10 +	pci_power_t new_state, old_state;
   11.11  
   11.12 -	/* Handle setting power state separately */
   11.13 -	new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
   11.14 -
   11.15 -	err = pci_read_config_word(dev, offset, &cur_value);
   11.16 +	err = pci_read_config_word(dev, offset, &old_value);
   11.17  	if (err)
   11.18  		goto out;
   11.19  
   11.20 +	old_state = (pci_power_t)(old_value & PCI_PM_CTRL_STATE_MASK);
   11.21 +	new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
   11.22 +
   11.23  	new_value &= PM_OK_BITS;
   11.24 -	if ((cur_value & PM_OK_BITS) != new_value) {
   11.25 -		new_value = (cur_value & ~PM_OK_BITS) | new_value;
   11.26 +	if ((old_value & PM_OK_BITS) != new_value) {
   11.27 +		new_value = (old_value & ~PM_OK_BITS) | new_value;
   11.28  		err = pci_write_config_word(dev, offset, new_value);
   11.29  		if (err)
   11.30  			goto out;
   11.31 @@ -53,10 +53,25 @@ static int pm_ctrl_write(struct pci_dev 
   11.32  	/* Let pci core handle the power management change */
   11.33  	dev_dbg(&dev->dev, "set power state to %x\n", new_state);
   11.34  	err = pci_set_power_state(dev, new_state);
   11.35 -	if (err)
   11.36 +	if (err) {
   11.37  		err = PCIBIOS_SET_FAILED;
   11.38 +		goto out;
   11.39 +	}
   11.40  
   11.41 -      out:
   11.42 +	/*
   11.43 +	 * Device may lose PCI config info on D3->D0 transition. This
   11.44 +	 * is a problem for some guests which will not reset BARs. Even
   11.45 +	 * those that have a go will be foiled by our BAR-write handler
   11.46 +	 * which will discard the write! Since Linux won't re-init
   11.47 +	 * the config space automatically in all cases, we do it here.
   11.48 +	 * Future: Should we re-initialise all first 64 bytes of config space?
   11.49 +	 */
   11.50 +	if (new_state == PCI_D0 &&
   11.51 +	    (old_state == PCI_D3hot || old_state == PCI_D3cold) &&
   11.52 +	    !(old_value & PCI_PM_CTRL_NO_SOFT_RESET))
   11.53 +		pci_restore_bars(dev);
   11.54 +
   11.55 + out:
   11.56  	return err;
   11.57  }
   11.58  
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c	Fri Mar 30 10:27:15 2007 -0600
    12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c	Fri Mar 30 17:18:42 2007 -0600
    12.3 @@ -20,11 +20,15 @@ struct pci_bar_info {
    12.4  
    12.5  static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
    12.6  {
    12.7 +	int err;
    12.8 +
    12.9  	if (!dev->is_enabled && is_enable_cmd(value)) {
   12.10  		if (unlikely(verbose_request))
   12.11  			printk(KERN_DEBUG "pciback: %s: enable\n",
   12.12  			       pci_name(dev));
   12.13 -		pci_enable_device(dev);
   12.14 +		err = pci_enable_device(dev);
   12.15 +		if (err)
   12.16 +			return err;
   12.17  	} else if (dev->is_enabled && !is_enable_cmd(value)) {
   12.18  		if (unlikely(verbose_request))
   12.19  			printk(KERN_DEBUG "pciback: %s: disable\n",
   12.20 @@ -44,7 +48,13 @@ static int command_write(struct pci_dev 
   12.21  			printk(KERN_DEBUG
   12.22  			       "pciback: %s: enable memory-write-invalidate\n",
   12.23  			       pci_name(dev));
   12.24 -		pci_set_mwi(dev);
   12.25 +		err = pci_set_mwi(dev);
   12.26 +		if (err) {
   12.27 +			printk(KERN_WARNING
   12.28 +			       "pciback: %s: cannot enable memory-write-invalidate (%d)\n",
   12.29 +			       pci_name(dev), err);
   12.30 +			value &= ~PCI_COMMAND_INVALIDATE;
   12.31 +		}
   12.32  	}
   12.33  
   12.34  	return pci_write_config_word(dev, offset, value);
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c	Fri Mar 30 10:27:15 2007 -0600
    13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c	Fri Mar 30 17:18:42 2007 -0600
    13.3 @@ -805,6 +805,18 @@ static ssize_t permissive_show(struct de
    13.4  
    13.5  DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
    13.6  
    13.7 +static void pcistub_exit(void)
    13.8 +{
    13.9 +	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
   13.10 +	driver_remove_file(&pciback_pci_driver.driver,
   13.11 +			   &driver_attr_remove_slot);
   13.12 +	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
   13.13 +	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
   13.14 +	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
   13.15 +
   13.16 +	pci_unregister_driver(&pciback_pci_driver);
   13.17 +}
   13.18 +
   13.19  static int __init pcistub_init(void)
   13.20  {
   13.21  	int pos = 0;
   13.22 @@ -845,12 +857,23 @@ static int __init pcistub_init(void)
   13.23  	if (err < 0)
   13.24  		goto out;
   13.25  
   13.26 -	driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
   13.27 -	driver_create_file(&pciback_pci_driver.driver,
   13.28 -			   &driver_attr_remove_slot);
   13.29 -	driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
   13.30 -	driver_create_file(&pciback_pci_driver.driver, &driver_attr_quirks);
   13.31 -	driver_create_file(&pciback_pci_driver.driver, &driver_attr_permissive);
   13.32 +	err = driver_create_file(&pciback_pci_driver.driver,
   13.33 +				 &driver_attr_new_slot);
   13.34 +	if (!err)
   13.35 +		err = driver_create_file(&pciback_pci_driver.driver,
   13.36 +					 &driver_attr_remove_slot);
   13.37 +	if (!err)
   13.38 +		err = driver_create_file(&pciback_pci_driver.driver,
   13.39 +					 &driver_attr_slots);
   13.40 +	if (!err)
   13.41 +		err = driver_create_file(&pciback_pci_driver.driver,
   13.42 +					 &driver_attr_quirks);
   13.43 +	if (!err)
   13.44 +		err = driver_create_file(&pciback_pci_driver.driver,
   13.45 +					 &driver_attr_permissive);
   13.46 +
   13.47 +	if (err)
   13.48 +		pcistub_exit();
   13.49  
   13.50        out:
   13.51  	return err;
   13.52 @@ -887,23 +910,17 @@ static int __init pciback_init(void)
   13.53  #endif
   13.54  
   13.55  	pcistub_init_devices_late();
   13.56 -	pciback_xenbus_register();
   13.57 +	err = pciback_xenbus_register();
   13.58 +	if (err)
   13.59 +		pcistub_exit();
   13.60  
   13.61 -	return 0;
   13.62 +	return err;
   13.63  }
   13.64  
   13.65  static void __exit pciback_cleanup(void)
   13.66  {
   13.67  	pciback_xenbus_unregister();
   13.68 -
   13.69 -	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
   13.70 -	driver_remove_file(&pciback_pci_driver.driver,
   13.71 -			   &driver_attr_remove_slot);
   13.72 -	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
   13.73 -	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
   13.74 -	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
   13.75 -
   13.76 -	pci_unregister_driver(&pciback_pci_driver);
   13.77 +	pcistub_exit();
   13.78  }
   13.79  
   13.80  module_init(pciback_init);
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Fri Mar 30 10:27:15 2007 -0600
    14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Fri Mar 30 17:18:42 2007 -0600
    14.3 @@ -58,6 +58,13 @@ struct xenbus_dev_transaction {
    14.4  	struct xenbus_transaction handle;
    14.5  };
    14.6  
    14.7 +struct read_buffer {
    14.8 +	struct list_head list;
    14.9 +	unsigned int cons;
   14.10 +	unsigned int len;
   14.11 +	char msg[];
   14.12 +};
   14.13 +
   14.14  struct xenbus_dev_data {
   14.15  	/* In-progress transaction. */
   14.16  	struct list_head transactions;
   14.17 @@ -73,9 +80,7 @@ struct xenbus_dev_data {
   14.18  	} u;
   14.19  
   14.20  	/* Response queue. */
   14.21 -#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1))
   14.22 -	char read_buffer[PAGE_SIZE];
   14.23 -	unsigned int read_cons, read_prod;
   14.24 +	struct list_head read_buffers;
   14.25  	wait_queue_head_t read_waitq;
   14.26  
   14.27  	struct mutex reply_mutex;
   14.28 @@ -88,18 +93,34 @@ static ssize_t xenbus_dev_read(struct fi
   14.29  			       size_t len, loff_t *ppos)
   14.30  {
   14.31  	struct xenbus_dev_data *u = filp->private_data;
   14.32 -	int i;
   14.33 +	struct read_buffer *rb;
   14.34 +	int i, ret;
   14.35  
   14.36 -	if (wait_event_interruptible(u->read_waitq,
   14.37 -				     u->read_prod != u->read_cons))
   14.38 -		return -EINTR;
   14.39 +	mutex_lock(&u->reply_mutex);
   14.40 +	while (list_empty(&u->read_buffers)) {
   14.41 +		mutex_unlock(&u->reply_mutex);
   14.42 +		ret = wait_event_interruptible(u->read_waitq,
   14.43 +					       !list_empty(&u->read_buffers));
   14.44 +		if (ret)
   14.45 +			return ret;
   14.46 +		mutex_lock(&u->reply_mutex);
   14.47 +	}
   14.48  
   14.49 -	for (i = 0; i < len; i++) {
   14.50 -		if (u->read_cons == u->read_prod)
   14.51 -			break;
   14.52 -		put_user(u->read_buffer[MASK_READ_IDX(u->read_cons)], ubuf+i);
   14.53 -		u->read_cons++;
   14.54 +	rb = list_entry(u->read_buffers.next, struct read_buffer, list);
   14.55 +	for (i = 0; i < len;) {
   14.56 +		put_user(rb->msg[rb->cons], ubuf + i);
   14.57 +		i++;
   14.58 +		rb->cons++;
   14.59 +		if (rb->cons == rb->len) {
   14.60 +			list_del(&rb->list);
   14.61 +			kfree(rb);
   14.62 +			if (list_empty(&u->read_buffers))
   14.63 +				break;
   14.64 +			rb = list_entry(u->read_buffers.next,
   14.65 +					struct read_buffer, list);
   14.66 +		}
   14.67  	}
   14.68 +	mutex_unlock(&u->reply_mutex);
   14.69  
   14.70  	return i;
   14.71  }
   14.72 @@ -107,16 +128,20 @@ static ssize_t xenbus_dev_read(struct fi
   14.73  static void queue_reply(struct xenbus_dev_data *u,
   14.74  			char *data, unsigned int len)
   14.75  {
   14.76 -	int i;
   14.77 +	struct read_buffer *rb;
   14.78  
   14.79 -	mutex_lock(&u->reply_mutex);
   14.80 +	if (len == 0)
   14.81 +		return;
   14.82  
   14.83 -	for (i = 0; i < len; i++, u->read_prod++)
   14.84 -		u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
   14.85 +	rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL);
   14.86 +	BUG_ON(rb == NULL);
   14.87  
   14.88 -	BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
   14.89 +	rb->cons = 0;
   14.90 +	rb->len = len;
   14.91  
   14.92 -	mutex_unlock(&u->reply_mutex);
   14.93 +	memcpy(rb->msg, data, len);
   14.94 +
   14.95 +	list_add_tail(&rb->list, &u->read_buffers);
   14.96  
   14.97  	wake_up(&u->read_waitq);
   14.98  }
   14.99 @@ -155,10 +180,12 @@ static void watch_fired(struct xenbus_wa
  14.100  
  14.101  	hdr.type = XS_WATCH_EVENT;
  14.102  	hdr.len = body_len;
  14.103 -	
  14.104 +
  14.105 +	mutex_lock(&adap->dev_data->reply_mutex);
  14.106  	queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr));
  14.107  	queue_reply(adap->dev_data, (char *)path, path_len);
  14.108  	queue_reply(adap->dev_data, (char *)token, tok_len);
  14.109 +	mutex_unlock(&adap->dev_data->reply_mutex);
  14.110  }
  14.111  
  14.112  static LIST_HEAD(watch_list);
  14.113 @@ -230,13 +257,18 @@ static ssize_t xenbus_dev_write(struct f
  14.114  			list_del(&trans->list);
  14.115  			kfree(trans);
  14.116  		}
  14.117 +		mutex_lock(&u->reply_mutex);
  14.118  		queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
  14.119  		queue_reply(u, (char *)reply, u->u.msg.len);
  14.120 +		mutex_unlock(&u->reply_mutex);
  14.121  		kfree(reply);
  14.122  		break;
  14.123  
  14.124  	case XS_WATCH:
  14.125 -	case XS_UNWATCH:
  14.126 +	case XS_UNWATCH: {
  14.127 +		static const char *XS_RESP = "OK";
  14.128 +		struct xsd_sockmsg hdr;
  14.129 +
  14.130  		path = u->u.buffer + sizeof(u->u.msg);
  14.131  		token = memchr(path, 0, u->u.msg.len);
  14.132  		if (token == NULL) {
  14.133 @@ -246,9 +278,6 @@ static ssize_t xenbus_dev_write(struct f
  14.134  		token++;
  14.135  
  14.136  		if (msg_type == XS_WATCH) {
  14.137 -			static const char * XS_WATCH_RESP = "OK";
  14.138 -			struct xsd_sockmsg hdr;
  14.139 -
  14.140  			watch = kmalloc(sizeof(*watch), GFP_KERNEL);
  14.141  			watch->watch.node = kmalloc(strlen(path)+1,
  14.142                                                      GFP_KERNEL);
  14.143 @@ -266,11 +295,6 @@ static ssize_t xenbus_dev_write(struct f
  14.144  			}
  14.145  			
  14.146  			list_add(&watch->list, &u->watches);
  14.147 -
  14.148 -			hdr.type = XS_WATCH;
  14.149 -			hdr.len = strlen(XS_WATCH_RESP) + 1;
  14.150 -			queue_reply(u, (char *)&hdr, sizeof(hdr));
  14.151 -			queue_reply(u, (char *)XS_WATCH_RESP, hdr.len);
  14.152  		} else {
  14.153  			list_for_each_entry_safe(watch, tmp_watch,
  14.154                                                   &u->watches, list) {
  14.155 @@ -285,7 +309,14 @@ static ssize_t xenbus_dev_write(struct f
  14.156  			}
  14.157  		}
  14.158  
  14.159 +		hdr.type = msg_type;
  14.160 +		hdr.len = strlen(XS_RESP) + 1;
  14.161 +		mutex_lock(&u->reply_mutex);
  14.162 +		queue_reply(u, (char *)&hdr, sizeof(hdr));
  14.163 +		queue_reply(u, (char *)XS_RESP, hdr.len);
  14.164 +		mutex_unlock(&u->reply_mutex);
  14.165  		break;
  14.166 +	}
  14.167  
  14.168  	default:
  14.169  		rc = -EINVAL;
  14.170 @@ -312,6 +343,7 @@ static int xenbus_dev_open(struct inode 
  14.171  
  14.172  	INIT_LIST_HEAD(&u->transactions);
  14.173  	INIT_LIST_HEAD(&u->watches);
  14.174 +	INIT_LIST_HEAD(&u->read_buffers);
  14.175  	init_waitqueue_head(&u->read_waitq);
  14.176  
  14.177  	mutex_init(&u->reply_mutex);
  14.178 @@ -349,7 +381,7 @@ static unsigned int xenbus_dev_poll(stru
  14.179  	struct xenbus_dev_data *u = file->private_data;
  14.180  
  14.181  	poll_wait(file, &u->read_waitq, wait);
  14.182 -	if (u->read_cons != u->read_prod)
  14.183 +	if (!list_empty(&u->read_buffers))
  14.184  		return POLLIN | POLLRDNORM;
  14.185  	return 0;
  14.186  }
    15.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Mar 30 10:27:15 2007 -0600
    15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Mar 30 17:18:42 2007 -0600
    15.3 @@ -335,6 +335,9 @@ int xenbus_register_driver_common(struct
    15.4  {
    15.5  	int ret;
    15.6  
    15.7 +	if (bus->error)
    15.8 +		return bus->error;
    15.9 +
   15.10  	drv->driver.name = drv->name;
   15.11  	drv->driver.bus = &bus->bus;
   15.12  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
   15.13 @@ -476,6 +479,9 @@ int xenbus_probe_node(struct xen_bus_typ
   15.14  
   15.15  	enum xenbus_state state = xenbus_read_driver_state(nodename);
   15.16  
   15.17 +	if (bus->error)
   15.18 +		return bus->error;
   15.19 +
   15.20  	if (state != XenbusStateInitialising) {
   15.21  		/* Device is not new, so ignore it.  This can happen if a
   15.22  		   device is going away after switching to Closed.  */
   15.23 @@ -513,10 +519,18 @@ int xenbus_probe_node(struct xen_bus_typ
   15.24  	if (err)
   15.25  		goto fail;
   15.26  
   15.27 -	device_create_file(&xendev->dev, &dev_attr_nodename);
   15.28 -	device_create_file(&xendev->dev, &dev_attr_devtype);
   15.29 +	err = device_create_file(&xendev->dev, &dev_attr_nodename);
   15.30 +	if (err)
   15.31 +		goto unregister;
   15.32 +	err = device_create_file(&xendev->dev, &dev_attr_devtype);
   15.33 +	if (err)
   15.34 +		goto unregister;
   15.35  
   15.36  	return 0;
   15.37 +unregister:
   15.38 +	device_remove_file(&xendev->dev, &dev_attr_nodename);
   15.39 +	device_remove_file(&xendev->dev, &dev_attr_devtype);
   15.40 +	device_unregister(&xendev->dev);
   15.41  fail:
   15.42  	kfree(xendev);
   15.43  	return err;
   15.44 @@ -565,6 +579,9 @@ int xenbus_probe_devices(struct xen_bus_
   15.45  	char **dir;
   15.46  	unsigned int i, dir_n;
   15.47  
   15.48 +	if (bus->error)
   15.49 +		return bus->error;
   15.50 +
   15.51  	dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
   15.52  	if (IS_ERR(dir))
   15.53  		return PTR_ERR(dir);
   15.54 @@ -608,7 +625,7 @@ void dev_changed(const char *node, struc
   15.55  	char type[BUS_ID_SIZE];
   15.56  	const char *p, *root;
   15.57  
   15.58 -	if (char_count(node, '/') < 2)
   15.59 +	if (bus->error || char_count(node, '/') < 2)
   15.60   		return;
   15.61  
   15.62  	exists = xenbus_exists(XBT_NIL, node, "");
   15.63 @@ -742,7 +759,8 @@ void xenbus_suspend(void)
   15.64  {
   15.65  	DPRINTK("");
   15.66  
   15.67 -	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
   15.68 +	if (!xenbus_frontend.error)
   15.69 +		bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
   15.70  	xenbus_backend_suspend(suspend_dev);
   15.71  	xs_suspend();
   15.72  }
   15.73 @@ -752,7 +770,8 @@ void xenbus_resume(void)
   15.74  {
   15.75  	xb_init_comms();
   15.76  	xs_resume();
   15.77 -	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
   15.78 +	if (!xenbus_frontend.error)
   15.79 +		bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
   15.80  	xenbus_backend_resume(resume_dev);
   15.81  }
   15.82  EXPORT_SYMBOL_GPL(xenbus_resume);
   15.83 @@ -760,7 +779,8 @@ EXPORT_SYMBOL_GPL(xenbus_resume);
   15.84  void xenbus_suspend_cancel(void)
   15.85  {
   15.86  	xs_suspend_cancel();
   15.87 -	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
   15.88 +	if (!xenbus_frontend.error)
   15.89 +		bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
   15.90  	xenbus_backend_resume(suspend_cancel_dev);
   15.91  }
   15.92  EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
   15.93 @@ -854,7 +874,11 @@ static int __init xenbus_probe_init(void
   15.94  		return -ENODEV;
   15.95  
   15.96  	/* Register ourselves with the kernel bus subsystem */
   15.97 -	bus_register(&xenbus_frontend.bus);
   15.98 +	xenbus_frontend.error = bus_register(&xenbus_frontend.bus);
   15.99 +	if (xenbus_frontend.error)
  15.100 +		printk(KERN_WARNING
  15.101 +		       "XENBUS: Error registering frontend bus: %i\n",
  15.102 +		       xenbus_frontend.error);
  15.103  	xenbus_backend_bus_register();
  15.104  
  15.105  	/*
  15.106 @@ -925,7 +949,15 @@ static int __init xenbus_probe_init(void
  15.107  	}
  15.108  
  15.109  	/* Register ourselves with the kernel device subsystem */
  15.110 -	device_register(&xenbus_frontend.dev);
  15.111 +	if (!xenbus_frontend.error) {
  15.112 +		xenbus_frontend.error = device_register(&xenbus_frontend.dev);
  15.113 +		if (xenbus_frontend.error) {
  15.114 +			bus_unregister(&xenbus_frontend.bus);
  15.115 +			printk(KERN_WARNING
  15.116 +			       "XENBUS: Error registering frontend device: %i\n",
  15.117 +			       xenbus_frontend.error);
  15.118 +		}
  15.119 +	}
  15.120  	xenbus_backend_device_register();
  15.121  
  15.122  	if (!is_initial_xendomain())
  15.123 @@ -972,6 +1004,8 @@ static int is_disconnected_device(struct
  15.124  
  15.125  static int exists_disconnected_device(struct device_driver *drv)
  15.126  {
  15.127 +	if (xenbus_frontend.error)
  15.128 +		return xenbus_frontend.error;
  15.129  	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
  15.130  				is_disconnected_device);
  15.131  }
  15.132 @@ -1036,8 +1070,10 @@ static void wait_for_devices(struct xenb
  15.133  #ifndef MODULE
  15.134  static int __init boot_wait_for_devices(void)
  15.135  {
  15.136 -	ready_to_wait_for_devices = 1;
  15.137 -	wait_for_devices(NULL);
  15.138 +	if (!xenbus_frontend.error) {
  15.139 +		ready_to_wait_for_devices = 1;
  15.140 +		wait_for_devices(NULL);
  15.141 +	}
  15.142  	return 0;
  15.143  }
  15.144  
    16.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h	Fri Mar 30 10:27:15 2007 -0600
    16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h	Fri Mar 30 17:18:42 2007 -0600
    16.3 @@ -51,6 +51,7 @@ static inline void xenbus_backend_device
    16.4  struct xen_bus_type
    16.5  {
    16.6  	char *root;
    16.7 +	int error;
    16.8  	unsigned int levels;
    16.9  	int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
   16.10  	int (*probe)(const char *type, const char *dir);
    17.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c	Fri Mar 30 10:27:15 2007 -0600
    17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c	Fri Mar 30 17:18:42 2007 -0600
    17.3 @@ -245,13 +245,15 @@ static struct xenbus_watch be_watch = {
    17.4  void xenbus_backend_suspend(int (*fn)(struct device *, void *))
    17.5  {
    17.6  	DPRINTK("");
    17.7 -	bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
    17.8 +	if (!xenbus_backend.error)
    17.9 +		bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
   17.10  }
   17.11  
   17.12  void xenbus_backend_resume(int (*fn)(struct device *, void *))
   17.13  {
   17.14  	DPRINTK("");
   17.15 -	bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
   17.16 +	if (!xenbus_backend.error)
   17.17 +		bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
   17.18  }
   17.19  
   17.20  void xenbus_backend_probe_and_watch(void)
   17.21 @@ -262,10 +264,23 @@ void xenbus_backend_probe_and_watch(void
   17.22  
   17.23  void xenbus_backend_bus_register(void)
   17.24  {
   17.25 -	bus_register(&xenbus_backend.bus);
   17.26 +	xenbus_backend.error = bus_register(&xenbus_backend.bus);
   17.27 +	if (xenbus_backend.error)
   17.28 +		printk(KERN_WARNING
   17.29 +		       "XENBUS: Error registering backend bus: %i\n",
   17.30 +		       xenbus_backend.error);
   17.31  }
   17.32  
   17.33  void xenbus_backend_device_register(void)
   17.34  {
   17.35 -	device_register(&xenbus_backend.dev);
   17.36 +	if (xenbus_backend.error)
   17.37 +		return;
   17.38 +
   17.39 +	xenbus_backend.error = device_register(&xenbus_backend.dev);
   17.40 +	if (xenbus_backend.error) {
   17.41 +		bus_unregister(&xenbus_backend.bus);
   17.42 +		printk(KERN_WARNING
   17.43 +		       "XENBUS: Error registering backend device: %i\n",
   17.44 +		       xenbus_backend.error);
   17.45 +	}
   17.46  }
    18.1 --- a/tools/Rules.mk	Fri Mar 30 10:27:15 2007 -0600
    18.2 +++ b/tools/Rules.mk	Fri Mar 30 17:18:42 2007 -0600
    18.3 @@ -24,9 +24,9 @@ CFLAGS-$(CONFIG_X86_32) += $(call cc-opt
    18.4  CFLAGS += $(CFLAGS-y)
    18.5  
    18.6  # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
    18.7 -ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn)
    18.8 -$(error Xen tools require at least gcc-3.4)
    18.9 -endif
   18.10 +check-$(CONFIG_X86) = $(call cc-ver-check,CC,0x030400,\
   18.11 +                        "Xen requires at least gcc-3.4")
   18.12 +$(eval $(check-y))
   18.13  
   18.14  %.opic: %.c
   18.15  	$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
    19.1 --- a/tools/examples/Makefile	Fri Mar 30 10:27:15 2007 -0600
    19.2 +++ b/tools/examples/Makefile	Fri Mar 30 17:18:42 2007 -0600
    19.3 @@ -9,7 +9,9 @@ XENDOMAINS_SYSCONFIG = init.d/sysconfig.
    19.4  # Xen configuration dir and configs to go there.
    19.5  XEN_CONFIG_DIR = /etc/xen
    19.6  XEN_CONFIGS = xend-config.sxp
    19.7 +XEN_CONFIGS += xend-config-xenapi.sxp
    19.8  XEN_CONFIGS += xm-config.xml
    19.9 +XEN_CONFIGS += xm-config-xenapi.xml
   19.10  XEN_CONFIGS += xmexample1 
   19.11  XEN_CONFIGS += xmexample2
   19.12  XEN_CONFIGS += xmexample.hvm
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/examples/xend-config-xenapi.sxp	Fri Mar 30 17:18:42 2007 -0600
    20.3 @@ -0,0 +1,195 @@
    20.4 +# -*- sh -*-
    20.5 +
    20.6 +#
    20.7 +# Xend configuration file.
    20.8 +#
    20.9 +
   20.10 +# This example configuration is appropriate for an installation that 
   20.11 +# utilizes a bridged network configuration. Access to xend via http
   20.12 +# is disabled.  
   20.13 +
   20.14 +# Commented out entries show the default for that entry, unless otherwise
   20.15 +# specified.
   20.16 +
   20.17 +#(logfile /var/log/xen/xend.log)
   20.18 +#(loglevel DEBUG)
   20.19 +
   20.20 +
   20.21 +# The Xen-API server configuration.  (Please note that this server is
   20.22 +# available as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied
   20.23 +# upon).
   20.24 +#
   20.25 +# This value configures the ports, interfaces, and access controls for the
   20.26 +# Xen-API server.  Each entry in the list starts with either unix, a port
   20.27 +# number, or an address:port pair.  If this is "unix", then a UDP socket is
   20.28 +# opened, and this entry applies to that.  If it is a port, then Xend will
   20.29 +# listen on all interfaces on that TCP port, and if it is an address:port
   20.30 +# pair, then Xend will listen on the specified port, using the interface with
   20.31 +# the specified address.
   20.32 +#
   20.33 +# The subsequent string configures the user-based access control for the
   20.34 +# listener in question.  This can be one of "none" or "pam", indicating either
   20.35 +# that users should be allowed access unconditionally, or that the local
   20.36 +# Pluggable Authentication Modules configuration should be used.  If this
   20.37 +# string is missing or empty, then "pam" is used.
   20.38 +#
   20.39 +# The final string gives the host-based access control for that listener. If
   20.40 +# this is missing or empty, then all connections are accepted.  Otherwise,
   20.41 +# this should be a space-separated sequence of regular expressions; any host
   20.42 +# with a fully-qualified domain name or an IP address that matches one of
   20.43 +# these regular expressions will be accepted.
   20.44 +#
   20.45 +# Example: listen on TCP port 9363 on all interfaces, accepting connections
   20.46 +# only from machines in example.com or localhost, and allow access through
   20.47 +# the unix domain socket unconditionally:
   20.48 +#
   20.49 +   (xen-api-server ((9363 none)))
   20.50 +#                    (unix none)))
   20.51 +#
   20.52 +# Optionally, the TCP Xen-API server can use SSL by specifying the private
   20.53 +# key and certificate location:
   20.54 +#
   20.55 +#                    (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
   20.56 +#
   20.57 +# Default:
   20.58 +#   (xen-api-server ((unix)))
   20.59 +
   20.60 +
   20.61 +#(xend-http-server no)
   20.62 +#(xend-unix-server no)
   20.63 +#(xend-tcp-xmlrpc-server no)
   20.64 +#(xend-unix-xmlrpc-server yes)
   20.65 +#(xend-relocation-server no)
   20.66 +(xend-relocation-server yes)
   20.67 +
   20.68 +#(xend-unix-path /var/lib/xend/xend-socket)
   20.69 +
   20.70 +
   20.71 +# Address and port xend should use for the legacy TCP XMLRPC interface, 
   20.72 +# if xen-tcp-xmlrpc-server is set.
   20.73 +#(xen-tcp-xmlrpc-server-address 'localhost')
   20.74 +#(xen-tcp-xmlrpc-server-port 8006)
   20.75 +
   20.76 +# SSL key and certificate to use for the legacy TCP XMLRPC interface.
   20.77 +# Setting these will mean that this port serves only SSL connections as
   20.78 +# opposed to plaintext ones.
   20.79 +#(xend-tcp-xmlrpc-server-ssl-key-file  /etc/xen/xmlrpc.key)
   20.80 +#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
   20.81 +
   20.82 +
   20.83 +# Port xend should use for the HTTP interface, if xend-http-server is set.
   20.84 +#(xend-port            8000)
   20.85 +
   20.86 +# Port xend should use for the relocation interface, if xend-relocation-server
   20.87 +# is set.
   20.88 +#(xend-relocation-port 8002)
   20.89 +
   20.90 +# Address xend should listen on for HTTP connections, if xend-http-server is
   20.91 +# set.
   20.92 +# Specifying 'localhost' prevents remote connections.
   20.93 +# Specifying the empty string '' (the default) allows all connections.
   20.94 +#(xend-address '')
   20.95 +#(xend-address localhost)
   20.96 +
   20.97 +# Address xend should listen on for relocation-socket connections, if
   20.98 +# xend-relocation-server is set.
   20.99 +# Meaning and default as for xend-address above.
  20.100 +#(xend-relocation-address '')
  20.101 +
  20.102 +# The hosts allowed to talk to the relocation port.  If this is empty (the
  20.103 +# default), then all connections are allowed (assuming that the connection
  20.104 +# arrives on a port and interface on which we are listening; see
  20.105 +# xend-relocation-port and xend-relocation-address above).  Otherwise, this
  20.106 +# should be a space-separated sequence of regular expressions.  Any host with
  20.107 +# a fully-qualified domain name or an IP address that matches one of these
  20.108 +# regular expressions will be accepted.
  20.109 +#
  20.110 +# For example:
  20.111 +#  (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$')
  20.112 +#
  20.113 +#(xend-relocation-hosts-allow '')
  20.114 +(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
  20.115 +
  20.116 +# The limit (in kilobytes) on the size of the console buffer
  20.117 +#(console-limit 1024)
  20.118 +
  20.119 +##
  20.120 +# To bridge network traffic, like this:
  20.121 +#
  20.122 +# dom0: fake eth0 -> vif0.0 -+
  20.123 +#                            |
  20.124 +#                          bridge -> real eth0 -> the network
  20.125 +#                            |
  20.126 +# domU: fake eth0 -> vifN.0 -+
  20.127 +#
  20.128 +# use
  20.129 +#
  20.130 +# (network-script network-bridge)
  20.131 +#
  20.132 +# Your default ethernet device is used as the outgoing interface, by default. 
  20.133 +# To use a different one (e.g. eth1) use
  20.134 +#
  20.135 +# (network-script 'network-bridge netdev=eth1')
  20.136 +#
  20.137 +# The bridge is named xenbr0, by default.  To rename the bridge, use
  20.138 +#
  20.139 +# (network-script 'network-bridge bridge=<name>')
  20.140 +#
  20.141 +# It is possible to use the network-bridge script in more complicated
  20.142 +# scenarios, such as having two outgoing interfaces, with two bridges, and
  20.143 +# two fake interfaces per guest domain.  To do things like this, write
  20.144 +# yourself a wrapper script, and call network-bridge from it, as appropriate.
  20.145 +#
  20.146 +(network-script network-bridge)
  20.147 +
  20.148 +# The script used to control virtual interfaces.  This can be overridden on a
  20.149 +# per-vif basis when creating a domain or a configuring a new vif.  The
  20.150 +# vif-bridge script is designed for use with the network-bridge script, or
  20.151 +# similar configurations.
  20.152 +#
  20.153 +# If you have overridden the bridge name using
  20.154 +# (network-script 'network-bridge bridge=<name>') then you may wish to do the
  20.155 +# same here.  The bridge name can also be set when creating a domain or
  20.156 +# configuring a new vif, but a value specified here would act as a default.
  20.157 +#
  20.158 +# If you are using only one bridge, the vif-bridge script will discover that,
  20.159 +# so there is no need to specify it explicitly.
  20.160 +#
  20.161 +(vif-script vif-bridge)
  20.162 +
  20.163 +
  20.164 +## Use the following if network traffic is routed, as an alternative to the
  20.165 +# settings for bridged networking given above.
  20.166 +#(network-script network-route)
  20.167 +#(vif-script     vif-route)
  20.168 +
  20.169 +
  20.170 +## Use the following if network traffic is routed with NAT, as an alternative
  20.171 +# to the settings for bridged networking given above.
  20.172 +#(network-script network-nat)
  20.173 +#(vif-script     vif-nat)
  20.174 +
  20.175 +
  20.176 +# Dom0 will balloon out when needed to free memory for domU.
  20.177 +# dom0-min-mem is the lowest memory level (in MB) dom0 will get down to.
  20.178 +# If dom0-min-mem=0, dom0 will never balloon out.
  20.179 +(dom0-min-mem 196)
  20.180 +
  20.181 +# In SMP system, dom0 will use dom0-cpus # of CPUS
  20.182 +# If dom0-cpus = 0, dom0 will take all cpus available
  20.183 +(dom0-cpus 0)
  20.184 +
  20.185 +# Whether to enable core-dumps when domains crash.
  20.186 +#(enable-dump no)
  20.187 +
  20.188 +# The tool used for initiating virtual TPM migration
  20.189 +#(external-migration-tool '')
  20.190 +
  20.191 +# The interface for VNC servers to listen on. Defaults
  20.192 +# to 127.0.0.1  To restore old 'listen everywhere' behaviour
  20.193 +# set this to 0.0.0.0
  20.194 +#(vnc-listen '127.0.0.1')
  20.195 +
  20.196 +# The default password for VNC console on HVM domain.
  20.197 +# Empty string is no authentication.
  20.198 +(vncpasswd '')
    21.1 --- a/tools/examples/xend-config.sxp	Fri Mar 30 10:27:15 2007 -0600
    21.2 +++ b/tools/examples/xend-config.sxp	Fri Mar 30 17:18:42 2007 -0600
    21.3 @@ -46,6 +46,11 @@
    21.4  #   (xen-api-server ((9363 pam '^localhost$ example\\.com$')
    21.5  #                    (unix none)))
    21.6  #
    21.7 +# Optionally, the TCP Xen-API server can use SSL by specifying the private
    21.8 +# key and certificate location:
    21.9 +#
   21.10 +#                    (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
   21.11 +#
   21.12  # Default:
   21.13  #   (xen-api-server ((unix)))
   21.14  
   21.15 @@ -59,11 +64,18 @@
   21.16  
   21.17  #(xend-unix-path /var/lib/xend/xend-socket)
   21.18  
   21.19 -# Address and port xend should use for the TCP XMLRPC interface, 
   21.20 +
   21.21 +# Address and port xend should use for the legacy TCP XMLRPC interface, 
   21.22  # if xen-tcp-xmlrpc-server is set.
   21.23  #(xen-tcp-xmlrpc-server-address 'localhost')
   21.24  #(xen-tcp-xmlrpc-server-port 8006)
   21.25  
   21.26 +# SSL key and certificate to use for the legacy TCP XMLRPC interface.
   21.27 +# Setting these will mean that this port serves only SSL connections as
   21.28 +# opposed to plaintext ones.
   21.29 +#(xend-tcp-xmlrpc-server-ssl-key-file  /etc/xen/xmlrpc.key)
   21.30 +#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
   21.31 +
   21.32  
   21.33  # Port xend should use for the HTTP interface, if xend-http-server is set.
   21.34  #(xend-port            8000)
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/examples/xm-config-xenapi.xml	Fri Mar 30 17:18:42 2007 -0600
    22.3 @@ -0,0 +1,43 @@
    22.4 +<!--
    22.5 +
    22.6 +Copyright (C) 2006 XenSource Inc.
    22.7 +
    22.8 +This library is free software; you can redistribute it and/or
    22.9 +modify it under the terms of version 2.1 of the GNU Lesser General Public
   22.10 +License as published by the Free Software Foundation.
   22.11 +
   22.12 +This library is distributed in the hope that it will be useful,
   22.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   22.15 +Lesser General Public License for more details.
   22.16 +
   22.17 +You should have received a copy of the GNU Lesser General Public
   22.18 +License along with this library; if not, write to the Free Software
   22.19 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22.20 +
   22.21 +-->
   22.22 +
   22.23 +<!--
   22.24 +
   22.25 +This is a configuration file for xm; it should be placed in
   22.26 +/etc/xen/xm-config.xml.  If this file is missing, then xm will fall back to
   22.27 +the normal behaviour that's in Xen 3.0.4 and below.  The settings here are
   22.28 +most useful for experimenting with the Xen-API preview in Xen 3.0.4.
   22.29 +
   22.30 +-->
   22.31 +
   22.32 +<xm>
   22.33 +  <!-- The server element describes how to talk to Xend.  The type may be 
   22.34 +       Xen-API or LegacyXMLRPC (the default).  The URI is that of the
   22.35 +       server; you might try http://server:9363/ or
   22.36 +       httpu:///var/run/xend/xen-api.sock for the Xen-API, or
   22.37 +       httpu:///var/run/xend/xmlrpc.sock for the legacy server.
   22.38 +
   22.39 +       The username and password attributes will be used to log in if Xen-API
   22.40 +       is being used.
   22.41 +    -->
   22.42 +  <server type='Xen-API'
   22.43 +          uri='http://localhost:9363/'
   22.44 +          username='me'
   22.45 +          password='mypassword' />
   22.46 +</xm>
    23.1 --- a/tools/ioemu/hw/ne2000.c	Fri Mar 30 10:27:15 2007 -0600
    23.2 +++ b/tools/ioemu/hw/ne2000.c	Fri Mar 30 17:18:42 2007 -0600
    23.3 @@ -770,7 +770,7 @@ void isa_ne2000_init(int base, int irq, 
    23.4               s->macaddr[4],
    23.5               s->macaddr[5]);
    23.6               
    23.7 -    register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
    23.8 +    register_savevm("ne2000", base, 2, ne2000_save, ne2000_load, s);
    23.9  }
   23.10  
   23.11  /***********************************************************/
   23.12 @@ -806,6 +806,7 @@ void pci_ne2000_init(PCIBus *bus, NICInf
   23.13      PCINE2000State *d;
   23.14      NE2000State *s;
   23.15      uint8_t *pci_conf;
   23.16 +    int instance;
   23.17      
   23.18      d = (PCINE2000State *)pci_register_device(bus,
   23.19                                                "NE2000", sizeof(PCINE2000State),
   23.20 @@ -840,8 +841,8 @@ void pci_ne2000_init(PCIBus *bus, NICInf
   23.21               s->macaddr[4],
   23.22               s->macaddr[5]);
   23.23               
   23.24 -    /* XXX: instance number ? */
   23.25 -    register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
   23.26 -    register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load, 
   23.27 -                    &d->dev);
   23.28 +    instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
   23.29 +    register_savevm("ne2000", instance, 2, ne2000_save, ne2000_load, s);
   23.30 +    register_savevm("ne2000_pci", instance, 1, generic_pci_save, 
   23.31 +                    generic_pci_load, &d->dev);
   23.32  }
    24.1 --- a/tools/ioemu/hw/pcnet.c	Fri Mar 30 10:27:15 2007 -0600
    24.2 +++ b/tools/ioemu/hw/pcnet.c	Fri Mar 30 17:18:42 2007 -0600
    24.3 @@ -1727,10 +1727,63 @@ static void pcnet_mmio_map(PCIDevice *pc
    24.4      cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_io_addr);
    24.5  }
    24.6  
    24.7 +
    24.8 +static void pcnet_save(QEMUFile *f, void *opaque)
    24.9 +{
   24.10 +    PCNetState *s = opaque;
   24.11 +    unsigned int i;
   24.12 +
   24.13 +    qemu_put_be32s(f, &s->rap);
   24.14 +    qemu_put_be32s(f, &s->isr);
   24.15 +    qemu_put_be32s(f, &s->lnkst);
   24.16 +    qemu_put_be32s(f, &s->rdra);
   24.17 +    qemu_put_be32s(f, &s->tdra);
   24.18 +    qemu_put_buffer(f, s->prom, 16);
   24.19 +    for (i = 0; i < 128; i++)
   24.20 +        qemu_put_be16s(f, &s->csr[i]);
   24.21 +    for (i = 0; i < 32; i++)
   24.22 +        qemu_put_be16s(f, &s->bcr[i]);
   24.23 +    qemu_put_be64s(f, &s->timer);
   24.24 +    qemu_put_be32s(f, &s->xmit_pos);
   24.25 +    qemu_put_be32s(f, &s->recv_pos);
   24.26 +    qemu_put_buffer(f, s->buffer, 4096);
   24.27 +    qemu_put_be32s(f, &s->tx_busy);
   24.28 +    qemu_put_timer(f, s->poll_timer);
   24.29 +}
   24.30 +
   24.31 +static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
   24.32 +{
   24.33 +    PCNetState *s = opaque;
   24.34 +    int i, ret;
   24.35 +
   24.36 +    if (version_id != 1)
   24.37 +        return -EINVAL;
   24.38 +
   24.39 +    qemu_get_be32s(f, &s->rap);
   24.40 +    qemu_get_be32s(f, &s->isr);
   24.41 +    qemu_get_be32s(f, &s->lnkst);
   24.42 +    qemu_get_be32s(f, &s->rdra);
   24.43 +    qemu_get_be32s(f, &s->tdra);
   24.44 +    qemu_get_buffer(f, s->prom, 16);
   24.45 +    for (i = 0; i < 128; i++)
   24.46 +        qemu_get_be16s(f, &s->csr[i]);
   24.47 +    for (i = 0; i < 32; i++)
   24.48 +        qemu_get_be16s(f, &s->bcr[i]);
   24.49 +    qemu_get_be64s(f, &s->timer);
   24.50 +    qemu_get_be32s(f, &s->xmit_pos);
   24.51 +    qemu_get_be32s(f, &s->recv_pos);
   24.52 +    qemu_get_buffer(f, s->buffer, 4096);
   24.53 +    qemu_get_be32s(f, &s->tx_busy);
   24.54 +    qemu_get_timer(f, s->poll_timer);
   24.55 +
   24.56 +    return 0;
   24.57 +}
   24.58 +
   24.59  void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
   24.60  {
   24.61      PCNetState *d;
   24.62      uint8_t *pci_conf;
   24.63 +    int instance;
   24.64  
   24.65  #if 0
   24.66      printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
   24.67 @@ -1775,6 +1828,11 @@ void pci_pcnet_init(PCIBus *bus, NICInfo
   24.68  
   24.69      d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
   24.70                                   pcnet_can_receive, d);
   24.71 +
   24.72 +    instance = pci_bus_num(bus) << 8 | d->dev.devfn;
   24.73 +    register_savevm("pcnet", instance, 1, pcnet_save, pcnet_load, d);
   24.74 +    register_savevm("pcnet_pci", instance, 1, generic_pci_save,
   24.75 +                    generic_pci_load, &d->dev);
   24.76      
   24.77      snprintf(d->vc->info_str, sizeof(d->vc->info_str),
   24.78               "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
    25.1 --- a/tools/ioemu/hw/piix4acpi.c	Fri Mar 30 10:27:15 2007 -0600
    25.2 +++ b/tools/ioemu/hw/piix4acpi.c	Fri Mar 30 17:18:42 2007 -0600
    25.3 @@ -57,6 +57,20 @@ typedef struct PCIAcpiState {
    25.4      uint16_t pm1_control; /* pm1a_ECNT_BLK */
    25.5  } PCIAcpiState;
    25.6  
    25.7 +static void piix4acpi_save(QEMUFile *f, void *opaque)
    25.8 +{
    25.9 +    PCIAcpiState *s = opaque;
   25.10 +    qemu_put_be16s(f, &s->pm1_control);
   25.11 +}
   25.12 +
   25.13 +static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
   25.14 +{
   25.15 +    PCIAcpiState *s = opaque;
   25.16 +    if (version_id > 1) 
   25.17 +        return -EINVAL;
   25.18 +    qemu_get_be16s(f, &s->pm1_control);
   25.19 +}
   25.20 +
   25.21  static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
   25.22  {
   25.23      PCIAcpiState *s = opaque;
   25.24 @@ -193,4 +207,8 @@ void pci_piix4_acpi_init(PCIBus *bus, in
   25.25      d->pm1_control = SCI_EN;
   25.26  
   25.27      acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
   25.28 +
   25.29 +    register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);    
   25.30 +    register_savevm("piix4acpi_pci", 0, 1, generic_pci_save, generic_pci_load, 
   25.31 +                    &d->dev);
   25.32  }
    26.1 --- a/tools/ioemu/hw/rtl8139.c	Fri Mar 30 10:27:15 2007 -0600
    26.2 +++ b/tools/ioemu/hw/rtl8139.c	Fri Mar 30 17:18:42 2007 -0600
    26.3 @@ -3406,6 +3406,7 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
    26.4      PCIRTL8139State *d;
    26.5      RTL8139State *s;
    26.6      uint8_t *pci_conf;
    26.7 +    int instance;
    26.8      
    26.9      d = (PCIRTL8139State *)pci_register_device(bus,
   26.10                                                "RTL8139", sizeof(PCIRTL8139State),
   26.11 @@ -3460,10 +3461,10 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
   26.12      s->cplus_txbuffer_len = 0;
   26.13      s->cplus_txbuffer_offset = 0;
   26.14               
   26.15 -    /* XXX: instance number ? */
   26.16 -    register_savevm("rtl8139", 0, 2, rtl8139_save, rtl8139_load, s);
   26.17 -    register_savevm("rtl8139_pci", 0, 1, generic_pci_save, generic_pci_load, 
   26.18 -                    &d->dev);
   26.19 +    instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
   26.20 +    register_savevm("rtl8139", instance, 2, rtl8139_save, rtl8139_load, s);
   26.21 +    register_savevm("rtl8139_pci", instance, 1, generic_pci_save, 
   26.22 +                    generic_pci_load, &d->dev);
   26.23  
   26.24  #if RTL8139_ONBOARD_TIMER
   26.25      s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
    27.1 --- a/tools/ioemu/hw/usb-uhci.c	Fri Mar 30 10:27:15 2007 -0600
    27.2 +++ b/tools/ioemu/hw/usb-uhci.c	Fri Mar 30 17:18:42 2007 -0600
    27.3 @@ -700,6 +700,7 @@ int uhci_usb_load(QEMUFile *f, void *opa
    27.4  
    27.5      qemu_get_timer(f, s->frame_timer);
    27.6  
    27.7 +    return 0;
    27.8  }
    27.9  
   27.10  void usb_uhci_init(PCIBus *bus, int devfn)
    28.1 --- a/tools/ioemu/vl.c	Fri Mar 30 10:27:15 2007 -0600
    28.2 +++ b/tools/ioemu/vl.c	Fri Mar 30 17:18:42 2007 -0600
    28.3 @@ -6109,10 +6109,9 @@ int main(int argc, char **argv)
    28.4  #endif /* !CONFIG_DM */
    28.5      cyls = heads = secs = 0;
    28.6      translation = BIOS_ATA_TRANSLATION_AUTO;
    28.7 -    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
    28.8 -
    28.9 -    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
   28.10 -    for(i = 1; i < MAX_SERIAL_PORTS; i++)
   28.11 +    pstrcpy(monitor_device, sizeof(monitor_device), "null");
   28.12 +
   28.13 +    for(i = 0; i < MAX_SERIAL_PORTS; i++)
   28.14          serial_devices[i][0] = '\0';
   28.15      serial_device_index = 0;
   28.16  
    29.1 --- a/tools/libxc/xc_hvm_restore.c	Fri Mar 30 10:27:15 2007 -0600
    29.2 +++ b/tools/libxc/xc_hvm_restore.c	Fri Mar 30 17:18:42 2007 -0600
    29.3 @@ -81,7 +81,7 @@ int xc_hvm_restore(int xc_handle, int io
    29.4      unsigned int rc = 1, n, i;
    29.5      uint32_t rec_len, nr_vcpus;
    29.6      uint8_t *hvm_buf = NULL;
    29.7 -    unsigned long long v_end, memsize;
    29.8 +    unsigned long long v_end;
    29.9      unsigned long shared_page_nr;
   29.10  
   29.11      unsigned long pfn;
   29.12 @@ -91,16 +91,19 @@ int xc_hvm_restore(int xc_handle, int io
   29.13      /* Types of the pfns in the current region */
   29.14      unsigned long region_pfn_type[MAX_BATCH_SIZE];
   29.15  
   29.16 -    /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
   29.17 -    unsigned long nr_pages;
   29.18 -
   29.19      /* The size of an array big enough to contain all guest pfns */
   29.20      unsigned long pfn_array_size = max_pfn + 1;
   29.21  
   29.22 -    /* hvm guest mem size (Mb) */
   29.23 -    memsize = (unsigned long long)*store_mfn;
   29.24 -    v_end = memsize << 20;
   29.25 -    nr_pages = (unsigned long) memsize << (20 - PAGE_SHIFT);
   29.26 +    /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
   29.27 +    unsigned long nr_pages = max_pfn + 1;
   29.28 +    /* MMIO hole doesn't contain RAM */
   29.29 +    if ( nr_pages >= HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT ) 
   29.30 +        nr_pages -= HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; 
   29.31 +    /* VGA hole doesn't contain RAM */
   29.32 +    nr_pages -= 0x20;
   29.33 +
   29.34 +    /* XXX: Unlikely to be true, but matches previous behaviour. :( */
   29.35 +    v_end = (nr_pages + 0x20) << PAGE_SHIFT;
   29.36  
   29.37      DPRINTF("xc_hvm_restore:dom=%d, nr_pages=0x%lx, store_evtchn=%d, "
   29.38              "*store_mfn=%ld, pae=%u, apic=%u.\n", 
   29.39 @@ -146,7 +149,7 @@ int xc_hvm_restore(int xc_handle, int io
   29.40          0, 0, &pfns[0x00]);
   29.41      if ( (rc == 0) && (nr_pages > 0xc0) )
   29.42          rc = xc_domain_memory_populate_physmap(
   29.43 -            xc_handle, dom, nr_pages - 0xc0, 0, 0, &pfns[0xc0]);
   29.44 +            xc_handle, dom, nr_pages - 0xa0, 0, 0, &pfns[0xc0]);
   29.45      if ( rc != 0 )
   29.46      {
   29.47          PERROR("Could not allocate memory for HVM guest.\n");
   29.48 @@ -276,14 +279,6 @@ int xc_hvm_restore(int xc_handle, int io
   29.49      else
   29.50          shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
   29.51  
   29.52 -    /* Paranoia: clean pages. */
   29.53 -    if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) ||
   29.54 -         xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) ||
   29.55 -         xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) ) {
   29.56 -        ERROR("error clearing comms frames!\n");
   29.57 -        goto out;
   29.58 -    }
   29.59 -
   29.60      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
   29.61      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
   29.62      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
    30.1 --- a/tools/libxen/Makefile	Fri Mar 30 10:27:15 2007 -0600
    30.2 +++ b/tools/libxen/Makefile	Fri Mar 30 17:18:42 2007 -0600
    30.3 @@ -51,6 +51,9 @@ libxenapi.a: $(LIBXENAPI_OBJS)
    30.4  test/test_bindings: test/test_bindings.o libxenapi.so
    30.5  	$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
    30.6  
    30.7 +test/test_event_handling: test/test_event_handling.o libxenapi.so
    30.8 +	$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
    30.9 +
   30.10  test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so
   30.11  	$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
   30.12  
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/libxen/include/xen_event.h	Fri Mar 30 17:18:42 2007 -0600
    31.3 @@ -0,0 +1,102 @@
    31.4 +/*
    31.5 + * Copyright (c) 2006-2007, XenSource Inc.
    31.6 + *
    31.7 + * This library is free software; you can redistribute it and/or
    31.8 + * modify it under the terms of the GNU Lesser General Public
    31.9 + * License as published by the Free Software Foundation; either
   31.10 + * version 2.1 of the License, or (at your option) any later version.
   31.11 + *
   31.12 + * This library is distributed in the hope that it will be useful,
   31.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   31.15 + * Lesser General Public License for more details.
   31.16 + *
   31.17 + * You should have received a copy of the GNU Lesser General Public
   31.18 + * License along with this library; if not, write to the Free Software
   31.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   31.20 + */
   31.21 +
   31.22 +#ifndef XEN_EVENT_H
   31.23 +#define XEN_EVENT_H
   31.24 +
   31.25 +#include "xen_common.h"
   31.26 +#include "xen_event_decl.h"
   31.27 +#include "xen_event_operation.h"
   31.28 +#include "xen_string_set.h"
   31.29 +
   31.30 +
   31.31 +/*
   31.32 + * The event class.
   31.33 + * 
   31.34 + * Asynchronous event registration and handling.
   31.35 + */
   31.36 +
   31.37 +
   31.38 +
   31.39 +typedef struct xen_event_record
   31.40 +{
   31.41 +    int64_t id;
   31.42 +    time_t timestamp;
   31.43 +    char *class;
   31.44 +    enum xen_event_operation operation;
   31.45 +    char *ref;
   31.46 +    char *obj_uuid;
   31.47 +} xen_event_record;
   31.48 +
   31.49 +/**
   31.50 + * Allocate a xen_event_record.
   31.51 + */
   31.52 +extern xen_event_record *
   31.53 +xen_event_record_alloc(void);
   31.54 +
   31.55 +/**
   31.56 + * Free the given xen_event_record, and all referenced values.  The
   31.57 + * given record must have been allocated by this library.
   31.58 + */
   31.59 +extern void
   31.60 +xen_event_record_free(xen_event_record *record);
   31.61 +
   31.62 +
   31.63 +typedef struct xen_event_record_set
   31.64 +{
   31.65 +    size_t size;
   31.66 +    xen_event_record *contents[];
   31.67 +} xen_event_record_set;
   31.68 +
   31.69 +/**
   31.70 + * Allocate a xen_event_record_set of the given size.
   31.71 + */
   31.72 +extern xen_event_record_set *
   31.73 +xen_event_record_set_alloc(size_t size);
   31.74 +
   31.75 +/**
   31.76 + * Free the given xen_event_record_set, and all referenced values.  The
   31.77 + * given set must have been allocated by this library.
   31.78 + */
   31.79 +extern void
   31.80 +xen_event_record_set_free(xen_event_record_set *set);
   31.81 +
   31.82 +
   31.83 +/**
   31.84 + * Registers this session with the event system.  Specifying the empty
   31.85 + * list will register for all classes.
   31.86 + */
   31.87 +extern bool
   31.88 +xen_event_register(xen_session *session, struct xen_string_set *classes);
   31.89 +
   31.90 +
   31.91 +/**
   31.92 + * Unregisters this session with the event system.
   31.93 + */
   31.94 +extern bool
   31.95 +xen_event_unregister(xen_session *session, struct xen_string_set *classes);
   31.96 +
   31.97 +
   31.98 +/**
   31.99 + * Blocking call which returns a (possibly empty) batch of events.
  31.100 + */
  31.101 +extern bool
  31.102 +xen_event_next(xen_session *session, struct xen_event_record_set **result);
  31.103 +
  31.104 +
  31.105 +#endif
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tools/libxen/include/xen_event_decl.h	Fri Mar 30 17:18:42 2007 -0600
    32.3 @@ -0,0 +1,25 @@
    32.4 +/*
    32.5 + * Copyright (c) 2006-2007, XenSource Inc.
    32.6 + *
    32.7 + * This library is free software; you can redistribute it and/or
    32.8 + * modify it under the terms of the GNU Lesser General Public
    32.9 + * License as published by the Free Software Foundation; either
   32.10 + * version 2.1 of the License, or (at your option) any later version.
   32.11 + *
   32.12 + * This library is distributed in the hope that it will be useful,
   32.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   32.15 + * Lesser General Public License for more details.
   32.16 + *
   32.17 + * You should have received a copy of the GNU Lesser General Public
   32.18 + * License along with this library; if not, write to the Free Software
   32.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   32.20 + */
   32.21 +
   32.22 +#ifndef XEN_EVENT_DECL_H
   32.23 +#define XEN_EVENT_DECL_H
   32.24 +
   32.25 +struct xen_event_record;
   32.26 +struct xen_event_record_set;
   32.27 +
   32.28 +#endif
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/tools/libxen/include/xen_event_operation.h	Fri Mar 30 17:18:42 2007 -0600
    33.3 @@ -0,0 +1,82 @@
    33.4 +/*
    33.5 + * Copyright (c) 2006-2007, XenSource Inc.
    33.6 + *
    33.7 + * This library is free software; you can redistribute it and/or
    33.8 + * modify it under the terms of the GNU Lesser General Public
    33.9 + * License as published by the Free Software Foundation; either
   33.10 + * version 2.1 of the License, or (at your option) any later version.
   33.11 + *
   33.12 + * This library is distributed in the hope that it will be useful,
   33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   33.15 + * Lesser General Public License for more details.
   33.16 + *
   33.17 + * You should have received a copy of the GNU Lesser General Public
   33.18 + * License along with this library; if not, write to the Free Software
   33.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   33.20 + */
   33.21 +
   33.22 +#ifndef XEN_EVENT_OPERATION_H
   33.23 +#define XEN_EVENT_OPERATION_H
   33.24 +
   33.25 +
   33.26 +#include "xen_common.h"
   33.27 +
   33.28 +
   33.29 +enum xen_event_operation
   33.30 +{
   33.31 +    /**
   33.32 +     * An object has been created
   33.33 +     */
   33.34 +    XEN_EVENT_OPERATION_ADD,
   33.35 +
   33.36 +    /**
   33.37 +     * An object has been deleted
   33.38 +     */
   33.39 +    XEN_EVENT_OPERATION_DEL,
   33.40 +
   33.41 +    /**
   33.42 +     * An object has been modified
   33.43 +     */
   33.44 +    XEN_EVENT_OPERATION_MOD
   33.45 +};
   33.46 +
   33.47 +
   33.48 +typedef struct xen_event_operation_set
   33.49 +{
   33.50 +    size_t size;
   33.51 +    enum xen_event_operation contents[];
   33.52 +} xen_event_operation_set;
   33.53 +
   33.54 +/**
   33.55 + * Allocate a xen_event_operation_set of the given size.
   33.56 + */
   33.57 +extern xen_event_operation_set *
   33.58 +xen_event_operation_set_alloc(size_t size);
   33.59 +
   33.60 +/**
   33.61 + * Free the given xen_event_operation_set.  The given set must have
   33.62 + * been allocated by this library.
   33.63 + */
   33.64 +extern void
   33.65 +xen_event_operation_set_free(xen_event_operation_set *set);
   33.66 +
   33.67 +
   33.68 +/**
   33.69 + * Return the name corresponding to the given code.  This string must
   33.70 + * not be modified or freed.
   33.71 + */
   33.72 +extern const char *
   33.73 +xen_event_operation_to_string(enum xen_event_operation val);
   33.74 +
   33.75 +
   33.76 +/**
   33.77 + * Return the correct code for the given string, or set the session
   33.78 + * object to failure and return an undefined value if the given string does
   33.79 + * not match a known code.
   33.80 + */
   33.81 +extern enum xen_event_operation
   33.82 +xen_event_operation_from_string(xen_session *session, const char *str);
   33.83 +
   33.84 +
   33.85 +#endif
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/tools/libxen/include/xen_event_operation_internal.h	Fri Mar 30 17:18:42 2007 -0600
    34.3 @@ -0,0 +1,37 @@
    34.4 +/*
    34.5 + * Copyright (c) 2006-2007, XenSource Inc.
    34.6 + *
    34.7 + * This library is free software; you can redistribute it and/or
    34.8 + * modify it under the terms of the GNU Lesser General Public
    34.9 + * License as published by the Free Software Foundation; either
   34.10 + * version 2.1 of the License, or (at your option) any later version.
   34.11 + *
   34.12 + * This library is distributed in the hope that it will be useful,
   34.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   34.15 + * Lesser General Public License for more details.
   34.16 + *
   34.17 + * You should have received a copy of the GNU Lesser General Public
   34.18 + * License along with this library; if not, write to the Free Software
   34.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   34.20 + */
   34.21 +
   34.22 +
   34.23 +/*
   34.24 + * Declarations of the abstract types used during demarshalling of enum
   34.25 + * xen_event_operation.  Internal to this library -- do not use from outside.
   34.26 + */
   34.27 +
   34.28 +
   34.29 +#ifndef XEN_EVENT_OPERATION_INTERNAL_H
   34.30 +#define XEN_EVENT_OPERATION_INTERNAL_H
   34.31 +
   34.32 +
   34.33 +#include "xen_internal.h"
   34.34 +
   34.35 +
   34.36 +extern const abstract_type xen_event_operation_abstract_type_;
   34.37 +extern const abstract_type xen_event_operation_set_abstract_type_;
   34.38 +
   34.39 +
   34.40 +#endif
    35.1 --- a/tools/libxen/include/xen_network.h	Fri Mar 30 10:27:15 2007 -0600
    35.2 +++ b/tools/libxen/include/xen_network.h	Fri Mar 30 17:18:42 2007 -0600
    35.3 @@ -22,6 +22,7 @@
    35.4  #include "xen_common.h"
    35.5  #include "xen_network_decl.h"
    35.6  #include "xen_pif_decl.h"
    35.7 +#include "xen_string_string_map.h"
    35.8  #include "xen_vif_decl.h"
    35.9  
   35.10  
   35.11 @@ -68,6 +69,7 @@ typedef struct xen_network_record
   35.12      char *name_description;
   35.13      struct xen_vif_record_opt_set *vifs;
   35.14      struct xen_pif_record_opt_set *pifs;
   35.15 +    xen_string_string_map *other_config;
   35.16  } xen_network_record;
   35.17  
   35.18  /**
   35.19 @@ -220,6 +222,13 @@ xen_network_get_pifs(xen_session *sessio
   35.20  
   35.21  
   35.22  /**
   35.23 + * Get the other_config field of the given network.
   35.24 + */
   35.25 +extern bool
   35.26 +xen_network_get_other_config(xen_session *session, xen_string_string_map **result, xen_network network);
   35.27 +
   35.28 +
   35.29 +/**
   35.30   * Set the name/label field of the given network.
   35.31   */
   35.32  extern bool
   35.33 @@ -234,6 +243,30 @@ xen_network_set_name_description(xen_ses
   35.34  
   35.35  
   35.36  /**
   35.37 + * Set the other_config field of the given network.
   35.38 + */
   35.39 +extern bool
   35.40 +xen_network_set_other_config(xen_session *session, xen_network network, xen_string_string_map *other_config);
   35.41 +
   35.42 +
   35.43 +/**
   35.44 + * Add the given key-value pair to the other_config field of the given
   35.45 + * network.
   35.46 + */
   35.47 +extern bool
   35.48 +xen_network_add_to_other_config(xen_session *session, xen_network network, char *key, char *value);
   35.49 +
   35.50 +
   35.51 +/**
   35.52 + * Remove the given key and its corresponding value from the
   35.53 + * other_config field of the given network.  If the key is not in that Map,
   35.54 + * then do nothing.
   35.55 + */
   35.56 +extern bool
   35.57 +xen_network_remove_from_other_config(xen_session *session, xen_network network, char *key);
   35.58 +
   35.59 +
   35.60 +/**
   35.61   * Return a list of all the networks known to the system.
   35.62   */
   35.63  extern bool
    36.1 --- a/tools/libxen/src/xen_common.c	Fri Mar 30 10:27:15 2007 -0600
    36.2 +++ b/tools/libxen/src/xen_common.c	Fri Mar 30 17:18:42 2007 -0600
    36.3 @@ -1217,11 +1217,88 @@ static void parse_result(xen_session *se
    36.4  }
    36.5  
    36.6  
    36.7 +static void
    36.8 +make_body_add_type(enum abstract_typename typename, abstract_value *v,
    36.9 +                   xmlNode *params_node)
   36.10 +{
   36.11 +    char buf[20];
   36.12 +    switch (typename)
   36.13 +    {
   36.14 +    case STRING:
   36.15 +        add_param(params_node, "string", v->u.string_val);
   36.16 +        break;
   36.17 +
   36.18 +    case INT:
   36.19 +        snprintf(buf, sizeof(buf), "%"PRId64, v->u.int_val);
   36.20 +        add_param(params_node, "string", buf);
   36.21 +        break;
   36.22 +
   36.23 +    case FLOAT:
   36.24 +        snprintf(buf, sizeof(buf), "%lf", v->u.float_val);
   36.25 +        add_param(params_node, "double", buf);
   36.26 +        break;
   36.27 +
   36.28 +    case BOOL:
   36.29 +        add_param(params_node, "boolean", v->u.bool_val ? "1" : "0");
   36.30 +        break;
   36.31 +        
   36.32 +    case VOID:
   36.33 +        add_param(params_node, "string", "");
   36.34 +        break;
   36.35 +
   36.36 +    case ENUM:
   36.37 +        add_param(params_node, "string",
   36.38 +                  v->type->enum_marshaller(v->u.enum_val));
   36.39 +        break;
   36.40 +
   36.41 +    case SET:
   36.42 +    {
   36.43 +        const struct abstract_type *member_type = v->type->child;
   36.44 +        arbitrary_set *set_val = v->u.struct_val;
   36.45 +        abstract_value v;
   36.46 +        xmlNode *data_node = add_param_struct(params_node);
   36.47 +
   36.48 +        for (size_t i = 0; i < set_val->size; i++)
   36.49 +        {
   36.50 +            switch (member_type->typename) {
   36.51 +                case STRING:
   36.52 +                    v.u.string_val = (char *)set_val->contents[i];
   36.53 +                    make_body_add_type(member_type->typename, &v, data_node);
   36.54 +                    break;
   36.55 +                default:
   36.56 +                    assert(false);
   36.57 +            }
   36.58 +        }
   36.59 +    }
   36.60 +    break;
   36.61 +
   36.62 +    case STRUCT:
   36.63 +    {
   36.64 +        size_t member_count = v->type->member_count;
   36.65 +
   36.66 +        xmlNode *struct_node = add_param_struct(params_node);
   36.67 +
   36.68 +        for (size_t i = 0; i < member_count; i++)
   36.69 +        {
   36.70 +            const struct struct_member *mem = v->type->members + i;
   36.71 +            const char *key = mem->key;
   36.72 +            void *struct_value = v->u.struct_val;
   36.73 +
   36.74 +            add_struct_value(mem->type, struct_value + mem->offset,
   36.75 +                             add_struct_member, key, struct_node);
   36.76 +        }
   36.77 +    }
   36.78 +    break;
   36.79 +
   36.80 +    default:
   36.81 +        assert(false);
   36.82 +    }
   36.83 +}
   36.84 +
   36.85 +
   36.86  static char *
   36.87  make_body(const char *method_name, abstract_value params[], int param_count)
   36.88  {
   36.89 -    char buf[20];
   36.90 -
   36.91      xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
   36.92      xmlNode *methodCall = xmlNewNode(NULL, BAD_CAST "methodCall");
   36.93      xmlDocSetRootElement(doc, methodCall);
   36.94 @@ -1235,56 +1312,7 @@ make_body(const char *method_name, abstr
   36.95      for (int p = 0; p < param_count; p++)
   36.96      {
   36.97          abstract_value *v = params + p;
   36.98 -        switch (v->type->typename)
   36.99 -        {
  36.100 -        case STRING:
  36.101 -            add_param(params_node, "string", v->u.string_val);
  36.102 -            break;
  36.103 -
  36.104 -        case INT:
  36.105 -            snprintf(buf, sizeof(buf), "%"PRId64, v->u.int_val);
  36.106 -            add_param(params_node, "string", buf);
  36.107 -            break;
  36.108 -
  36.109 -        case FLOAT:
  36.110 -            snprintf(buf, sizeof(buf), "%lf", v->u.float_val);
  36.111 -            add_param(params_node, "double", buf);
  36.112 -            break;
  36.113 -
  36.114 -        case BOOL:
  36.115 -            add_param(params_node, "boolean", v->u.bool_val ? "1" : "0");
  36.116 -            break;
  36.117 -            
  36.118 -        case VOID:
  36.119 -            add_param(params_node, "string", "");
  36.120 -            break;
  36.121 -
  36.122 -        case ENUM:
  36.123 -            add_param(params_node, "string",
  36.124 -                      v->type->enum_marshaller(v->u.enum_val));
  36.125 -            break;
  36.126 -
  36.127 -        case STRUCT:
  36.128 -        {
  36.129 -            size_t member_count = v->type->member_count;
  36.130 -
  36.131 -            xmlNode *struct_node = add_param_struct(params_node);
  36.132 -
  36.133 -            for (size_t i = 0; i < member_count; i++)
  36.134 -            {
  36.135 -                const struct struct_member *mem = v->type->members + i;
  36.136 -                const char *key = mem->key;
  36.137 -                void *struct_value = v->u.struct_val;
  36.138 -
  36.139 -                add_struct_value(mem->type, struct_value + mem->offset,
  36.140 -                                 add_struct_member, key, struct_node);
  36.141 -            }
  36.142 -        }
  36.143 -        break;
  36.144 -
  36.145 -        default:
  36.146 -            assert(false);
  36.147 -        }
  36.148 +        make_body_add_type(v->type->typename, v, params_node);
  36.149      }
  36.150  
  36.151      xmlBufferPtr buffer = xmlBufferCreate();
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tools/libxen/src/xen_event.c	Fri Mar 30 17:18:42 2007 -0600
    37.3 @@ -0,0 +1,123 @@
    37.4 +/*
    37.5 + * Copyright (c) 2006-2007, XenSource Inc.
    37.6 + *
    37.7 + * This library is free software; you can redistribute it and/or
    37.8 + * modify it under the terms of the GNU Lesser General Public
    37.9 + * License as published by the Free Software Foundation; either
   37.10 + * version 2.1 of the License, or (at your option) any later version.
   37.11 + *
   37.12 + * This library is distributed in the hope that it will be useful,
   37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   37.15 + * Lesser General Public License for more details.
   37.16 + *
   37.17 + * You should have received a copy of the GNU Lesser General Public
   37.18 + * License along with this library; if not, write to the Free Software
   37.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   37.20 + */
   37.21 +
   37.22 +
   37.23 +#include <stddef.h>
   37.24 +#include <stdlib.h>
   37.25 +
   37.26 +#include "xen_common.h"
   37.27 +#include "xen_event.h"
   37.28 +#include "xen_event_operation_internal.h"
   37.29 +#include "xen_internal.h"
   37.30 +
   37.31 +
   37.32 +XEN_ALLOC(xen_event_record)
   37.33 +XEN_SET_ALLOC_FREE(xen_event_record)
   37.34 +
   37.35 +
   37.36 +static const struct_member xen_event_record_struct_members[] =
   37.37 +    {
   37.38 +        { .key = "id",
   37.39 +          .type = &abstract_type_int,
   37.40 +          .offset = offsetof(xen_event_record, id) },
   37.41 +        { .key = "timestamp",
   37.42 +          .type = &abstract_type_datetime,
   37.43 +          .offset = offsetof(xen_event_record, timestamp) },
   37.44 +        { .key = "class",
   37.45 +          .type = &abstract_type_string,
   37.46 +          .offset = offsetof(xen_event_record, class) },
   37.47 +        { .key = "operation",
   37.48 +          .type = &xen_event_operation_abstract_type_,
   37.49 +          .offset = offsetof(xen_event_record, operation) },
   37.50 +        { .key = "ref",
   37.51 +          .type = &abstract_type_string,
   37.52 +          .offset = offsetof(xen_event_record, ref) },
   37.53 +        { .key = "obj_uuid",
   37.54 +          .type = &abstract_type_string,
   37.55 +          .offset = offsetof(xen_event_record, obj_uuid) }
   37.56 +    };
   37.57 +
   37.58 +const abstract_type xen_event_record_abstract_type_ =
   37.59 +    {
   37.60 +       .typename = STRUCT,
   37.61 +       .struct_size = sizeof(xen_event_record),
   37.62 +       .member_count =
   37.63 +           sizeof(xen_event_record_struct_members) / sizeof(struct_member),
   37.64 +       .members = xen_event_record_struct_members
   37.65 +    };
   37.66 +
   37.67 +
   37.68 +const abstract_type xen_event_record_set_abstract_type_ =
   37.69 +    {
   37.70 +       .typename = SET,
   37.71 +        .child = &xen_event_record_abstract_type_
   37.72 +    };
   37.73 +
   37.74 +
   37.75 +void
   37.76 +xen_event_record_free(xen_event_record *record)
   37.77 +{
   37.78 +    if (record == NULL)
   37.79 +    {
   37.80 +        return;
   37.81 +    }
   37.82 +    free(record->class);
   37.83 +    free(record->ref);
   37.84 +    free(record->obj_uuid);
   37.85 +    free(record);
   37.86 +}
   37.87 +
   37.88 +
   37.89 +bool
   37.90 +xen_event_register(xen_session *session, struct xen_string_set *classes)
   37.91 +{
   37.92 +    abstract_value param_values[] =
   37.93 +        {
   37.94 +            { .type = &abstract_type_string_set,
   37.95 +              .u.set_val = (arbitrary_set *)classes }
   37.96 +        };
   37.97 +
   37.98 +    xen_call_(session, "event.register", param_values, 1, NULL, NULL);
   37.99 +    return session->ok;
  37.100 +}
  37.101 +
  37.102 +
  37.103 +bool
  37.104 +xen_event_unregister(xen_session *session, struct xen_string_set *classes)
  37.105 +{
  37.106 +    abstract_value param_values[] =
  37.107 +        {
  37.108 +            { .type = &abstract_type_string_set,
  37.109 +              .u.set_val = (arbitrary_set *)classes }
  37.110 +        };
  37.111 +
  37.112 +    xen_call_(session, "event.unregister", param_values, 1, NULL, NULL);
  37.113 +    return session->ok;
  37.114 +}
  37.115 +
  37.116 +
  37.117 +bool
  37.118 +xen_event_next(xen_session *session, struct xen_event_record_set **result)
  37.119 +{
  37.120 +
  37.121 +    abstract_type result_type = xen_event_record_set_abstract_type_;
  37.122 +
  37.123 +    *result = NULL;
  37.124 +    xen_call_(session, "event.next", NULL, 0, &result_type, result);
  37.125 +    return session->ok;
  37.126 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/tools/libxen/src/xen_event_operation.c	Fri Mar 30 17:18:42 2007 -0600
    38.3 @@ -0,0 +1,75 @@
    38.4 +/*
    38.5 + * Copyright (c) 2006-2007, XenSource Inc.
    38.6 + *
    38.7 + * This library is free software; you can redistribute it and/or
    38.8 + * modify it under the terms of the GNU Lesser General Public
    38.9 + * License as published by the Free Software Foundation; either
   38.10 + * version 2.1 of the License, or (at your option) any later version.
   38.11 + *
   38.12 + * This library is distributed in the hope that it will be useful,
   38.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   38.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   38.15 + * Lesser General Public License for more details.
   38.16 + *
   38.17 + * You should have received a copy of the GNU Lesser General Public
   38.18 + * License along with this library; if not, write to the Free Software
   38.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   38.20 + */
   38.21 +
   38.22 +#include <string.h>
   38.23 +
   38.24 +#include "xen_internal.h"
   38.25 +#include "xen_event_operation.h"
   38.26 +#include "xen_event_operation_internal.h"
   38.27 +
   38.28 +
   38.29 +/*
   38.30 + * Maintain this in the same order as the enum declaration!
   38.31 + */
   38.32 +static const char *lookup_table[] =
   38.33 +{
   38.34 +    "add",
   38.35 +    "del",
   38.36 +    "mod"
   38.37 +};
   38.38 +
   38.39 +
   38.40 +extern xen_event_operation_set *
   38.41 +xen_event_operation_set_alloc(size_t size)
   38.42 +{
   38.43 +    return calloc(1, sizeof(xen_event_operation_set) +
   38.44 +                  size * sizeof(enum xen_event_operation));
   38.45 +}
   38.46 +
   38.47 +
   38.48 +extern void
   38.49 +xen_event_operation_set_free(xen_event_operation_set *set)
   38.50 +{
   38.51 +    free(set);
   38.52 +}
   38.53 +
   38.54 +
   38.55 +const char *
   38.56 +xen_event_operation_to_string(enum xen_event_operation val)
   38.57 +{
   38.58 +    return lookup_table[val];
   38.59 +}
   38.60 +
   38.61 +
   38.62 +extern enum xen_event_operation
   38.63 +xen_event_operation_from_string(xen_session *session, const char *str)
   38.64 +{
   38.65 +    return ENUM_LOOKUP(session, str, lookup_table);
   38.66 +}
   38.67 +
   38.68 +
   38.69 +const abstract_type xen_event_operation_abstract_type_ =
   38.70 +    {
   38.71 +        .typename = ENUM,
   38.72 +        .enum_marshaller =
   38.73 +             (const char *(*)(int))&xen_event_operation_to_string,
   38.74 +        .enum_demarshaller =
   38.75 +             (int (*)(xen_session *, const char *))&xen_event_operation_from_string
   38.76 +    };
   38.77 +
   38.78 +
    39.1 --- a/tools/libxen/src/xen_network.c	Fri Mar 30 10:27:15 2007 -0600
    39.2 +++ b/tools/libxen/src/xen_network.c	Fri Mar 30 17:18:42 2007 -0600
    39.3 @@ -24,6 +24,7 @@
    39.4  #include "xen_internal.h"
    39.5  #include "xen_network.h"
    39.6  #include "xen_pif.h"
    39.7 +#include "xen_string_string_map.h"
    39.8  #include "xen_vif.h"
    39.9  
   39.10  
   39.11 @@ -52,7 +53,10 @@ static const struct_member xen_network_r
   39.12            .offset = offsetof(xen_network_record, vifs) },
   39.13          { .key = "PIFs",
   39.14            .type = &abstract_type_ref_set,
   39.15 -          .offset = offsetof(xen_network_record, pifs) }
   39.16 +          .offset = offsetof(xen_network_record, pifs) },
   39.17 +        { .key = "other_config",
   39.18 +          .type = &abstract_type_string_string_map,
   39.19 +          .offset = offsetof(xen_network_record, other_config) }
   39.20      };
   39.21  
   39.22  const abstract_type xen_network_record_abstract_type_ =
   39.23 @@ -78,6 +82,7 @@ xen_network_record_free(xen_network_reco
   39.24      free(record->name_description);
   39.25      xen_vif_record_opt_set_free(record->vifs);
   39.26      xen_pif_record_opt_set_free(record->pifs);
   39.27 +    xen_string_string_map_free(record->other_config);
   39.28      free(record);
   39.29  }
   39.30  
   39.31 @@ -239,6 +244,23 @@ xen_network_get_pifs(xen_session *sessio
   39.32  
   39.33  
   39.34  bool
   39.35 +xen_network_get_other_config(xen_session *session, xen_string_string_map **result, xen_network network)
   39.36 +{
   39.37 +    abstract_value param_values[] =
   39.38 +        {
   39.39 +            { .type = &abstract_type_string,
   39.40 +              .u.string_val = network }
   39.41 +        };
   39.42 +
   39.43 +    abstract_type result_type = abstract_type_string_string_map;
   39.44 +
   39.45 +    *result = NULL;
   39.46 +    XEN_CALL_("network.get_other_config");
   39.47 +    return session->ok;
   39.48 +}
   39.49 +
   39.50 +
   39.51 +bool
   39.52  xen_network_set_name_label(xen_session *session, xen_network network, char *label)
   39.53  {
   39.54      abstract_value param_values[] =
   39.55 @@ -271,6 +293,56 @@ xen_network_set_name_description(xen_ses
   39.56  
   39.57  
   39.58  bool
   39.59 +xen_network_set_other_config(xen_session *session, xen_network network, xen_string_string_map *other_config)
   39.60 +{
   39.61 +    abstract_value param_values[] =
   39.62 +        {
   39.63 +            { .type = &abstract_type_string,
   39.64 +              .u.string_val = network },
   39.65 +            { .type = &abstract_type_string_string_map,
   39.66 +              .u.set_val = (arbitrary_set *)other_config }
   39.67 +        };
   39.68 +
   39.69 +    xen_call_(session, "network.set_other_config", param_values, 2, NULL, NULL);
   39.70 +    return session->ok;
   39.71 +}
   39.72 +
   39.73 +
   39.74 +bool
   39.75 +xen_network_add_to_other_config(xen_session *session, xen_network network, char *key, char *value)
   39.76 +{
   39.77 +    abstract_value param_values[] =
   39.78 +        {
   39.79 +            { .type = &abstract_type_string,
   39.80 +              .u.string_val = network },
   39.81 +            { .type = &abstract_type_string,
   39.82 +              .u.string_val = key },
   39.83 +            { .type = &abstract_type_string,
   39.84 +              .u.string_val = value }
   39.85 +        };
   39.86 +
   39.87 +    xen_call_(session, "network.add_to_other_config", param_values, 3, NULL, NULL);
   39.88 +    return session->ok;
   39.89 +}
   39.90 +
   39.91 +
   39.92 +bool
   39.93 +xen_network_remove_from_other_config(xen_session *session, xen_network network, char *key)
   39.94 +{
   39.95 +    abstract_value param_values[] =
   39.96 +        {
   39.97 +            { .type = &abstract_type_string,
   39.98 +              .u.string_val = network },
   39.99 +            { .type = &abstract_type_string,
  39.100 +              .u.string_val = key }
  39.101 +        };
  39.102 +
  39.103 +    xen_call_(session, "network.remove_from_other_config", param_values, 2, NULL, NULL);
  39.104 +    return session->ok;
  39.105 +}
  39.106 +
  39.107 +
  39.108 +bool
  39.109  xen_network_get_all(xen_session *session, struct xen_network_set **result)
  39.110  {
  39.111  
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/tools/libxen/test/test_event_handling.c	Fri Mar 30 17:18:42 2007 -0600
    40.3 @@ -0,0 +1,211 @@
    40.4 +/*
    40.5 + * Copyright (c) 2006-2007 XenSource, Inc.
    40.6 + *
    40.7 + * This library is free software; you can redistribute it and/or
    40.8 + * modify it under the terms of the GNU Lesser General Public
    40.9 + * License as published by the Free Software Foundation; either
   40.10 + * version 2.1 of the License, or (at your option) any later version.
   40.11 + *
   40.12 + * This library is distributed in the hope that it will be useful,
   40.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   40.15 + * Lesser General Public License for more details.
   40.16 + *
   40.17 + * You should have received a copy of the GNU Lesser General Public
   40.18 + * License along with this library; if not, write to the Free Software
   40.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   40.20 + */
   40.21 +
   40.22 +#define _GNU_SOURCE
   40.23 +#include <assert.h>
   40.24 +#include <inttypes.h>
   40.25 +#include <stdlib.h>
   40.26 +#include <stdio.h>
   40.27 +#include <string.h>
   40.28 +
   40.29 +#include <libxml/parser.h>
   40.30 +#include <curl/curl.h>
   40.31 +
   40.32 +#include "xen_event.h"
   40.33 +
   40.34 +//#define PRINT_XML
   40.35 +
   40.36 +static void usage()
   40.37 +{
   40.38 +    fprintf(stderr,
   40.39 +"Usage:\n"
   40.40 +"\n"
   40.41 +"    test_event_handling <server> <username> <password>\n"
   40.42 +"\n"
   40.43 +"where\n"
   40.44 +"        <server>   is the server's host and port, e.g. localhost:9363;\n"
   40.45 +"        <username> is the username to use at the server; and\n"
   40.46 +"        <password> is the password.\n");
   40.47 +
   40.48 +    exit(EXIT_FAILURE);
   40.49 +}
   40.50 +
   40.51 +
   40.52 +static char *url;
   40.53 +
   40.54 +
   40.55 +typedef struct
   40.56 +{
   40.57 +    xen_result_func func;
   40.58 +    void *handle;
   40.59 +} xen_comms;
   40.60 +
   40.61 +
   40.62 +static size_t
   40.63 +write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
   40.64 +{
   40.65 +    size_t n = size * nmemb;
   40.66 +#ifdef PRINT_XML
   40.67 +    printf("\n\n---Result from server -----------------------\n");
   40.68 +    printf("%s\n",((char*) ptr));
   40.69 +    fflush(stdout);
   40.70 +#endif
   40.71 +    return comms->func(ptr, n, comms->handle) ? n : 0;
   40.72 +}
   40.73 +
   40.74 +
   40.75 +static int
   40.76 +call_func(const void *data, size_t len, void *user_handle,
   40.77 +          void *result_handle, xen_result_func result_func)
   40.78 +{
   40.79 +    (void)user_handle;
   40.80 +
   40.81 +#ifdef PRINT_XML
   40.82 +    printf("\n\n---Data to server: -----------------------\n");
   40.83 +    printf("%s\n",((char*) data));
   40.84 +    fflush(stdout);
   40.85 +#endif
   40.86 +
   40.87 +    CURL *curl = curl_easy_init();
   40.88 +    if (!curl) {
   40.89 +        return -1;
   40.90 +    }
   40.91 +
   40.92 +    xen_comms comms = {
   40.93 +        .func = result_func,
   40.94 +        .handle = result_handle
   40.95 +    };
   40.96 +
   40.97 +    curl_easy_setopt(curl, CURLOPT_URL, url);
   40.98 +    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
   40.99 +    curl_easy_setopt(curl, CURLOPT_MUTE, 1);
  40.100 +    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
  40.101 +    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
  40.102 +    curl_easy_setopt(curl, CURLOPT_POST, 1);
  40.103 +    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
  40.104 +    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
  40.105 +
  40.106 +    CURLcode result = curl_easy_perform(curl);
  40.107 +
  40.108 +    curl_easy_cleanup(curl);
  40.109 +
  40.110 +    return result;
  40.111 +}
  40.112 +
  40.113 +
  40.114 +static void print_error(xen_session *session)
  40.115 +{
  40.116 +    fprintf(stderr, "Error: %d", session->error_description_count);
  40.117 +    for (int i = 0; i < session->error_description_count; i++)
  40.118 +    {
  40.119 +        fprintf(stderr, "%s ", session->error_description[i]);
  40.120 +    }
  40.121 +    fprintf(stderr, "\n");
  40.122 +}
  40.123 +
  40.124 +
  40.125 +/**
  40.126 + * Workaround for whinging GCCs, as suggested by strftime(3).
  40.127 + */
  40.128 +static size_t my_strftime(char *s, size_t max, const char *fmt,
  40.129 +                          const struct tm *tm)
  40.130 +{
  40.131 +    return strftime(s, max, fmt, tm);
  40.132 +}
  40.133 +
  40.134 +
  40.135 +int main(int argc, char **argv)
  40.136 +{
  40.137 +    if (argc != 4)
  40.138 +    {
  40.139 +        usage();
  40.140 +    }
  40.141 +
  40.142 +    url = argv[1];
  40.143 +    char *username = argv[2];
  40.144 +    char *password = argv[3];
  40.145 +
  40.146 +    xmlInitParser();
  40.147 +    xen_init();
  40.148 +    curl_global_init(CURL_GLOBAL_ALL);
  40.149 +
  40.150 +#define CLEANUP                                 \
  40.151 +    do {                                        \
  40.152 +        xen_session_logout(session);            \
  40.153 +        curl_global_cleanup();                  \
  40.154 +        xen_fini();                             \
  40.155 +        xmlCleanupParser();                     \
  40.156 +    } while(0)                                  \
  40.157 +
  40.158 +    
  40.159 +    xen_session *session =
  40.160 +        xen_session_login_with_password(call_func, NULL, username, password);
  40.161 +
  40.162 +    struct xen_string_set *classes = xen_string_set_alloc(0);
  40.163 +    xen_event_register(session, classes);
  40.164 +    xen_string_set_free(classes);
  40.165 +
  40.166 +    if (!session->ok)
  40.167 +    {
  40.168 +        print_error(session);
  40.169 +        CLEANUP;
  40.170 +        return 1;
  40.171 +    }
  40.172 +
  40.173 +    while (true)
  40.174 +    {
  40.175 +        struct xen_event_record_set *events;
  40.176 +        if (!xen_event_next(session, &events))
  40.177 +        {
  40.178 +            print_error(session);
  40.179 +            CLEANUP;
  40.180 +            return 1;
  40.181 +        }
  40.182 +
  40.183 +        for (size_t i = 0; i < events->size; i++)
  40.184 +        {
  40.185 +            xen_event_record *ev = events->contents[i];
  40.186 +            char time[256];
  40.187 +            struct tm *tm = localtime(&ev->timestamp);
  40.188 +            my_strftime(time, 256, "%c, local time", tm);
  40.189 +            printf("Event received: ID = %"PRId64", %s.\n", ev->id, time);
  40.190 +            switch (ev->operation)
  40.191 +            {
  40.192 +            case XEN_EVENT_OPERATION_ADD:
  40.193 +                printf("%s created with UUID %s.\n", ev->class, ev->obj_uuid);
  40.194 +                break;
  40.195 +
  40.196 +            case XEN_EVENT_OPERATION_DEL:
  40.197 +                printf("%s with UUID %s deleted.\n", ev->class, ev->obj_uuid);
  40.198 +                break;
  40.199 +
  40.200 +            case XEN_EVENT_OPERATION_MOD:
  40.201 +                printf("%s with UUID %s modified.\n", ev->class, ev->obj_uuid);
  40.202 +                break;
  40.203 +            default:
  40.204 +                assert(false);
  40.205 +            }
  40.206 +        }
  40.207 +
  40.208 +        xen_event_record_set_free(events);
  40.209 +    }
  40.210 +
  40.211 +    CLEANUP;
  40.212 +
  40.213 +    return 0;
  40.214 +}
    41.1 --- a/tools/pygrub/src/pygrub	Fri Mar 30 10:27:15 2007 -0600
    41.2 +++ b/tools/pygrub/src/pygrub	Fri Mar 30 17:18:42 2007 -0600
    41.3 @@ -125,16 +125,13 @@ class GrubLineEditor(curses.textpad.Text
    41.4          is that we can handle lines longer than the window."""
    41.5  
    41.6          self.win.clear()
    41.7 -        if self.pos > 70:
    41.8 -            if self.pos > 130:
    41.9 -                off = 120
   41.10 -            else:
   41.11 -                off = 55
   41.12 -            l = [ "<" ] + self.line[off:]
   41.13 -            p = self.pos - off
   41.14 -        else:
   41.15 -            l = self.line[:70]
   41.16 -            p = self.pos
   41.17 +        p = self.pos
   41.18 +        off = 0
   41.19 +        while p > 70:
   41.20 +            p -= 55
   41.21 +            off += 55
   41.22 +
   41.23 +        l = self.line[off:off+70]
   41.24          self.win.addstr(0, 0, string.join(l, ("")))
   41.25          if self.pos > 70:
   41.26              self.win.addch(0, 0, curses.ACS_LARROW)
    42.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Fri Mar 30 10:27:15 2007 -0600
    42.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri Mar 30 17:18:42 2007 -0600
    42.3 @@ -467,6 +467,26 @@ static PyObject *pyxc_linux_build(XcObje
    42.4      return pyxc_error_to_exception();
    42.5  }
    42.6  
    42.7 +static PyObject *pyxc_get_hvm_param(XcObject *self,
    42.8 +                                    PyObject *args,
    42.9 +                                    PyObject *kwds)
   42.10 +{
   42.11 +    uint32_t dom;
   42.12 +    int param;
   42.13 +    unsigned long value;
   42.14 +
   42.15 +    static char *kwd_list[] = { "domid", "param", NULL }; 
   42.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
   42.17 +                                      &dom, &param) )
   42.18 +        return NULL;
   42.19 +
   42.20 +    if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
   42.21 +        return pyxc_error_to_exception();
   42.22 +
   42.23 +    return Py_BuildValue("i", value);
   42.24 +
   42.25 +}
   42.26 +
   42.27  static PyObject *pyxc_hvm_build(XcObject *self,
   42.28                                  PyObject *args,
   42.29                                  PyObject *kwds)
   42.30 @@ -1225,6 +1245,14 @@ static PyMethodDef pyxc_methods[] = {
   42.31        " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
   42.32        "Returns: [int] 0 on success; -1 on error.\n" },
   42.33  
   42.34 +    { "hvm_get_param", 
   42.35 +      (PyCFunction)pyxc_get_hvm_param, 
   42.36 +      METH_VARARGS | METH_KEYWORDS, "\n"
   42.37 +      "get a parameter of HVM guest OS.\n"
   42.38 +      " dom     [int]:      Identifier of domain to build into.\n"
   42.39 +      " param   [int]:      No. of HVM param.\n"
   42.40 +      "Returns: [int] value of the param.\n" },
   42.41 +
   42.42      { "sched_id_get",
   42.43        (PyCFunction)pyxc_sched_id_get,
   42.44        METH_NOARGS, "\n"
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/tools/python/xen/util/xmlrpcclient.py	Fri Mar 30 17:18:42 2007 -0600
    43.3 @@ -0,0 +1,123 @@
    43.4 +#============================================================================
    43.5 +# This library is free software; you can redistribute it and/or
    43.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    43.7 +# License as published by the Free Software Foundation.
    43.8 +#
    43.9 +# This library is distributed in the hope that it will be useful,
   43.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   43.12 +# Lesser General Public License for more details.
   43.13 +#
   43.14 +# You should have received a copy of the GNU Lesser General Public
   43.15 +# License along with this library; if not, write to the Free Software
   43.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   43.17 +#============================================================================
   43.18 +# Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
   43.19 +# Copyright (C) 2007 XenSource Inc.
   43.20 +#============================================================================
   43.21 +
   43.22 +
   43.23 +from httplib import FakeSocket, HTTPConnection, HTTP
   43.24 +import socket
   43.25 +import string
   43.26 +import xmlrpclib
   43.27 +from types import StringTypes
   43.28 +
   43.29 +
   43.30 +try:
   43.31 +    import SSHTransport
   43.32 +    ssh_enabled = True
   43.33 +except ImportError:
   43.34 +    # SSHTransport is disabled on Python <2.4, because it uses the subprocess
   43.35 +    # package.
   43.36 +    ssh_enabled = False
   43.37 +
   43.38 +
   43.39 +# A new ServerProxy that also supports httpu urls.  An http URL comes in the
   43.40 +# form:
   43.41 +#
   43.42 +# httpu:///absolute/path/to/socket.sock
   43.43 +#
   43.44 +# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
   43.45 +
   43.46 +class HTTPUnixConnection(HTTPConnection):
   43.47 +    def connect(self):
   43.48 +        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   43.49 +        self.sock.connect(self.host)
   43.50 +
   43.51 +class HTTPUnix(HTTP):
   43.52 +    _connection_class = HTTPUnixConnection
   43.53 +
   43.54 +class UnixTransport(xmlrpclib.Transport):
   43.55 +    def request(self, host, handler, request_body, verbose=0):
   43.56 +        self.__handler = handler
   43.57 +        return xmlrpclib.Transport.request(self, host, '/RPC2',
   43.58 +                                           request_body, verbose)
   43.59 +    def make_connection(self, host):
   43.60 +        return HTTPUnix(self.__handler)
   43.61 +
   43.62 +
   43.63 +# We need our own transport for HTTPS, because xmlrpclib.SafeTransport is
   43.64 +# broken -- it does not handle ERROR_ZERO_RETURN properly.
   43.65 +class HTTPSTransport(xmlrpclib.SafeTransport):
   43.66 +    def _parse_response(self, file, sock):
   43.67 +        p, u = self.getparser()
   43.68 +        while 1:
   43.69 +            try:
   43.70 +                if sock:
   43.71 +                    response = sock.recv(1024)
   43.72 +                else:
   43.73 +                    response = file.read(1024)
   43.74 +            except socket.sslerror, exn:
   43.75 +                if exn[0] == socket.SSL_ERROR_ZERO_RETURN:
   43.76 +                    break
   43.77 +                raise
   43.78 +                
   43.79 +            if not response:
   43.80 +                break
   43.81 +            if self.verbose:
   43.82 +                print 'body:', repr(response)
   43.83 +            p.feed(response)
   43.84 +            
   43.85 +        file.close()
   43.86 +        p.close()
   43.87 +        return u.close()
   43.88 +
   43.89 +
   43.90 +# See xmlrpclib2.TCPXMLRPCServer._marshalled_dispatch.
   43.91 +def conv_string(x):
   43.92 +    if isinstance(x, StringTypes):
   43.93 +        s = string.replace(x, "'", r"\047")
   43.94 +        exec "s = '" + s + "'"
   43.95 +        return s
   43.96 +    else:
   43.97 +        return x
   43.98 +
   43.99 +
  43.100 +class ServerProxy(xmlrpclib.ServerProxy):
  43.101 +    def __init__(self, uri, transport=None, encoding=None, verbose=0,
  43.102 +                 allow_none=1):
  43.103 +        if transport == None:
  43.104 +            (protocol, rest) = uri.split(':', 1)
  43.105 +            if protocol == 'httpu':
  43.106 +                uri = 'http:' + rest
  43.107 +                transport = UnixTransport()
  43.108 +            elif protocol == 'https':
  43.109 +                transport = HTTPSTransport()
  43.110 +            elif protocol == 'ssh':
  43.111 +                global ssh_enabled
  43.112 +                if ssh_enabled:
  43.113 +                    (transport, uri) = SSHTransport.getHTTPURI(uri)
  43.114 +                else:
  43.115 +                    raise ValueError(
  43.116 +                        "SSH transport not supported on Python <2.4.")
  43.117 +        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
  43.118 +                                       verbose, allow_none)
  43.119 +
  43.120 +    def __request(self, methodname, params):
  43.121 +        response = xmlrpclib.ServerProxy.__request(self, methodname, params)
  43.122 +
  43.123 +        if isinstance(response, tuple):
  43.124 +            return tuple([conv_string(x) for x in response])
  43.125 +        else:
  43.126 +            return conv_string(response)
    44.1 --- a/tools/python/xen/util/xmlrpclib2.py	Fri Mar 30 10:27:15 2007 -0600
    44.2 +++ b/tools/python/xen/util/xmlrpclib2.py	Fri Mar 30 17:18:42 2007 -0600
    44.3 @@ -21,12 +21,10 @@ An enhanced XML-RPC client/server interf
    44.4  """
    44.5  
    44.6  import re
    44.7 -import string
    44.8  import fcntl
    44.9  from types import *
   44.10      
   44.11  
   44.12 -from httplib import HTTPConnection, HTTP
   44.13  from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
   44.14  import SocketServer
   44.15  import xmlrpclib, socket, os, stat
   44.16 @@ -36,14 +34,6 @@ import mkdir
   44.17  from xen.web import connection
   44.18  from xen.xend.XendLogging import log
   44.19  
   44.20 -try:
   44.21 -    import SSHTransport
   44.22 -    ssh_enabled = True
   44.23 -except ImportError:
   44.24 -    # SSHTransport is disabled on Python <2.4, because it uses the subprocess
   44.25 -    # package.
   44.26 -    ssh_enabled = False
   44.27 -
   44.28  #
   44.29  # Convert all integers to strings as described in the Xen API
   44.30  #
   44.31 @@ -64,13 +54,6 @@ def stringify(value):
   44.32          return value
   44.33  
   44.34  
   44.35 -# A new ServerProxy that also supports httpu urls.  An http URL comes in the
   44.36 -# form:
   44.37 -#
   44.38 -# httpu:///absolute/path/to/socket.sock
   44.39 -#
   44.40 -# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
   44.41 -
   44.42  # We're forced to subclass the RequestHandler class so that we can work around
   44.43  # some bugs in Keep-Alive handling and also enabled it by default
   44.44  class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
   44.45 @@ -106,60 +89,6 @@ class XMLRPCRequestHandler(SimpleXMLRPCR
   44.46          if self.close_connection == 1:
   44.47              self.connection.shutdown(1)
   44.48  
   44.49 -class HTTPUnixConnection(HTTPConnection):
   44.50 -    def connect(self):
   44.51 -        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   44.52 -        self.sock.connect(self.host)
   44.53 -
   44.54 -class HTTPUnix(HTTP):
   44.55 -    _connection_class = HTTPUnixConnection
   44.56 -
   44.57 -class UnixTransport(xmlrpclib.Transport):
   44.58 -    def request(self, host, handler, request_body, verbose=0):
   44.59 -        self.__handler = handler
   44.60 -        return xmlrpclib.Transport.request(self, host, '/RPC2',
   44.61 -                                           request_body, verbose)
   44.62 -    def make_connection(self, host):
   44.63 -        return HTTPUnix(self.__handler)
   44.64 -
   44.65 -
   44.66 -# See _marshalled_dispatch below.
   44.67 -def conv_string(x):
   44.68 -    if isinstance(x, StringTypes):
   44.69 -        s = string.replace(x, "'", r"\047")
   44.70 -        exec "s = '" + s + "'"
   44.71 -        return s
   44.72 -    else:
   44.73 -        return x
   44.74 -
   44.75 -
   44.76 -class ServerProxy(xmlrpclib.ServerProxy):
   44.77 -    def __init__(self, uri, transport=None, encoding=None, verbose=0,
   44.78 -                 allow_none=1):
   44.79 -        if transport == None:
   44.80 -            (protocol, rest) = uri.split(':', 1)
   44.81 -            if protocol == 'httpu':
   44.82 -                uri = 'http:' + rest
   44.83 -                transport = UnixTransport()
   44.84 -            elif protocol == 'ssh':
   44.85 -                global ssh_enabled
   44.86 -                if ssh_enabled:
   44.87 -                    (transport, uri) = SSHTransport.getHTTPURI(uri)
   44.88 -                else:
   44.89 -                    raise ValueError(
   44.90 -                        "SSH transport not supported on Python <2.4.")
   44.91 -        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
   44.92 -                                       verbose, allow_none)
   44.93 -
   44.94 -    def __request(self, methodname, params):
   44.95 -        response = xmlrpclib.ServerProxy.__request(self, methodname, params)
   44.96 -
   44.97 -        if isinstance(response, tuple):
   44.98 -            return tuple([conv_string(x) for x in response])
   44.99 -        else:
  44.100 -            return conv_string(response)
  44.101 -
  44.102 -
  44.103  # This is a base XML-RPC server for TCP.  It sets allow_reuse_address to
  44.104  # true, and has an improved marshaller that logs and serializes exceptions.
  44.105  
    45.1 --- a/tools/python/xen/xend/XendAPI.py	Fri Mar 30 10:27:15 2007 -0600
    45.2 +++ b/tools/python/xen/xend/XendAPI.py	Fri Mar 30 17:18:42 2007 -0600
    45.3 @@ -17,6 +17,8 @@
    45.4  
    45.5  import inspect
    45.6  import os
    45.7 +import Queue
    45.8 +import sets
    45.9  import string
   45.10  import sys
   45.11  import traceback
   45.12 @@ -32,7 +34,9 @@ from xen.xend.XendAuthSessions import in
   45.13  from xen.xend.XendError import *
   45.14  from xen.xend.XendClient import ERROR_INVALID_DOMAIN
   45.15  from xen.xend.XendLogging import log
   45.16 +from xen.xend.XendNetwork import XendNetwork
   45.17  from xen.xend.XendTask import XendTask
   45.18 +from xen.xend.XendPIFMetrics import XendPIFMetrics
   45.19  from xen.xend.XendVMMetrics import XendVMMetrics
   45.20  
   45.21  from xen.xend.XendAPIConstants import *
   45.22 @@ -85,6 +89,91 @@ def now():
   45.23  
   45.24  
   45.25  # ---------------------------------------------------
   45.26 +# Event dispatch
   45.27 +# ---------------------------------------------------
   45.28 +
   45.29 +EVENT_QUEUE_LENGTH = 50
   45.30 +event_registrations = {}
   45.31 +
   45.32 +def event_register(session, reg_classes):
   45.33 +    if session not in event_registrations:
   45.34 +        event_registrations[session] = {
   45.35 +            'classes' : sets.Set(),
   45.36 +            'queue'   : Queue.Queue(EVENT_QUEUE_LENGTH),
   45.37 +            'next-id' : 1
   45.38 +            }
   45.39 +    if not reg_classes:
   45.40 +        reg_classes = classes
   45.41 +    event_registrations[session]['classes'].union_update(reg_classes)
   45.42 +
   45.43 +
   45.44 +def event_unregister(session, unreg_classes):
   45.45 +    if session not in event_registrations:
   45.46 +        return
   45.47 +
   45.48 +    if unreg_classes:
   45.49 +        event_registrations[session]['classes'].intersection_update(
   45.50 +            unreg_classes)
   45.51 +        if len(event_registrations[session]['classes']) == 0:
   45.52 +            del event_registrations[session]
   45.53 +    else:
   45.54 +        del event_registrations[session]
   45.55 +
   45.56 +
   45.57 +def event_next(session):
   45.58 +    if session not in event_registrations:
   45.59 +        return xen_api_error(['SESSION_NOT_REGISTERED', session])
   45.60 +    queue = event_registrations[session]['queue']
   45.61 +    events = [queue.get()]
   45.62 +    try:
   45.63 +        while True:
   45.64 +            events.append(queue.get(False))
   45.65 +    except Queue.Empty:
   45.66 +        pass
   45.67 +
   45.68 +    return xen_api_success(events)
   45.69 +
   45.70 +
   45.71 +def _ctor_event_dispatch(xenapi, ctor, api_cls, session, args):
   45.72 +    result = ctor(xenapi, session, *args)
   45.73 +    if result['Status'] == 'Success':
   45.74 +        ref = result['Value']
   45.75 +        _event_dispatch('add', api_cls, ref, '')
   45.76 +    return result
   45.77 +
   45.78 +
   45.79 +def _dtor_event_dispatch(xenapi, dtor, api_cls, session, ref, args):
   45.80 +    result = dtor(xenapi, session, ref, *args)
   45.81 +    if result['Status'] == 'Success':
   45.82 +        _event_dispatch('del', api_cls, ref, '')
   45.83 +    return result
   45.84 +
   45.85 +
   45.86 +def _setter_event_dispatch(xenapi, setter, api_cls, attr_name, session, ref,
   45.87 +                           args):
   45.88 +    result = setter(xenapi, session, ref, *args)
   45.89 +    if result['Status'] == 'Success':
   45.90 +        _event_dispatch('mod', api_cls, ref, attr_name)
   45.91 +    return result
   45.92 +
   45.93 +
   45.94 +def _event_dispatch(operation, api_cls, ref, attr_name):
   45.95 +    event = {
   45.96 +        'timestamp' : now(),
   45.97 +        'class'     : api_cls,
   45.98 +        'operation' : operation,
   45.99 +        'ref'       : ref,
  45.100 +        'obj_uuid'  : ref,
  45.101 +        'field'     : attr_name,
  45.102 +        }
  45.103 +    for reg in event_registrations.values():
  45.104 +        if api_cls in reg['classes']:
  45.105 +            event['id'] = reg['next-id']
  45.106 +            reg['next-id'] += 1
  45.107 +            reg['queue'].put(event)
  45.108 +
  45.109 +
  45.110 +# ---------------------------------------------------
  45.111  # Python Method Decorators for input value validation
  45.112  # ---------------------------------------------------
  45.113  
  45.114 @@ -373,6 +462,36 @@ def do_vm_func(fn_name, vm_ref, *args, *
  45.115                                exn.actual])
  45.116  
  45.117  
  45.118 +classes = {
  45.119 +    'session'      : None,
  45.120 +    'event'        : None,
  45.121 +    'host'         : valid_host,
  45.122 +    'host_cpu'     : valid_host_cpu,
  45.123 +    'host_metrics' : valid_host_metrics,
  45.124 +    'network'      : valid_network,
  45.125 +    'VM'           : valid_vm,
  45.126 +    'VM_metrics'   : valid_vm_metrics,
  45.127 +    'VBD'          : valid_vbd,
  45.128 +    'VBD_metrics'  : valid_vbd_metrics,
  45.129 +    'VIF'          : valid_vif,
  45.130 +    'VIF_metrics'  : valid_vif_metrics,
  45.131 +    'VDI'          : valid_vdi,
  45.132 +    'VTPM'         : valid_vtpm,
  45.133 +    'console'      : valid_console,
  45.134 +    'SR'           : valid_sr,
  45.135 +    'PIF'          : valid_pif,
  45.136 +    'PIF_metrics'  : valid_pif_metrics,
  45.137 +    'task'         : valid_task,
  45.138 +    'debug'        : valid_debug,
  45.139 +}
  45.140 +
  45.141 +autoplug_classes = {
  45.142 +    'network'     : XendNetwork,
  45.143 +    'VM_metrics'  : XendVMMetrics,
  45.144 +    'PIF_metrics' : XendPIFMetrics,
  45.145 +}
  45.146 +
  45.147 +
  45.148  class XendAPI(object):
  45.149      """Implementation of the Xen-API in Xend. Expects to be
  45.150      used via XMLRPCServer.
  45.151 @@ -414,27 +533,7 @@ class XendAPI(object):
  45.152          server.
  45.153          """
  45.154          global_validators = [session_required, catch_typeerror]
  45.155 -        classes = {
  45.156 -            'session'      : None,
  45.157 -            'host'         : valid_host,
  45.158 -            'host_cpu'     : valid_host_cpu,
  45.159 -            'host_metrics' : valid_host_metrics,
  45.160 -            'network'      : valid_network,
  45.161 -            'VM'           : valid_vm,
  45.162 -            'VM_metrics'   : valid_vm_metrics,
  45.163 -            'VBD'          : valid_vbd,
  45.164 -            'VBD_metrics'  : valid_vbd_metrics,
  45.165 -            'VIF'          : valid_vif,
  45.166 -            'VIF_metrics'  : valid_vif_metrics,
  45.167 -            'VDI'          : valid_vdi,
  45.168 -            'VTPM'         : valid_vtpm,
  45.169 -            'console'      : valid_console,
  45.170 -            'SR'           : valid_sr,
  45.171 -            'PIF'          : valid_pif,
  45.172 -            'PIF_metrics'  : valid_pif_metrics,
  45.173 -            'task'         : valid_task,
  45.174 -            'debug'        : valid_debug,
  45.175 -        }
  45.176 +
  45.177  
  45.178          # Cheat methods
  45.179          # -------------
  45.180 @@ -457,6 +556,77 @@ class XendAPI(object):
  45.181              setattr(cls, get_by_uuid, _get_by_uuid)
  45.182              setattr(cls, get_uuid,    _get_uuid)
  45.183  
  45.184 +
  45.185 +        # Autoplugging classes
  45.186 +        # --------------------
  45.187 +        # These have all of their methods grabbed out from the implementation
  45.188 +        # class, and wrapped up to be compatible with the Xen-API.
  45.189 +        
  45.190 +        for api_cls, impl_cls in autoplug_classes.items():
  45.191 +            def doit(n):
  45.192 +                getter = getattr(cls, '_%s_get' % api_cls)
  45.193 +                dot_n = '%s.%s' % (api_cls, n)
  45.194 +                full_n = '%s_%s' % (api_cls, n)
  45.195 +                if not hasattr(cls, full_n):
  45.196 +                    f = getattr(impl_cls, n)
  45.197 +                    argcounts[dot_n] = f.func_code.co_argcount + 1
  45.198 +                    setattr(cls, full_n,
  45.199 +                            lambda s, session, ref, *args: \
  45.200 +                               xen_api_success( \
  45.201 +                                   f(getter(s, session, ref), *args)))
  45.202 +
  45.203 +            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
  45.204 +            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
  45.205 +            methods  = getattr(cls, '%s_methods' % api_cls, [])
  45.206 +            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
  45.207 +            
  45.208 +            for attr_name in ro_attrs + rw_attrs:
  45.209 +                doit('get_%s' % attr_name)
  45.210 +            for attr_name in rw_attrs + cls.Base_attr_rw:
  45.211 +                doit('set_%s' % attr_name)
  45.212 +            for method_name, return_type in methods + cls.Base_methods:
  45.213 +                doit('%s' % method_name)
  45.214 +            for func_name, return_type in funcs + cls.Base_funcs:
  45.215 +                doit('%s' % func_name)
  45.216 +
  45.217 +
  45.218 +        def wrap_method(name, new_f):
  45.219 +            try:
  45.220 +                f = getattr(cls, name)
  45.221 +                wrapped_f = (lambda *args: new_f(f, *args))
  45.222 +                wrapped_f.api = f.api
  45.223 +                wrapped_f.async = f.async
  45.224 +                setattr(cls, name, wrapped_f)
  45.225 +            except AttributeError:
  45.226 +                # Logged below (API call: %s not found)
  45.227 +                pass
  45.228 +
  45.229 +
  45.230 +        def setter_event_wrapper(api_cls, attr_name):
  45.231 +            setter_name = '%s_set_%s' % (api_cls, attr_name)
  45.232 +            wrap_method(
  45.233 +                setter_name,
  45.234 +                lambda setter, s, session, ref, *args:
  45.235 +                _setter_event_dispatch(s, setter, api_cls, attr_name,
  45.236 +                                       session, ref, args))
  45.237 +
  45.238 +
  45.239 +        def ctor_event_wrapper(api_cls):
  45.240 +            ctor_name = '%s_create' % api_cls
  45.241 +            wrap_method(
  45.242 +                ctor_name,
  45.243 +                lambda ctor, s, session, *args:
  45.244 +                _ctor_event_dispatch(s, ctor, api_cls, session, args))
  45.245 +
  45.246 +
  45.247 +        def dtor_event_wrapper(api_cls):
  45.248 +            dtor_name = '%s_destroy' % api_cls
  45.249 +            wrap_method(
  45.250 +                dtor_name,
  45.251 +                lambda dtor, s, session, ref, *args:
  45.252 +                _dtor_event_dispatch(s, dtor, api_cls, session, ref, args))
  45.253 +
  45.254 +
  45.255          # Wrapping validators around XMLRPC calls
  45.256          # ---------------------------------------
  45.257  
  45.258 @@ -466,7 +636,8 @@ class XendAPI(object):
  45.259                  n_ = n.replace('.', '_')
  45.260                  try:
  45.261                      f = getattr(cls, n_)
  45.262 -                    argcounts[n] = f.func_code.co_argcount - 1
  45.263 +                    if n not in argcounts:
  45.264 +                        argcounts[n] = f.func_code.co_argcount - 1
  45.265                      
  45.266                      validators = takes_instance and validator and \
  45.267                                   [validator] or []
  45.268 @@ -498,6 +669,7 @@ class XendAPI(object):
  45.269              for attr_name in rw_attrs + cls.Base_attr_rw:
  45.270                  doit('%s.set_%s' % (api_cls, attr_name), True,
  45.271                       async_support = False)
  45.272 +                setter_event_wrapper(api_cls, attr_name)
  45.273  
  45.274              # wrap validators around methods
  45.275              for method_name, return_type in methods + cls.Base_methods:
  45.276 @@ -509,6 +681,10 @@ class XendAPI(object):
  45.277                  doit('%s.%s' % (api_cls, func_name), False, async_support = True,
  45.278                       return_type = return_type)
  45.279  
  45.280 +            ctor_event_wrapper(api_cls)
  45.281 +            dtor_event_wrapper(api_cls)
  45.282 +
  45.283 +
  45.284      _decorate = classmethod(_decorate)
  45.285  
  45.286      def __init__(self, auth):
  45.287 @@ -516,7 +692,7 @@ class XendAPI(object):
  45.288  
  45.289      Base_attr_ro = ['uuid']
  45.290      Base_attr_rw = []
  45.291 -    Base_methods = [('destroy', None), ('get_record', 'Struct')]
  45.292 +    Base_methods = [('get_record', 'Struct')]
  45.293      Base_funcs   = [('get_all', 'Set'), ('get_by_uuid', None)]
  45.294  
  45.295      # Xen API: Class Session
  45.296 @@ -916,59 +1092,40 @@ class XendAPI(object):
  45.297  
  45.298      network_attr_ro = ['VIFs', 'PIFs']
  45.299      network_attr_rw = ['name_label',
  45.300 -                       'name_description']
  45.301 -    
  45.302 -    network_funcs = [('create', 'network')]
  45.303 +                       'name_description',
  45.304 +                       'other_config']
  45.305 +    network_methods = [('add_to_other_config', None),
  45.306 +                       ('remove_from_other_config', None),
  45.307 +                       ('destroy', None)]
  45.308 +    network_funcs = [('create', None)]
  45.309      
  45.310 -    def network_create(self, _, name_label, name_description):
  45.311 -        return xen_api_success(
  45.312 -            XendNode.instance().network_create(name_label, name_description))
  45.313 -
  45.314 -    def network_destroy(self, _, ref):
  45.315 -        return xen_api_success(XendNode.instance().network_destroy(ref))
  45.316 -
  45.317 -    def _get_network(self, ref):
  45.318 +    def _network_get(self, _, ref):
  45.319          return XendNode.instance().get_network(ref)
  45.320  
  45.321      def network_get_all(self, _):
  45.322          return xen_api_success(XendNode.instance().get_network_refs())
  45.323  
  45.324 -    def network_get_record(self, _, ref):
  45.325 -        return xen_api_success(
  45.326 -            XendNode.instance().get_network(ref).get_record())
  45.327 -
  45.328 -    def network_get_name_label(self, _, ref):
  45.329 -        return xen_api_success(self._get_network(ref).name_label)
  45.330 -
  45.331 -    def network_get_name_description(self, _, ref):
  45.332 -        return xen_api_success(self._get_network(ref).name_description)
  45.333 -
  45.334 -    def network_get_VIFs(self, _, ref):
  45.335 -        return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
  45.336 -
  45.337 -    def network_get_PIFs(self, session, ref):
  45.338 -        return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
  45.339 -
  45.340 -    def network_set_name_label(self, _, ref, val):
  45.341 -        return xen_api_success(self._get_network(ref).set_name_label(val))
  45.342 -
  45.343 -    def network_set_name_description(self, _, ref, val):
  45.344 -        return xen_api_success(self._get_network(ref).set_name_description(val))
  45.345 +    def network_create(self, _, record):
  45.346 +        return xen_api_success(XendNode.instance().network_create(record))
  45.347 +
  45.348 +    def network_destroy(self, _, ref):
  45.349 +        return xen_api_success(XendNode.instance().network_destroy(ref))
  45.350 +
  45.351  
  45.352      # Xen API: Class PIF
  45.353      # ----------------------------------------------------------------
  45.354  
  45.355 -    PIF_attr_ro = ['metrics']
  45.356 +    PIF_attr_ro = ['network',
  45.357 +                   'host',
  45.358 +                   'metrics']
  45.359      PIF_attr_rw = ['device',
  45.360 -                   'network',
  45.361 -                   'host',
  45.362                     'MAC',
  45.363                     'MTU',
  45.364                     'VLAN']
  45.365  
  45.366      PIF_attr_inst = PIF_attr_rw
  45.367  
  45.368 -    PIF_methods = [('create_VLAN', 'int')]
  45.369 +    PIF_methods = [('create_VLAN', 'int'), ('destroy', None)]
  45.370  
  45.371      def _get_PIF(self, ref):
  45.372          return XendNode.instance().pifs[ref]
  45.373 @@ -1044,26 +1201,14 @@ class XendAPI(object):
  45.374                             'io_write_kbs',
  45.375                             'last_updated']
  45.376      PIF_metrics_attr_rw = []
  45.377 -    PIF_methods = []
  45.378 +    PIF_metrics_methods = []
  45.379  
  45.380      def PIF_metrics_get_all(self, _):
  45.381          return xen_api_success(XendNode.instance().pif_metrics.keys())
  45.382  
  45.383 -    def _PIF_metrics_get(self, ref):
  45.384 +    def _PIF_metrics_get(self, _, ref):
  45.385          return XendNode.instance().pif_metrics[ref]
  45.386  
  45.387 -    def PIF_metrics_get_record(self, _, ref):
  45.388 -        return xen_api_success(self._PIF_metrics_get(ref).get_record())
  45.389 -
  45.390 -    def PIF_metrics_get_io_read_kbs(self, _, ref):
  45.391 -        return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
  45.392 -
  45.393 -    def PIF_metrics_get_io_write_kbs(self, _, ref):
  45.394 -        return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
  45.395 -
  45.396 -    def PIF_metrics_get_last_updated(self, _1, _2):
  45.397 -        return xen_api_success(now())
  45.398 -
  45.399  
  45.400      # Xen API: Class VM
  45.401      # ----------------------------------------------------------------        
  45.402 @@ -1131,7 +1276,8 @@ class XendAPI(object):
  45.403                    ('save', None),
  45.404                    ('set_memory_dynamic_max_live', None),
  45.405                    ('set_memory_dynamic_min_live', None),
  45.406 -                  ('send_trigger', None)]
  45.407 +                  ('send_trigger', None),
  45.408 +                  ('destroy', None)]
  45.409      
  45.410      VM_funcs  = [('create', 'VM'),
  45.411                   ('restore', None),
  45.412 @@ -1390,7 +1536,8 @@ class XendAPI(object):
  45.413              if key.startswith("cpumap"):
  45.414                  vcpu = int(key[6:])
  45.415                  try:
  45.416 -                    xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
  45.417 +                    cpus = map(int, value.split(","))
  45.418 +                    xendom.domain_pincpu(xeninfo.getDomid(), vcpu, cpus)
  45.419                  except Exception, ex:
  45.420                      log.exception(ex)
  45.421  
  45.422 @@ -1633,14 +1780,15 @@ class XendAPI(object):
  45.423  
  45.424      def VM_send_sysrq(self, _, vm_ref, req):
  45.425          xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
  45.426 -        if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
  45.427 +        if xeninfo.state == XEN_API_VM_POWER_STATE_RUNNING \
  45.428 +               or xeninfo.state == XEN_API_VM_POWER_STATE_PAUSED:
  45.429 +            xeninfo.send_sysrq(req)
  45.430 +            return xen_api_success_void()
  45.431 +        else:
  45.432              return xen_api_error(
  45.433                  ['VM_BAD_POWER_STATE', vm_ref,
  45.434                   XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
  45.435                   XendDomain.POWER_STATE_NAMES[xeninfo.state]])
  45.436 -        xeninfo.send_sysrq(req)
  45.437 -        return xen_api_success_void()
  45.438 -
  45.439  
  45.440      def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
  45.441          xendom = XendDomain.instance()
  45.442 @@ -1675,58 +1823,28 @@ class XendAPI(object):
  45.443      VM_metrics_attr_rw = []
  45.444      VM_metrics_methods = []
  45.445  
  45.446 -    def _VM_metrics_get(self, ref):
  45.447 +    def _VM_metrics_get(self, _, ref):
  45.448          return XendVMMetrics.get_by_uuid(ref)
  45.449  
  45.450      def VM_metrics_get_all(self, _):
  45.451          return xen_api_success(XendVMMetrics.get_all())
  45.452  
  45.453 -    def VM_metrics_get_record(self, _, ref):
  45.454 -        return xen_api_success(self._VM_metrics_get(ref).get_record())
  45.455 -
  45.456 -    def VM_metrics_get_memory_actual(self, _, ref):
  45.457 -        return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
  45.458 -
  45.459 -    def VM_metrics_get_VCPUs_number(self, _, ref):
  45.460 -        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
  45.461 -
  45.462 -    def VM_metrics_get_VCPUs_utilisation(self, _, ref):
  45.463 -        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
  45.464 -
  45.465 -    def VM_metrics_get_VCPUs_CPU(self, _, ref):
  45.466 -        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
  45.467 -    
  45.468 -    def VM_metrics_get_VCPUs_flags(self, _, ref):
  45.469 -        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
  45.470 -
  45.471 -    def VM_metrics_get_VCPUs_params(self, _, ref):
  45.472 -        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
  45.473 -
  45.474 -    def VM_metrics_get_start_time(self, _, ref):
  45.475 -        return xen_api_success(self._VM_metrics_get(ref).get_start_time())
  45.476 -
  45.477 -    def VM_metrics_get_state(self, _, ref):
  45.478 -        return xen_api_success(self._VM_metrics_get(ref).get_state())
  45.479 -
  45.480 -    def VM_metrics_get_last_updated(self, _1, _2):
  45.481 -        return xen_api_success(now())
  45.482 -
  45.483  
  45.484      # Xen API: Class VBD
  45.485      # ----------------------------------------------------------------
  45.486  
  45.487 -    VBD_attr_ro = ['metrics',
  45.488 +    VBD_attr_ro = ['VM',
  45.489 +                   'VDI',
  45.490 +                   'metrics',
  45.491                     'runtime_properties']
  45.492 -    VBD_attr_rw = ['VM',
  45.493 -                   'VDI',
  45.494 -                   'device',
  45.495 +    VBD_attr_rw = ['device',
  45.496                     'bootable',
  45.497                     'mode',
  45.498                     'type']
  45.499  
  45.500      VBD_attr_inst = VBD_attr_rw
  45.501  
  45.502 -    VBD_methods = [('media_change', None)]
  45.503 +    VBD_methods = [('media_change', None), ('destroy', None)]
  45.504      VBD_funcs = [('create', 'VBD')]
  45.505      
  45.506      # object methods
  45.507 @@ -1868,7 +1986,10 @@ class XendAPI(object):
  45.508                             'io_write_kbs',
  45.509                             'last_updated']
  45.510      VBD_metrics_attr_rw = []
  45.511 -    VBD_methods = []
  45.512 +    VBD_metrics_methods = []
  45.513 +
  45.514 +    def VBD_metrics_get_all(self, session):
  45.515 +        return self.VBD_get_all(session)
  45.516  
  45.517      def VBD_metrics_get_record(self, _, ref):
  45.518          vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
  45.519 @@ -1893,16 +2014,17 @@ class XendAPI(object):
  45.520      # Xen API: Class VIF
  45.521      # ----------------------------------------------------------------
  45.522  
  45.523 -    VIF_attr_ro = ['metrics',
  45.524 +    VIF_attr_ro = ['network',
  45.525 +                   'VM',
  45.526 +                   'metrics',
  45.527                     'runtime_properties']
  45.528      VIF_attr_rw = ['device',
  45.529 -                   'network',
  45.530 -                   'VM',
  45.531                     'MAC',
  45.532                     'MTU']
  45.533  
  45.534      VIF_attr_inst = VIF_attr_rw
  45.535  
  45.536 +    VIF_methods = [('destroy', None)]
  45.537      VIF_funcs = [('create', 'VIF')]
  45.538  
  45.539                   
  45.540 @@ -1960,10 +2082,10 @@ class XendAPI(object):
  45.541          return xen_api_success(vif_ref)
  45.542  
  45.543      def VIF_get_VM(self, session, vif_ref):
  45.544 -        xendom = XendDomain.instance()        
  45.545 -        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)        
  45.546 +        xendom = XendDomain.instance()
  45.547 +        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
  45.548          return xen_api_success(vm.get_uuid())
  45.549 -    
  45.550 +
  45.551      def VIF_get_MTU(self, session, vif_ref):
  45.552          return self._VIF_get(vif_ref, 'MTU')
  45.553      
  45.554 @@ -2008,7 +2130,10 @@ class XendAPI(object):
  45.555                             'io_write_kbs',
  45.556                             'last_updated']
  45.557      VIF_metrics_attr_rw = []
  45.558 -    VIF_methods = []
  45.559 +    VIF_metrics_methods = []
  45.560 +
  45.561 +    def VIF_metrics_get_all(self, session):
  45.562 +        return self.VIF_get_all(session)
  45.563  
  45.564      def VIF_metrics_get_record(self, _, ref):
  45.565          vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
  45.566 @@ -2044,7 +2169,7 @@ class XendAPI(object):
  45.567                     'other_config']
  45.568      VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
  45.569  
  45.570 -    VDI_methods = [('snapshot', 'VDI')]
  45.571 +    VDI_methods = [('snapshot', 'VDI'), ('destroy', None)]
  45.572      VDI_funcs = [('create', 'VDI'),
  45.573                    ('get_by_name_label', 'Set(VDI)')]
  45.574  
  45.575 @@ -2161,6 +2286,7 @@ class XendAPI(object):
  45.576  
  45.577      VTPM_attr_inst = VTPM_attr_rw
  45.578  
  45.579 +    VTPM_methods = [('destroy', None)]
  45.580      VTPM_funcs = [('create', 'VTPM')]
  45.581      
  45.582      # object methods
  45.583 @@ -2319,7 +2445,7 @@ class XendAPI(object):
  45.584                      'name_label',
  45.585                      'name_description']
  45.586      
  45.587 -    SR_methods = [('clone', 'SR')]
  45.588 +    SR_methods = [('clone', 'SR'), ('destroy', None)]
  45.589      SR_funcs = [('get_by_name_label', 'Set(SR)'),
  45.590                  ('get_by_uuid', 'SR')]
  45.591  
  45.592 @@ -2395,6 +2521,26 @@ class XendAPI(object):
  45.593          return xen_api_success_void()
  45.594  
  45.595  
  45.596 +    # Xen API: Class event
  45.597 +    # ----------------------------------------------------------------
  45.598 +
  45.599 +    event_attr_ro = []
  45.600 +    event_attr_rw = []
  45.601 +    event_funcs = [('register', None),
  45.602 +                   ('unregister', None),
  45.603 +                   ('next', None)]
  45.604 +
  45.605 +    def event_register(self, session, reg_classes):
  45.606 +        event_register(session, reg_classes)
  45.607 +        return xen_api_success_void()
  45.608 +
  45.609 +    def event_unregister(self, session, unreg_classes):
  45.610 +        event_unregister(session, reg_classes)
  45.611 +        return xen_api_success_void()
  45.612 +
  45.613 +    def event_next(self, session):
  45.614 +        return event_next(session)
  45.615 +
  45.616      # Xen API: Class debug
  45.617      # ----------------------------------------------------------------
  45.618  
    46.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Fri Mar 30 10:27:15 2007 -0600
    46.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Fri Mar 30 17:18:42 2007 -0600
    46.3 @@ -192,13 +192,11 @@ def restore(xd, fd, dominfo = None, paus
    46.4      image_cfg = dominfo.info.get('image', {})
    46.5      is_hvm = dominfo.info.is_hvm()
    46.6      if is_hvm:
    46.7 -        hvm  = dominfo.info['memory_static_min']
    46.8          apic = int(dominfo.info['platform'].get('apic', 0))
    46.9          pae  = int(dominfo.info['platform'].get('pae',  0))
   46.10 -        log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d",
   46.11 -                 dominfo.domid, hvm, apic, pae)
   46.12 +        log.info("restore hvm domain %d, apic=%d, pae=%d",
   46.13 +                 dominfo.domid, apic, pae)
   46.14      else:
   46.15 -        hvm  = 0
   46.16          apic = 0
   46.17          pae  = 0
   46.18  
   46.19 @@ -224,7 +222,7 @@ def restore(xd, fd, dominfo = None, paus
   46.20  
   46.21          cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
   46.22                          fd, dominfo.getDomid(), max_pfn,
   46.23 -                        store_port, console_port, hvm, pae, apic])
   46.24 +                        store_port, console_port, int(is_hvm), pae, apic])
   46.25          log.debug("[xc_restore]: %s", string.join(cmd))
   46.26  
   46.27          handler = RestoreInputHandler()
    47.1 --- a/tools/python/xen/xend/XendClient.py	Fri Mar 30 10:27:15 2007 -0600
    47.2 +++ b/tools/python/xen/xend/XendClient.py	Fri Mar 30 17:18:42 2007 -0600
    47.3 @@ -17,7 +17,7 @@
    47.4  # Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
    47.5  #============================================================================
    47.6  
    47.7 -from xen.util.xmlrpclib2 import ServerProxy
    47.8 +from xen.util.xmlrpcclient import ServerProxy
    47.9  import os
   47.10  import sys
   47.11  
    48.1 --- a/tools/python/xen/xend/XendConfig.py	Fri Mar 30 10:27:15 2007 -0600
    48.2 +++ b/tools/python/xen/xend/XendConfig.py	Fri Mar 30 17:18:42 2007 -0600
    48.3 @@ -298,7 +298,7 @@ class XendConfig(dict):
    48.4              'actions_after_reboot': 'restart',
    48.5              'actions_after_crash': 'restart',
    48.6              'actions_after_suspend': '',
    48.7 -            'is_template': False,
    48.8 +            'is_a_template': False,
    48.9              'is_control_domain': False,
   48.10              'features': '',
   48.11              'PV_bootloader': '',
   48.12 @@ -452,7 +452,10 @@ class XendConfig(dict):
   48.13          for key, typ in XENAPI_CFG_TYPES.items():
   48.14              val = sxp.child_value(sxp_cfg, key)
   48.15              if val is not None:
   48.16 -                cfg[key] = typ(val)
   48.17 +                try:
   48.18 +                    cfg[key] = typ(val)
   48.19 +                except (ValueError, TypeError), e:
   48.20 +                    log.warn('Unable to convert type value for key: %s' % key)
   48.21  
   48.22          # Convert deprecated options to current equivalents.
   48.23          
   48.24 @@ -727,7 +730,7 @@ class XendConfig(dict):
   48.25              
   48.26              for key in XENAPI_PLATFORM_CFG:
   48.27                  val = sxp.child_value(image_sxp, key, None)
   48.28 -                if val is not None:
   48.29 +                if val is not None and val != '':
   48.30                      self['platform'][key] = val
   48.31              
   48.32              notes = sxp.children(image_sxp, 'notes')
   48.33 @@ -845,6 +848,8 @@ class XendConfig(dict):
   48.34                      sxpr.append([name, s])
   48.35  
   48.36          for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
   48.37 +            if legacy in ('cpus'): # skip this
   48.38 +                continue
   48.39              if self.has_key(xenapi) and self[xenapi] not in (None, []):
   48.40                  if type(self[xenapi]) == bool:
   48.41                      # convert booleans to ints before making an sxp item
   48.42 @@ -858,7 +863,7 @@ class XendConfig(dict):
   48.43          sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
   48.44  
   48.45          for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
   48.46 -            if legacy in ('domid', 'uuid'): # skip these
   48.47 +            if legacy in ('domid', 'uuid', 'cpus'): # skip these
   48.48                  continue
   48.49              if self.has_key(legacy) and self[legacy] not in (None, []):
   48.50                  sxpr.append([legacy, self[legacy]])
   48.51 @@ -1354,7 +1359,7 @@ class XendConfig(dict):
   48.52  
   48.53          for key in XENAPI_PLATFORM_CFG:
   48.54              val = sxp.child_value(image_sxp, key, None)
   48.55 -            if val is not None:
   48.56 +            if val is not None and val != '':
   48.57                  self['platform'][key] = val
   48.58  
   48.59          notes = sxp.children(image_sxp, 'notes')
    49.1 --- a/tools/python/xen/xend/XendConstants.py	Fri Mar 30 10:27:15 2007 -0600
    49.2 +++ b/tools/python/xen/xend/XendConstants.py	Fri Mar 30 17:18:42 2007 -0600
    49.3 @@ -37,6 +37,13 @@ DOMAIN_SHUTDOWN_REASONS = {
    49.4  REVERSE_DOMAIN_SHUTDOWN_REASONS = \
    49.5      dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()])
    49.6  
    49.7 +HVM_PARAM_CALLBACK_IRQ = 0
    49.8 +HVM_PARAM_STORE_PFN    = 1
    49.9 +HVM_PARAM_STORE_EVTCHN = 2
   49.10 +HVM_PARAM_PAE_ENABLED  = 4
   49.11 +HVM_PARAM_IOREQ_PFN    = 5
   49.12 +HVM_PARAM_BUFIOREQ_PFN = 6
   49.13 +
   49.14  restart_modes = [
   49.15      "restart",
   49.16      "destroy",
    50.1 --- a/tools/python/xen/xend/XendDomain.py	Fri Mar 30 10:27:15 2007 -0600
    50.2 +++ b/tools/python/xen/xend/XendDomain.py	Fri Mar 30 17:18:42 2007 -0600
    50.3 @@ -569,6 +569,26 @@ class XendDomain:
    50.4          finally:
    50.5              self.domains_lock.release()
    50.6  
    50.7 +    def autostart_domains(self):
    50.8 +        """ Autostart managed domains that are marked as such. """
    50.9 +
   50.10 +        need_starting = []
   50.11 +        
   50.12 +        self.domains_lock.acquire()
   50.13 +        try:
   50.14 +            for dom_uuid, dom in self.managed_domains.items():
   50.15 +                if dom and dom.state == DOM_STATE_HALTED:
   50.16 +                    on_xend_start = dom.info.get('on_xend_start', 'ignore')
   50.17 +                    auto_power_on = dom.info.get('auto_power_on', False)
   50.18 +                    should_start = (on_xend_start == 'start') or auto_power_on
   50.19 +                    if should_start:
   50.20 +                        need_starting.append(dom_uuid)
   50.21 +        finally:
   50.22 +            self.domains_lock.release()
   50.23 +
   50.24 +        for dom_uuid in need_starting:
   50.25 +            self.domain_start(dom_uuid, False)
   50.26 +
   50.27      def cleanup_domains(self):
   50.28          """Clean up domains that are marked as autostop.
   50.29          Should be called when Xend goes down. This is currently
    51.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Mar 30 10:27:15 2007 -0600
    51.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Mar 30 17:18:42 2007 -0600
    51.3 @@ -152,8 +152,9 @@ def recreate(info, priv):
    51.4      try:
    51.5          vmpath = xstransact.Read(dompath, "vm")
    51.6          if not vmpath:
    51.7 -            log.warn('/local/domain/%d/vm is missing. recreate is '
    51.8 -                     'confused, trying our best to recover' % domid)
    51.9 +            if not priv:
   51.10 +                log.warn('/local/domain/%d/vm is missing. recreate is '
   51.11 +                         'confused, trying our best to recover' % domid)
   51.12              needs_reinitialising = True
   51.13              raise XendError('reinit')
   51.14          
   51.15 @@ -447,13 +448,13 @@ class XendDomainInfo:
   51.16          self._removeVm('xend/previous_restart_time')
   51.17          self.storeDom("control/shutdown", reason)
   51.18  
   51.19 -        ## shutdown hypercall for hvm domain desides xenstore write
   51.20 +        # HVM domain shuts itself down only if it has PV drivers
   51.21          if self.info.is_hvm():
   51.22 -            for code in DOMAIN_SHUTDOWN_REASONS.keys():
   51.23 -                if DOMAIN_SHUTDOWN_REASONS[code] == reason:
   51.24 -                    break
   51.25 -            xc.domain_shutdown(self.domid, code)
   51.26 -
   51.27 +            hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ)
   51.28 +            if not hvm_pvdrv:
   51.29 +                code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
   51.30 +                log.info("HVM save:remote shutdown dom %d!", self.domid)
   51.31 +                xc.domain_shutdown(self.domid, code)
   51.32  
   51.33      def pause(self):
   51.34          """Pause domain
   51.35 @@ -2354,7 +2355,8 @@ class XendDomainInfo:
   51.36          if not dev_uuid:
   51.37              raise XendError('Failed to create device')
   51.38          
   51.39 -        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
   51.40 +        if self.state == XEN_API_VM_POWER_STATE_RUNNING \
   51.41 +               or self.state == XEN_API_VM_POWER_STATE_PAUSED:
   51.42  
   51.43              _, config = self.info['devices'][dev_uuid]
   51.44              dev_control = self.getDeviceController('vif')
    52.1 --- a/tools/python/xen/xend/XendLogging.py	Fri Mar 30 10:27:15 2007 -0600
    52.2 +++ b/tools/python/xen/xend/XendLogging.py	Fri Mar 30 17:18:42 2007 -0600
    52.3 @@ -62,6 +62,7 @@ if 'TRACE' not in logging.__dict__:
    52.4      # Work around a bug in Python's inspect module: findsource is supposed to
    52.5      # raise IOError if it fails, with other functions in that module coping
    52.6      # with that, but some people are seeing IndexError raised from there.
    52.7 +    # This is Python bug 1628987.  http://python.org/sf/1628987.
    52.8      if hasattr(inspect, 'findsource'):
    52.9          real_findsource = getattr(inspect, 'findsource')
   52.10          def findsource(*args, **kwargs):
    53.1 --- a/tools/python/xen/xend/XendMonitor.py	Fri Mar 30 10:27:15 2007 -0600
    53.2 +++ b/tools/python/xen/xend/XendMonitor.py	Fri Mar 30 17:18:42 2007 -0600
    53.3 @@ -24,8 +24,8 @@ import re
    53.4  """Monitoring thread to keep track of Xend statistics. """
    53.5  
    53.6  VBD_SYSFS_PATH = '/sys/devices/xen-backend/'
    53.7 -VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_req'
    53.8 -VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_req'
    53.9 +VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_sect'
   53.10 +VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_sect'
   53.11  VBD_DOMAIN_RE = r'vbd-(?P<domid>\d+)-(?P<devid>\d+)$'
   53.12  
   53.13  NET_PROCFS_PATH = '/proc/net/dev'
   53.14 @@ -51,14 +51,9 @@ VIF_DOMAIN_RE = re.compile(r'vif(?P<domi
   53.15                             PROC_NET_DEV_RE)
   53.16  PIF_RE = re.compile(r'^\s*(?P<iface>peth\d+):\s*' + PROC_NET_DEV_RE)
   53.17  
   53.18 -# The VBD transfer figures are in "requests" where we don't
   53.19 -# really know how many bytes per requests. For now we make
   53.20 -# up a number roughly could be.
   53.21 -VBD_ROUGH_BYTES_PER_REQUEST = 1024 * 8 * 4
   53.22 -
   53.23  # Interval to poll xc, sysfs and proc
   53.24  POLL_INTERVAL = 2.0
   53.25 -
   53.26 +SECTOR_SIZE = 512
   53.27  class XendMonitor(threading.Thread):
   53.28      """Monitors VCPU, VBD, VIF and PIF statistics for Xen API.
   53.29  
   53.30 @@ -186,9 +181,8 @@ class XendMonitor(threading.Thread):
   53.31                  usage_at = time.time()
   53.32                  rd_stat = int(open(rd_stat_path).readline().strip())
   53.33                  wr_stat = int(open(wr_stat_path).readline().strip())
   53.34 -                rd_stat *= VBD_ROUGH_BYTES_PER_REQUEST
   53.35 -                wr_stat *= VBD_ROUGH_BYTES_PER_REQUEST
   53.36 -                
   53.37 +                rd_stat *= SECTOR_SIZE
   53.38 +                wr_stat *= SECTOR_SIZE
   53.39                  if domid not in stats:
   53.40                      stats[domid] = {}
   53.41  
    54.1 --- a/tools/python/xen/xend/XendNetwork.py	Fri Mar 30 10:27:15 2007 -0600
    54.2 +++ b/tools/python/xen/xend/XendNetwork.py	Fri Mar 30 17:18:42 2007 -0600
    54.3 @@ -28,10 +28,17 @@ from XendLogging import log
    54.4  IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
    54.5  
    54.6  class XendNetwork:
    54.7 -    def __init__(self, uuid, name, description):
    54.8 +    def __init__(self, uuid, record):
    54.9          self.uuid = uuid
   54.10 -        self.name_label = name 
   54.11 -        self.name_description = description
   54.12 +        self.name_label = record.get('name_label', '')
   54.13 +        self.name_description = record.get('name_description', '')
   54.14 +        self.other_config = record.get('other_config', {})
   54.15 +
   54.16 +    def get_name_label(self):
   54.17 +        return self.name_label
   54.18 +
   54.19 +    def get_name_description(self):
   54.20 +        return self.name_description
   54.21  
   54.22      def set_name_label(self, new_name):
   54.23          self.name_label = new_name
   54.24 @@ -41,7 +48,7 @@ class XendNetwork:
   54.25          self.name_description = new_desc
   54.26          XendNode.instance().save_networks()
   54.27  
   54.28 -    def get_VIF_UUIDs(self):
   54.29 +    def get_VIFs(self):
   54.30          result = []
   54.31          vms = XendDomain.instance().get_all_vms()
   54.32          for vm in vms:
   54.33 @@ -52,17 +59,37 @@ class XendNetwork:
   54.34                      result.append(vif)
   54.35          return result
   54.36  
   54.37 -    def get_PIF_UUIDs(self):
   54.38 +    def get_PIFs(self):
   54.39          return [x.uuid for x in XendNode.instance().pifs.values()
   54.40                  if x.network == self]
   54.41  
   54.42 -    def get_record(self, transient = True):
   54.43 +    def get_other_config(self):
   54.44 +        return self.other_config
   54.45 +
   54.46 +    def set_other_config(self, value):
   54.47 +        self.other_config = value
   54.48 +        XendNode.instance().save_networks()
   54.49 +
   54.50 +    def add_to_other_config(self, key, value):
   54.51 +        self.other_config[key] = value
   54.52 +        XendNode.instance().save_networks()
   54.53 +
   54.54 +    def remove_from_other_config(self, key):
   54.55 +        if key in self.other_config:
   54.56 +            del self.other_config[key]
   54.57 +        XendNode.instance().save_networks()
   54.58 +
   54.59 +    def get_record(self):
   54.60 +        return self.get_record_internal(True)
   54.61 +
   54.62 +    def get_record_internal(self, transient):
   54.63          result = {
   54.64              'uuid': self.uuid,
   54.65              'name_label': self.name_label,
   54.66              'name_description': self.name_description,
   54.67 +            'other_config' : self.other_config,
   54.68          }
   54.69          if transient:
   54.70 -            result['VIFs'] = self.get_VIF_UUIDs()
   54.71 -            result['PIFs'] = self.get_PIF_UUIDs()
   54.72 +            result['VIFs'] = self.get_VIFs()
   54.73 +            result['PIFs'] = self.get_PIFs()
   54.74          return result
    55.1 --- a/tools/python/xen/xend/XendNode.py	Fri Mar 30 10:27:15 2007 -0600
    55.2 +++ b/tools/python/xen/xend/XendNode.py	Fri Mar 30 17:18:42 2007 -0600
    55.3 @@ -141,12 +141,16 @@ class XendNode:
    55.4          saved_networks = self.state_store.load_state('network')
    55.5          if saved_networks:
    55.6              for net_uuid, network in saved_networks.items():
    55.7 -                self.network_create(network.get('name_label'),
    55.8 -                                    network.get('name_description', ''),
    55.9 -                                    False, net_uuid)
   55.10 +                self.network_create(network, False, net_uuid)
   55.11          else:
   55.12 -            self.network_create('net0', '', False)
   55.13 +            bridges = Brctl.get_state().keys()
   55.14 +            for bridge in bridges:
   55.15 +                self.network_create({'name_label' : bridge }, False)
   55.16 +                
   55.17 +        # Get a mapping from interface to bridge
   55.18  
   55.19 +        if_to_br = dict(reduce(lambda ls,(b,ifs):[(i,b) for i in ifs] + ls,
   55.20 +                               Brctl.get_state().items(), []))
   55.21          # initialise PIFs
   55.22          saved_pifs = self.state_store.load_state('pif')
   55.23          if saved_pifs:
   55.24 @@ -176,8 +180,14 @@ class XendNode:
   55.25                                    pif_uuid, pif['network'], exn.pif_uuid)
   55.26          else:
   55.27              for name, mtu, mac in linux_get_phy_ifaces():
   55.28 -                network = self.networks.values()[0]
   55.29 -                self._PIF_create(name, mtu, -1, mac, network, False)
   55.30 +                bridge_name = if_to_br.get(name, None)
   55.31 +                if bridge_name is not None:
   55.32 +                    networks = [network for
   55.33 +                                network in self.networks.values()
   55.34 +                                if network.get_name_label() == bridge_name]
   55.35 +                    if len(networks) > 0:
   55.36 +                        network = networks[0]
   55.37 +                        self._PIF_create(name, mtu, -1, mac, network, False)
   55.38  
   55.39          # initialise storage
   55.40          saved_srs = self.state_store.load_state('sr')
   55.41 @@ -199,12 +209,10 @@ class XendNode:
   55.42  
   55.43  
   55.44  
   55.45 -    def network_create(self, name_label, name_description, persist = True,
   55.46 -                       net_uuid = None):
   55.47 +    def network_create(self, record, persist = True, net_uuid = None):
   55.48          if net_uuid is None:
   55.49              net_uuid = uuid.createString()
   55.50 -        self.networks[net_uuid] = XendNetwork(net_uuid, name_label,
   55.51 -                                              name_description)
   55.52 +        self.networks[net_uuid] = XendNetwork(net_uuid, record)
   55.53          if persist:
   55.54              self.save_networks()
   55.55          return net_uuid
   55.56 @@ -280,7 +288,7 @@ class XendNode:
   55.57          self.state_store.save_state('pif', pif_records)
   55.58  
   55.59      def save_networks(self):
   55.60 -        net_records = dict([(k, v.get_record(transient = False))
   55.61 +        net_records = dict([(k, v.get_record_internal(False))
   55.62                              for k, v in self.networks.items()])
   55.63          self.state_store.save_state('network', net_records)
   55.64  
    56.1 --- a/tools/python/xen/xend/XendOptions.py	Fri Mar 30 10:27:15 2007 -0600
    56.2 +++ b/tools/python/xen/xend/XendOptions.py	Fri Mar 30 17:18:42 2007 -0600
    56.3 @@ -165,7 +165,13 @@ class XendOptions:
    56.4  
    56.5      def get_xend_tcp_xmlrpc_server_address(self):
    56.6          return self.get_config_string("xend-tcp-xmlrpc-server-address",
    56.7 -                                    self.xend_tcp_xmlrpc_server_address_default)    
    56.8 +                                      self.xend_tcp_xmlrpc_server_address_default)
    56.9 +
   56.10 +    def get_xend_tcp_xmlrpc_server_ssl_key_file(self):
   56.11 +        return self.get_config_string("xend-tcp-xmlrpc-server-ssl-key-file")
   56.12 +
   56.13 +    def get_xend_tcp_xmlrpc_server_ssl_cert_file(self):
   56.14 +        return self.get_config_string("xend-tcp-xmlrpc-server-ssl-cert-file")
   56.15  
   56.16      def get_xend_unix_xmlrpc_server(self):
   56.17          return self.get_config_bool("xend-unix-xmlrpc-server",
    57.1 --- a/tools/python/xen/xend/XendPIFMetrics.py	Fri Mar 30 10:27:15 2007 -0600
    57.2 +++ b/tools/python/xen/xend/XendPIFMetrics.py	Fri Mar 30 17:18:42 2007 -0600
    57.3 @@ -39,11 +39,13 @@ class XendPIFMetrics:
    57.4              return pifs_util[pifname][n]
    57.5          return 0.0
    57.6  
    57.7 -    def get_record(self):
    57.8 +    def get_last_updated(self):
    57.9          import xen.xend.XendAPI as XendAPI
   57.10 +        return XendAPI.now()
   57.11 +
   57.12 +    def get_record(self):
   57.13          return {'uuid'         : self.uuid,
   57.14 -                'PIF'          : self.pif.uuid,
   57.15                  'io_read_kbs'  : self.get_io_read_kbs(),
   57.16                  'io_write_kbs' : self.get_io_write_kbs(),
   57.17 -                'last_updated' : XendAPI.now(),
   57.18 +                'last_updated' : self.get_last_updated(),
   57.19                  }
    58.1 --- a/tools/python/xen/xend/XendStateStore.py	Fri Mar 30 10:27:15 2007 -0600
    58.2 +++ b/tools/python/xen/xend/XendStateStore.py	Fri Mar 30 17:18:42 2007 -0600
    58.3 @@ -126,6 +126,13 @@ class XendStateStore:
    58.4                      if val_name not in cls_dict:
    58.5                          cls_dict[val_name] = {}
    58.6                      cls_dict[val_name][val_uuid] = None
    58.7 +                elif val_type == '':
    58.8 +                    # dictionary
    58.9 +                    k = val_elem.getAttribute('key').encode('utf8')
   58.10 +                    v = val_elem.getAttribute('value').encode('utf8')
   58.11 +                    if val_name not in cls_dict:
   58.12 +                        cls_dict[val_name] = {}
   58.13 +                    cls_dict[val_name][k] = v
   58.14                  elif val_type == 'string':
   58.15                      cls_dict[val_name] = val_text.encode('utf8')
   58.16                  elif val_type == 'float':
   58.17 @@ -197,7 +204,11 @@ class XendStateStore:
   58.18                  if type(val) == dict:
   58.19                      for val_uuid in val.keys():
   58.20                          val_node = doc.createElement(key)
   58.21 -                        val_node.setAttribute('uuid', val_uuid)
   58.22 +                        if key == 'other_config':
   58.23 +                            val_node.setAttribute('key', str(val_uuid))
   58.24 +                            val_node.setAttribute('value', str(val[val_uuid]))
   58.25 +                        else:
   58.26 +                            val_node.setAttribute('uuid', val_uuid)
   58.27                          node.appendChild(val_node)
   58.28                  elif type(val) in (list, tuple):
   58.29                      for val_uuid in val:
    59.1 --- a/tools/python/xen/xend/XendVMMetrics.py	Fri Mar 30 10:27:15 2007 -0600
    59.2 +++ b/tools/python/xen/xend/XendVMMetrics.py	Fri Mar 30 17:18:42 2007 -0600
    59.3 @@ -92,7 +92,7 @@ class XendVMMetrics:
    59.4                  set_flag('blocked')
    59.5                  set_flag('online')
    59.6                  set_flag('running')
    59.7 -                vcpus_flags[i] = ",".join(flags)
    59.8 +                vcpus_flags[i] = flags
    59.9              return vcpus_flags
   59.10          else:
   59.11              return {}
   59.12 @@ -115,7 +115,7 @@ class XendVMMetrics:
   59.13                  addState("dying")
   59.14                  addState("crashed")
   59.15                  addState("shutdown")
   59.16 -                return ",".join(states)
   59.17 +                return states
   59.18          except Exception, err:
   59.19              # ignore missing domain
   59.20              log.trace("domain_getinfo(%d) failed, ignoring: %s", domid, str(err))
   59.21 @@ -140,8 +140,11 @@ class XendVMMetrics:
   59.22      def get_start_time(self):
   59.23          return self.xend_domain_instance.info.get("start_time", -1)
   59.24      
   59.25 +    def get_last_updated(self):
   59.26 +        import xen.xend.XendAPI as XendAPI
   59.27 +        return XendAPI.now()
   59.28 +    
   59.29      def get_record(self):
   59.30 -        import xen.xend.XendAPI as XendAPI
   59.31          return { 'uuid'              : self.uuid,
   59.32                   'memory_actual'     : self.get_memory_actual(),
   59.33                   'VCPUs_number'      : self.get_VCPUs_number(),
   59.34 @@ -151,5 +154,5 @@ class XendVMMetrics:
   59.35                   'VCPUs_params'      : self.get_VCPUs_params(),
   59.36                   'start_time'        : self.get_start_time(),
   59.37                   'state'             : self.get_state(),
   59.38 -                 'last_updated'      : XendAPI.now(),
   59.39 +                 'last_updated'      : self.get_last_updated(),
   59.40                 }
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/tools/python/xen/xend/server/SSLXMLRPCServer.py	Fri Mar 30 17:18:42 2007 -0600
    60.3 @@ -0,0 +1,103 @@
    60.4 +#============================================================================
    60.5 +# This library is free software; you can redistribute it and/or
    60.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    60.7 +# License as published by the Free Software Foundation.
    60.8 +#
    60.9 +# This library is distributed in the hope that it will be useful,
   60.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   60.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   60.12 +# Lesser General Public License for more details.
   60.13 +#
   60.14 +# You should have received a copy of the GNU Lesser General Public
   60.15 +# License along with this library; if not, write to the Free Software
   60.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   60.17 +#============================================================================
   60.18 +# Copyright (C) 2007 XenSource Inc.
   60.19 +#============================================================================
   60.20 +
   60.21 +
   60.22 +"""
   60.23 +HTTPS wrapper for an XML-RPC server interface.  Requires PyOpenSSL (Debian
   60.24 +package python-pyopenssl).
   60.25 +"""
   60.26 +
   60.27 +import socket
   60.28 +
   60.29 +from OpenSSL import SSL
   60.30 +
   60.31 +from xen.util.xmlrpclib2 import XMLRPCRequestHandler, TCPXMLRPCServer
   60.32 +
   60.33 +
   60.34 +class SSLXMLRPCRequestHandler(XMLRPCRequestHandler):
   60.35 +    def setup(self):
   60.36 +        self.connection = self.request
   60.37 +        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
   60.38 +        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
   60.39 +
   60.40 +#
   60.41 +# Taken from pyOpenSSL-0.6 examples (public-domain)
   60.42 +#
   60.43 +
   60.44 +class SSLWrapper:
   60.45 +    """
   60.46 +    """
   60.47 +    def __init__(self, conn):
   60.48 +        """
   60.49 +        Connection is not yet a new-style class,
   60.50 +        so I'm making a proxy instead of subclassing.
   60.51 +        """
   60.52 +        self.__dict__["conn"] = conn
   60.53 +    def __getattr__(self, name):
   60.54 +        return getattr(self.__dict__["conn"], name)
   60.55 +    def __setattr__(self, name, value):
   60.56 +        setattr(self.__dict__["conn"], name, value)
   60.57 +
   60.58 +    def close(self):
   60.59 +        self.shutdown()
   60.60 +        return self.__dict__["conn"].close()
   60.61 +
   60.62 +    def shutdown(self, how=1):
   60.63 +        """
   60.64 +        SimpleXMLRpcServer.doPOST calls shutdown(1),
   60.65 +        and Connection.shutdown() doesn't take
   60.66 +        an argument. So we just discard the argument.
   60.67 +        """
   60.68 +        # Block until the shutdown is complete
   60.69 +        self.__dict__["conn"].shutdown()
   60.70 +        self.__dict__["conn"].shutdown()
   60.71 +
   60.72 +    def accept(self):
   60.73 +        """
   60.74 +        This is the other part of the shutdown() workaround.
   60.75 +        Since servers create new sockets, we have to infect
   60.76 +        them with our magic. :)
   60.77 +        """
   60.78 +        c, a = self.__dict__["conn"].accept()
   60.79 +        return (SSLWrapper(c), a)
   60.80 +
   60.81 +#
   60.82 +# End of pyOpenSSL-0.6 example code.
   60.83 +#
   60.84 +
   60.85 +class SSLXMLRPCServer(TCPXMLRPCServer):
   60.86 +    def __init__(self, addr, allowed, xenapi, logRequests = 1,
   60.87 +                 ssl_key_file = None, ssl_cert_file = None):
   60.88 +
   60.89 +        TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
   60.90 +                                 SSLXMLRPCRequestHandler, logRequests)
   60.91 +
   60.92 +        if not ssl_key_file or not ssl_cert_file:
   60.93 +            raise ValueError("SSLXMLRPCServer requires ssl_key_file "
   60.94 +                             "and ssl_cert_file to be set.")
   60.95 +
   60.96 +        # make a SSL socket
   60.97 +        ctx = SSL.Context(SSL.SSLv23_METHOD)
   60.98 +        ctx.set_options(SSL.OP_NO_SSLv2)
   60.99 +        ctx.use_privatekey_file (ssl_key_file)
  60.100 +        ctx.use_certificate_file(ssl_cert_file)
  60.101 +        self.socket = SSLWrapper(SSL.Connection(ctx,
  60.102 +                                 socket.socket(self.address_family,
  60.103 +                                               self.socket_type)))
  60.104 +        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  60.105 +        self.server_bind()
  60.106 +        self.server_activate()
    61.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Fri Mar 30 10:27:15 2007 -0600
    61.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Fri Mar 30 17:18:42 2007 -0600
    61.3 @@ -38,7 +38,8 @@ class Daemon:
    61.4          self.traceon = False
    61.5          self.tracefile = None
    61.6          self.traceindent = 0
    61.7 -        self.child = 0 
    61.8 +        self.child = 0
    61.9 +        self.traceLock = threading.Lock()
   61.10  
   61.11  
   61.12      def cleanup_xend(self, kill):
   61.13 @@ -253,6 +254,7 @@ class Daemon:
   61.14                  pass
   61.15  
   61.16      def print_trace(self, string):
   61.17 +        self.tracefile.write("%s: "% threading.currentThread().getName())
   61.18          for i in range(self.traceindent):
   61.19              ch = " "
   61.20              if (i % 5):
   61.21 @@ -263,50 +265,54 @@ class Daemon:
   61.22          self.tracefile.write(string)
   61.23              
   61.24      def trace(self, frame, event, arg):
   61.25 -        if not self.traceon:
   61.26 -            print >>self.tracefile
   61.27 -            print >>self.tracefile, '-' * 20, 'TRACE OFF', '-' * 20
   61.28 -            self.tracefile.close()
   61.29 -            self.tracefile = None
   61.30 -            return None
   61.31 -        if event == 'call':
   61.32 -            code = frame.f_code
   61.33 -            filename = code.co_filename
   61.34 -            m = re.search('.*xend/(.*)', filename)
   61.35 -            if not m:
   61.36 -                return None
   61.37 -            modulename = m.group(1)
   61.38 -            if modulename.endswith('.pyc'):
   61.39 -                modulename = modulename[:-1]
   61.40 -            if modulename == 'sxp.py' or \
   61.41 -               modulename == 'XendLogging.py' or \
   61.42 -               modulename == 'XendMonitor.py' or \
   61.43 -               modulename == 'server/SrvServer.py':
   61.44 +        self.traceLock.acquire()
   61.45 +        try:
   61.46 +            if not self.traceon:
   61.47 +                print >>self.tracefile
   61.48 +                print >>self.tracefile, '-' * 20, 'TRACE OFF', '-' * 20
   61.49 +                self.tracefile.close()
   61.50 +                self.tracefile = None
   61.51                  return None
   61.52 -            self.traceindent += 1
   61.53 -            self.print_trace("> %s:%s\n"
   61.54 -                             % (modulename, code.co_name))
   61.55 -        elif event == 'line':
   61.56 -            filename = frame.f_code.co_filename
   61.57 -            lineno = frame.f_lineno
   61.58 -            self.print_trace("%4d %s" %
   61.59 -                             (lineno, linecache.getline(filename, lineno)))
   61.60 -        elif event == 'return':
   61.61 -            code = frame.f_code
   61.62 -            filename = code.co_filename
   61.63 -            m = re.search('.*xend/(.*)', filename)
   61.64 -            if not m:
   61.65 -                return None
   61.66 -            modulename = m.group(1)
   61.67 -            self.print_trace("< %s:%s\n"
   61.68 -                             % (modulename, code.co_name))
   61.69 -            self.traceindent -= 1
   61.70 -        elif event == 'exception':
   61.71 -            self.print_trace("! Exception:\n")
   61.72 -            (ex, val, tb) = arg
   61.73 -            traceback.print_exception(ex, val, tb, 10, self.tracefile)
   61.74 -            #del tb
   61.75 -        return self.trace
   61.76 +            if event == 'call':
   61.77 +                code = frame.f_code
   61.78 +                filename = code.co_filename
   61.79 +                m = re.search('.*xend/(.*)', filename)
   61.80 +                if not m:
   61.81 +                    return None
   61.82 +                modulename = m.group(1)
   61.83 +                if modulename.endswith('.pyc'):
   61.84 +                    modulename = modulename[:-1]
   61.85 +                if modulename == 'sxp.py' or \
   61.86 +                   modulename == 'XendLogging.py' or \
   61.87 +                   modulename == 'XendMonitor.py' or \
   61.88 +                   modulename == 'server/SrvServer.py':
   61.89 +                    return None
   61.90 +                self.traceindent += 1
   61.91 +                self.print_trace("> %s:%s\n"
   61.92 +                                 % (modulename, code.co_name))
   61.93 +            elif event == 'line':
   61.94 +                filename = frame.f_code.co_filename
   61.95 +                lineno = frame.f_lineno
   61.96 +                self.print_trace("%4d %s" %
   61.97 +                                 (lineno, linecache.getline(filename, lineno)))
   61.98 +            elif event == 'return':
   61.99 +                code = frame.f_code
  61.100 +                filename = code.co_filename
  61.101 +                m = re.search('.*xend/(.*)', filename)
  61.102 +                if not m:
  61.103 +                    return None
  61.104 +                modulename = m.group(1)
  61.105 +                self.print_trace("< %s:%s\n"
  61.106 +                                 % (modulename, code.co_name))
  61.107 +                self.traceindent -= 1
  61.108 +            elif event == 'exception':
  61.109 +                self.print_trace("! Exception:\n")
  61.110 +                (ex, val, tb) = arg
  61.111 +                traceback.print_exception(ex, val, tb, 10, self.tracefile)
  61.112 +                #del tb
  61.113 +            return self.trace
  61.114 +        finally:
  61.115 +            self.traceLock.release()
  61.116  
  61.117      def set_user(self):
  61.118          # Set the UID.
    62.1 --- a/tools/python/xen/xend/server/SrvServer.py	Fri Mar 30 10:27:15 2007 -0600
    62.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Fri Mar 30 17:18:42 2007 -0600
    62.3 @@ -52,6 +52,7 @@ from xen.xend import XendNode, XendOptio
    62.4  from xen.xend import Vifctl
    62.5  from xen.xend.XendLogging import log
    62.6  from xen.xend.XendClient import XEN_API_SOCKET
    62.7 +from xen.xend.XendDomain import instance as xenddomain
    62.8  from xen.web.SrvDir import SrvDir
    62.9  
   62.10  from SrvRoot import SrvRoot
   62.11 @@ -72,7 +73,7 @@ class XendServers:
   62.12      def add(self, server):
   62.13          self.servers.append(server)
   62.14  
   62.15 -    def cleanup(self, signum = 0, frame = None):
   62.16 +    def cleanup(self, signum = 0, frame = None, reloading = False):
   62.17          log.debug("SrvServer.cleanup()")
   62.18          self.cleaningUp = True
   62.19          for server in self.servers:
   62.20 @@ -80,12 +81,18 @@ class XendServers:
   62.21                  server.shutdown()
   62.22              except:
   62.23                  pass
   62.24 +
   62.25 +        # clean up domains for those that have on_xend_stop
   62.26 +        if not reloading:
   62.27 +            xenddomain().cleanup_domains()
   62.28 +        
   62.29          self.running = False
   62.30 +        
   62.31  
   62.32      def reloadConfig(self, signum = 0, frame = None):
   62.33          log.debug("SrvServer.reloadConfig()")
   62.34          self.reloadingConfig = True
   62.35 -        self.cleanup(signum, frame)
   62.36 +        self.cleanup(signum, frame, reloading = True)
   62.37  
   62.38      def start(self, status):
   62.39          # Running the network script will spawn another process, which takes
   62.40 @@ -144,6 +151,12 @@ class XendServers:
   62.41                  status.close()
   62.42                  status = None
   62.43  
   62.44 +            # Reaching this point means we can auto start domains
   62.45 +            try:
   62.46 +                xenddomain().autostart_domains()
   62.47 +            except Exception, e:
   62.48 +                log.exception("Failed while autostarting domains")
   62.49 +
   62.50              # loop to keep main thread alive until it receives a SIGTERM
   62.51              self.running = True
   62.52              while self.running:
   62.53 @@ -172,33 +185,49 @@ def _loadConfig(servers, root, reload):
   62.54      api_cfg = xoptions.get_xen_api_server()
   62.55      if api_cfg:
   62.56          try:
   62.57 -            addrs = [(str(x[0]).split(':'),
   62.58 -                      len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
   62.59 -                      len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
   62.60 -                      or None)
   62.61 -                     for x in api_cfg]
   62.62 -            for addrport, auth, allowed in addrs:
   62.63 -                if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
   62.64 -                    log.error('Xen-API server configuration %s is invalid, ' +
   62.65 -                              'as %s is not a valid authentication type.',
   62.66 -                              api_cfg, auth)
   62.67 -                    break
   62.68 +            for server_cfg in api_cfg:
   62.69 +                # Parse the xen-api-server config
   62.70 +                
   62.71 +                ssl_key_file = None
   62.72 +                ssl_cert_file = None
   62.73 +                auth_method = XendAPI.AUTH_NONE
   62.74 +                hosts_allowed = None
   62.75 +                
   62.76 +                host_addr = server_cfg[0].split(':', 1)
   62.77 +                if len(host_addr) == 1:
   62.78 +                    if host_addr[0].lower() == 'unix':
   62.79 +                        use_tcp = False
   62.80 +                        host = 'localhost'
   62.81 +                        port = 0
   62.82 +                    else:
   62.83 +                        use_tcp = True
   62.84 +                        host = ''
   62.85 +                        port = int(host_addr[0])
   62.86 +                else:
   62.87 +                    use_tcp = True
   62.88 +                    host = str(host_addr[0])
   62.89 +                    port = int(host_addr[1])
   62.90  
   62.91 -                if len(addrport) == 1:
   62.92 -                    if addrport[0] == 'unix':
   62.93 -                        servers.add(XMLRPCServer(auth, True,
   62.94 -                                                 path = XEN_API_SOCKET,
   62.95 -                                                 hosts_allowed = allowed))
   62.96 -                    else:
   62.97 -                        servers.add(
   62.98 -                            XMLRPCServer(auth, True, True, '',
   62.99 -                                         int(addrport[0]),
  62.100 -                                         hosts_allowed = allowed))
  62.101 -                else:
  62.102 -                    addr, port = addrport
  62.103 -                    servers.add(XMLRPCServer(auth, True, True, addr,
  62.104 -                                             int(port),
  62.105 -                                             hosts_allowed = allowed))
  62.106 +                if len(server_cfg) > 1:
  62.107 +                    if server_cfg[1] in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
  62.108 +                        auth_method = server_cfg[1]
  62.109 +
  62.110 +                if len(server_cfg) > 2:
  62.111 +                    hosts_allowed = server_cfg[2] or None
  62.112 +
  62.113 +                if len(server_cfg) > 4:
  62.114 +                    # SSL key and cert file
  62.115 +                    ssl_key_file = server_cfg[3]
  62.116 +                    ssl_cert_file = server_cfg[4]
  62.117 +
  62.118 +
  62.119 +                servers.add(XMLRPCServer(auth_method, True, use_tcp = use_tcp,
  62.120 +                                         ssl_key_file = ssl_key_file,
  62.121 +                                         ssl_cert_file = ssl_cert_file,
  62.122 +                                         host = host, port = port,
  62.123 +                                         path = XEN_API_SOCKET,
  62.124 +                                         hosts_allowed = hosts_allowed))
  62.125 +
  62.126          except (ValueError, TypeError), exn:
  62.127              log.exception('Xen API Server init failed')
  62.128              log.error('Xen-API server configuration %s is invalid.', api_cfg)
  62.129 @@ -206,8 +235,17 @@ def _loadConfig(servers, root, reload):
  62.130      if xoptions.get_xend_tcp_xmlrpc_server():
  62.131          addr = xoptions.get_xend_tcp_xmlrpc_server_address()
  62.132          port = xoptions.get_xend_tcp_xmlrpc_server_port()
  62.133 -        servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
  62.134 -                                 host = addr, port = port))
  62.135 +        ssl_key_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_key_file()
  62.136 +        ssl_cert_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_cert_file()
  62.137 +
  62.138 +        if ssl_key_file and ssl_cert_file:
  62.139 +            servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
  62.140 +                                     ssl_key_file = ssl_key_file,
  62.141 +                                     ssl_cert_file = ssl_cert_file,
  62.142 +                                     host = addr, port = port))
  62.143 +        else:
  62.144 +            servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
  62.145 +                                     host = addr, port = port))
  62.146  
  62.147      if xoptions.get_xend_unix_xmlrpc_server():
  62.148          servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
    63.1 --- a/tools/python/xen/xend/server/XMLRPCServer.py	Fri Mar 30 10:27:15 2007 -0600
    63.2 +++ b/tools/python/xen/xend/server/XMLRPCServer.py	Fri Mar 30 17:18:42 2007 -0600
    63.3 @@ -21,6 +21,11 @@ import socket
    63.4  import types
    63.5  import xmlrpclib
    63.6  from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
    63.7 +try:
    63.8 +    from SSLXMLRPCServer import SSLXMLRPCServer
    63.9 +    ssl_enabled = True
   63.10 +except ImportError:
   63.11 +    ssl_enabled = False
   63.12  
   63.13  from xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNode
   63.14  from xen.xend import XendLogging, XendDmesg
   63.15 @@ -87,14 +92,20 @@ methods = ['device_create', 'device_conf
   63.16  exclude = ['domain_create', 'domain_restore']
   63.17  
   63.18  class XMLRPCServer:
   63.19 -    def __init__(self, auth, use_xenapi, use_tcp=False, host = "localhost",
   63.20 -                 port = 8006, path = XML_RPC_SOCKET, hosts_allowed = None):
   63.21 +    def __init__(self, auth, use_xenapi, use_tcp = False,
   63.22 +                 ssl_key_file = None, ssl_cert_file = None,
   63.23 +                 host = "localhost", port = 8006, path = XML_RPC_SOCKET,
   63.24 +                 hosts_allowed = None):
   63.25 +        
   63.26          self.use_tcp = use_tcp
   63.27          self.port = port
   63.28          self.host = host
   63.29          self.path = path
   63.30          self.hosts_allowed = hosts_allowed
   63.31          
   63.32 +        self.ssl_key_file = ssl_key_file
   63.33 +        self.ssl_cert_file = ssl_cert_file
   63.34 +        
   63.35          self.ready = False        
   63.36          self.running = True
   63.37          self.auth = auth
   63.38 @@ -107,14 +118,32 @@ class XMLRPCServer:
   63.39  
   63.40          try:
   63.41              if self.use_tcp:
   63.42 -                log.info("Opening TCP XML-RPC server on %s%d%s",
   63.43 +                using_ssl = self.ssl_key_file and self.ssl_cert_file
   63.44 +
   63.45 +                log.info("Opening %s XML-RPC server on %s%d%s",
   63.46 +                         using_ssl and 'HTTPS' or 'TCP',
   63.47                           self.host and '%s:' % self.host or
   63.48                           'all interfaces, port ',
   63.49                           self.port, authmsg)
   63.50 -                self.server = TCPXMLRPCServer((self.host, self.port),
   63.51 -                                              self.hosts_allowed,
   63.52 -                                              self.xenapi is not None,
   63.53 -                                              logRequests = False)
   63.54 +
   63.55 +                if using_ssl:
   63.56 +                    if not ssl_enabled:
   63.57 +                        raise ValueError("pyOpenSSL not installed. "
   63.58 +                                         "Unable to start HTTPS XML-RPC server")
   63.59 +                    self.server = SSLXMLRPCServer(
   63.60 +                        (self.host, self.port),
   63.61 +                        self.hosts_allowed,
   63.62 +                        self.xenapi is not None,
   63.63 +                        logRequests = False,
   63.64 +                        ssl_key_file = self.ssl_key_file,
   63.65 +                        ssl_cert_file = self.ssl_cert_file)
   63.66 +                else:
   63.67 +                    self.server = TCPXMLRPCServer(
   63.68 +                        (self.host, self.port),
   63.69 +                        self.hosts_allowed,
   63.70 +                        self.xenapi is not None,
   63.71 +                        logRequests = False)
   63.72 +
   63.73              else:
   63.74                  log.info("Opening Unix domain socket XML-RPC server on %s%s",
   63.75                           self.path, authmsg)
   63.76 @@ -126,7 +155,12 @@ class XMLRPCServer:
   63.77              ready = True
   63.78              running = False
   63.79              return
   63.80 -
   63.81 +        except Exception, e:
   63.82 +            log.exception('Cannot start server: %s!', e)
   63.83 +            ready = True
   63.84 +            running = False
   63.85 +            return
   63.86 +        
   63.87          # Register Xen API Functions
   63.88          # -------------------------------------------------------------------
   63.89          # exportable functions are ones that do not begin with '_'
    64.1 --- a/tools/python/xen/xm/XenAPI.py	Fri Mar 30 10:27:15 2007 -0600
    64.2 +++ b/tools/python/xen/xm/XenAPI.py	Fri Mar 30 17:18:42 2007 -0600
    64.3 @@ -12,7 +12,7 @@
    64.4  # License along with this library; if not, write to the Free Software
    64.5  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    64.6  #============================================================================
    64.7 -# Copyright (C) 2006 XenSource Inc.
    64.8 +# Copyright (C) 2006-2007 XenSource Inc.
    64.9  #============================================================================
   64.10  #
   64.11  # Parts of this file are based upon xmlrpclib.py, the XML-RPC client
   64.12 @@ -47,7 +47,7 @@
   64.13  import gettext
   64.14  import xmlrpclib
   64.15  
   64.16 -import xen.util.xmlrpclib2
   64.17 +import xen.util.xmlrpcclient as xmlrpcclient
   64.18  
   64.19  
   64.20  translation = gettext.translation('xen-xm', fallback = True)
   64.21 @@ -85,7 +85,7 @@ class Failure(Exception):
   64.22  _RECONNECT_AND_RETRY = (lambda _ : ())
   64.23  
   64.24  
   64.25 -class Session(xen.util.xmlrpclib2.ServerProxy):
   64.26 +class Session(xmlrpcclient.ServerProxy):
   64.27      """A server proxy and session manager for communicating with Xend using
   64.28      the Xen-API.
   64.29  
   64.30 @@ -104,14 +104,16 @@ class Session(xen.util.xmlrpclib2.Server
   64.31  
   64.32      def __init__(self, uri, transport=None, encoding=None, verbose=0,
   64.33                   allow_none=1):
   64.34 -        xen.util.xmlrpclib2.ServerProxy.__init__(self, uri, transport,
   64.35 -                                                 encoding, verbose,
   64.36 -                                                 allow_none)
   64.37 +        xmlrpcclient.ServerProxy.__init__(self, uri, transport, encoding,
   64.38 +                                          verbose, allow_none)
   64.39          self._session = None
   64.40          self.last_login_method = None
   64.41          self.last_login_params = None
   64.42  
   64.43  
   64.44 +    def getSession(self):
   64.45 +        return self._session
   64.46 +
   64.47      def xenapi_request(self, methodname, params):
   64.48          if methodname.startswith('login'):
   64.49              self._login(methodname, params)
   64.50 @@ -150,7 +152,7 @@ class Session(xen.util.xmlrpclib2.Server
   64.51          elif name.startswith('login'):
   64.52              return lambda *params: self._login(name, params)
   64.53          else:
   64.54 -            return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
   64.55 +            return xmlrpcclient.ServerProxy.__getattr__(self, name)
   64.56  
   64.57  
   64.58  def _parse_result(result):
    65.1 --- a/tools/python/xen/xm/create.dtd	Fri Mar 30 10:27:15 2007 -0600
    65.2 +++ b/tools/python/xen/xm/create.dtd	Fri Mar 30 17:18:42 2007 -0600
    65.3 @@ -37,6 +37,8 @@
    65.4                   memory,
    65.5                   vbd*,
    65.6                   vif*,
    65.7 +                 console*,
    65.8 +                 platform*,
    65.9                   vcpu_param*,
   65.10                   other_config*)> 
   65.11  <!ATTLIST vm     is_a_template          CDATA #REQUIRED
   65.12 @@ -46,11 +48,6 @@
   65.13                   actions_after_shutdown %NORMAL_EXIT; #REQUIRED 
   65.14                   actions_after_reboot   %NORMAL_EXIT; #REQUIRED
   65.15                   actions_after_crash    %CRASH_BEHAVIOUR; #REQUIRED
   65.16 -                 platform_std_VGA       CDATA #REQUIRED
   65.17 -                 platform_serial        CDATA #REQUIRED
   65.18 -                 platform_localtime     CDATA #REQUIRED 
   65.19 -                 platform_clock_offet   CDATA #REQUIRED
   65.20 -                 platform_enable_audio  CDATA #REQUIRED
   65.21                   PCI_bus                CDATA #REQUIRED> 
   65.22  
   65.23  <!ELEMENT memory EMPTY> 
   65.24 @@ -74,9 +71,11 @@
   65.25                   mtu             CDATA       #REQUIRED
   65.26                   device          CDATA       #REQUIRED
   65.27                   qos_algorithm_type CDATA    #REQUIRED
   65.28 -                 bridge          CDATA       #IMPLIED
   65.29                   network         CDATA       #IMPLIED> 
   65.30  
   65.31 +<!ELEMENT console (other_config*)>
   65.32 +<!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
   65.33 +
   65.34  <!ELEMENT pv     EMPTY>
   65.35  <!ATTLIST pv     kernel          CDATA #REQUIRED
   65.36                   bootloader      CDATA #REQUIRED
   65.37 @@ -105,13 +104,17 @@
   65.38  <!ELEMENT label  (#PCDATA)> 
   65.39  <!ELEMENT description (#PCDATA)>
   65.40  
   65.41 +<!ELEMENT platform   EMPTY>
   65.42 +<!ATTLIST platform   key   CDATA #REQUIRED
   65.43 +                     value CDATA #REQUIRED>
   65.44 +
   65.45  <!ELEMENT vcpu_param EMPTY>
   65.46  <!ATTLIST vcpu_param key   CDATA #REQUIRED
   65.47                       value CDATA #REQUIRED>
   65.48  
   65.49  <!ELEMENT other_config EMPTY>
   65.50  <!ATTLIST other_config key   CDATA #REQUIRED
   65.51 -                      value CDATA #REQUIRED>
   65.52 +                       value CDATA #REQUIRED>
   65.53  
   65.54  <!ELEMENT qos_algorithm_param EMPTY>
   65.55  <!ATTLIST qos_algorithm_param key   CDATA #REQUIRED
    66.1 --- a/tools/python/xen/xm/create.py	Fri Mar 30 10:27:15 2007 -0600
    66.2 +++ b/tools/python/xen/xm/create.py	Fri Mar 30 17:18:42 2007 -0600
    66.3 @@ -104,6 +104,11 @@ gopts.opt('xmldryrun', short='x',
    66.4            use="XML dry run - prints the resulting configuration in XML but "
    66.5            "does not create the domain.")
    66.6  
    66.7 +gopts.opt('skipdtd', short='s',
    66.8 +          fn=set_true, default=0,
    66.9 +          use="Skip DTD checking - skips checks on XML before creating. "
   66.10 +          " Experimental.  Can decrease create time." )
   66.11 +
   66.12  gopts.opt('paused', short='p',
   66.13            fn=set_true, default=0,
   66.14            use='Leave the domain paused after it is created.')
   66.15 @@ -1098,6 +1103,8 @@ def parseCommandLine(argv):
   66.16      if not gopts.vals.xauthority:
   66.17          gopts.vals.xauthority = get_xauthority()
   66.18  
   66.19 +    gopts.is_xml = False
   66.20 +
   66.21      # Process remaining args as config variables.
   66.22      for arg in args:
   66.23          if '=' in arg:
   66.24 @@ -1106,11 +1113,16 @@ def parseCommandLine(argv):
   66.25      if gopts.vals.config:
   66.26          config = gopts.vals.config
   66.27      else:
   66.28 -        gopts.load_defconfig()
   66.29 -        preprocess(gopts.vals)
   66.30 -        if not gopts.getopt('name') and gopts.getopt('defconfig'):
   66.31 -            gopts.setopt('name', os.path.basename(gopts.getopt('defconfig')))
   66.32 -        config = make_config(gopts.vals)
   66.33 +        try:
   66.34 +            gopts.load_defconfig()
   66.35 +            preprocess(gopts.vals)
   66.36 +            if not gopts.getopt('name') and gopts.getopt('defconfig'):
   66.37 +                gopts.setopt('name', os.path.basename(gopts.getopt('defconfig')))
   66.38 +            config = make_config(gopts.vals)
   66.39 +        except XMLFileError, ex:
   66.40 +            XMLFile = ex.getFile()
   66.41 +            gopts.is_xml = True
   66.42 +            config = ex.getFile()
   66.43  
   66.44      return (gopts, config)
   66.45  
   66.46 @@ -1233,6 +1245,8 @@ def help():
   66.47      return str(gopts)
   66.48  
   66.49  def main(argv):
   66.50 +    is_xml = False
   66.51 +    
   66.52      try:
   66.53          (opts, config) = parseCommandLine(argv)
   66.54      except StandardError, ex:
   66.55 @@ -1241,23 +1255,24 @@ def main(argv):
   66.56      if not opts:
   66.57          return
   66.58  
   66.59 -    if type(config) == str:
   66.60 -        try:
   66.61 -            config = sxp.parse(file(config))[0]
   66.62 -        except IOError, exn:
   66.63 -            raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
   66.64 +    if not opts.is_xml:
   66.65 +        if type(config) == str:
   66.66 +            try:
   66.67 +                config = sxp.parse(file(config))[0]
   66.68 +            except IOError, exn:
   66.69 +                raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
   66.70 +        
   66.71 +        if serverType == SERVER_XEN_API:
   66.72 +            from xen.xm.xenapi_create import sxp2xml
   66.73 +            sxp2xml_inst = sxp2xml()
   66.74 +            doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
   66.75  
   66.76 -    if serverType == SERVER_XEN_API:
   66.77 -        from xen.xm.xenapi_create import sxp2xml
   66.78 -        sxp2xml_inst = sxp2xml()
   66.79 -        doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
   66.80 +        if opts.vals.dryrun and not opts.is_xml:
   66.81 +            SXPPrettyPrint.prettyprint(config)
   66.82  
   66.83 -    if opts.vals.dryrun:
   66.84 -        SXPPrettyPrint.prettyprint(config)
   66.85 -
   66.86 -    if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
   66.87 -        from xml.dom.ext import PrettyPrint as XMLPrettyPrint
   66.88 -        XMLPrettyPrint(doc)
   66.89 +        if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
   66.90 +            from xml.dom.ext import PrettyPrint as XMLPrettyPrint
   66.91 +            XMLPrettyPrint(doc)
   66.92  
   66.93      if opts.vals.dryrun or opts.vals.xmldryrun:
   66.94          return                                               
   66.95 @@ -1268,10 +1283,15 @@ def main(argv):
   66.96      if serverType == SERVER_XEN_API:        
   66.97          from xen.xm.xenapi_create import xenapi_create
   66.98          xenapi_create_inst = xenapi_create()
   66.99 -        vm_refs = xenapi_create_inst.create(document = doc)
  66.100 +        if opts.is_xml:
  66.101 +            vm_refs = xenapi_create_inst.create(filename = config,
  66.102 +                                                skipdtd = opts.vals.skipdtd)
  66.103 +        else:
  66.104 +            vm_refs = xenapi_create_inst.create(document = doc,
  66.105 +                                                skipdtd = opts.vals.skipdtd)
  66.106  
  66.107          map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
  66.108 -    else:
  66.109 +    elif not opts.is_xml:
  66.110          if not create_security_check(config):
  66.111              raise security.ACMError(
  66.112                  'Security Configuration prevents domain from starting')
    67.1 --- a/tools/python/xen/xm/main.py	Fri Mar 30 10:27:15 2007 -0600
    67.2 +++ b/tools/python/xen/xm/main.py	Fri Mar 30 17:18:42 2007 -0600
    67.3 @@ -49,7 +49,7 @@ from xen.xend.XendConstants import *
    67.4  
    67.5  from xen.xm.opts import OptionError, Opts, wrap, set_true
    67.6  from xen.xm import console
    67.7 -from xen.util.xmlrpclib2 import ServerProxy
    67.8 +from xen.util.xmlrpcclient import ServerProxy
    67.9  
   67.10  import XenAPI
   67.11  
   67.12 @@ -345,7 +345,8 @@ acm_commands = [
   67.13      ]
   67.14  
   67.15  all_commands = (domain_commands + host_commands + scheduler_commands +
   67.16 -                device_commands + vnet_commands + acm_commands + ['shell'])
   67.17 +                device_commands + vnet_commands + acm_commands +
   67.18 +                ['shell', 'event-monitor'])
   67.19  
   67.20  
   67.21  ##
   67.22 @@ -559,11 +560,21 @@ def err(msg):
   67.23  def get_single_vm(dom):
   67.24      if serverType == SERVER_XEN_API:
   67.25          uuids = server.xenapi.VM.get_by_name_label(dom)
   67.26 -        n = len(uuids)
   67.27 -        if n > 0:
   67.28 +        if len(uuids) > 0:
   67.29              return uuids[0]
   67.30 -        else:
   67.31 -            raise OptionError("Domain '%s' not found." % dom)
   67.32 +
   67.33 +        try:
   67.34 +            domid = int(dom)
   67.35 +            uuids = [server.xenapi.VM.get_domid(vm_ref)
   67.36 +                     for vm_ref in server.xenapi.VM.get_all()
   67.37 +                     if int(server.xenapi.VM.get_domid(vm_ref)) == domid]
   67.38 +        except:
   67.39 +            pass
   67.40 +            
   67.41 +        if len(uuids) > 0:
   67.42 +            return uuids[0]
   67.43 +
   67.44 +        raise OptionError("Domain '%s' not found." % dom)
   67.45      else:
   67.46          dominfo = server.xend.domain(dom, False)
   67.47          return dominfo['uuid']
   67.48 @@ -633,6 +644,17 @@ def xm_shell(args):
   67.49      Shell().cmdloop('The Xen Master. Type "help" for a list of functions.')
   67.50  
   67.51  
   67.52 +def xm_event_monitor(args):
   67.53 +    if serverType == SERVER_XEN_API:
   67.54 +        while True:
   67.55 +            server.xenapi.event.register(args)
   67.56 +            events = server.xenapi.event.next()
   67.57 +            for e in events:
   67.58 +                print e
   67.59 +    else:
   67.60 +        err("Event monitoring not supported unless using Xen-API.")
   67.61 +
   67.62 +
   67.63  #########################################################################
   67.64  #
   67.65  #  Main xm functions
   67.66 @@ -722,7 +744,7 @@ def getDomains(domain_names, state, full
   67.67              states = ('running', 'blocked', 'paused', 'shutdown',
   67.68                        'crashed', 'dying')
   67.69              def state_on_off(state):
   67.70 -                if dom_metrics['state'].find(state) > -1:
   67.71 +                if state in dom_metrics['state']:
   67.72                      return state[0]
   67.73                  else:
   67.74                      return "-"
   67.75 @@ -850,7 +872,8 @@ def parse_doms_info(info):
   67.76  
   67.77  def check_sched_type(sched):
   67.78      if serverType == SERVER_XEN_API:
   67.79 -        current = server.xenapi.host.get_sched_policy(server.xenapi.session.get_this_host())
   67.80 +        current = server.xenapi.host.get_sched_policy(
   67.81 +            server.xenapi.session.get_this_host(server.getSession()))
   67.82      else:
   67.83          current = 'unknown'
   67.84          for x in server.xend.node.info()[1:]:
   67.85 @@ -952,12 +975,10 @@ def xm_vcpu_list(args):
   67.86                      ['name',       vm_records[vm_ref]['name_label']],
   67.87                      ['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
   67.88  
   67.89 -            
   67.90 -
   67.91              for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
   67.92                  def chk_flag(flag):
   67.93 -                    return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
   67.94 -                           .find(flag) > -1 and 1 or 0
   67.95 +                    return flag in vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
   67.96 +                           and 1 or 0
   67.97                  
   67.98                  vcpu_info = ['vcpu',
   67.99                               ['number',
  67.100 @@ -1044,7 +1065,7 @@ def xm_vcpu_list(args):
  67.101  
  67.102              if serverType == SERVER_XEN_API:
  67.103                  nr_cpus = len(server.xenapi.host.get_host_CPUs(
  67.104 -                    server.xenapi.session.get_this_host()))
  67.105 +                    server.xenapi.session.get_this_host(server.getSession())))
  67.106              else:
  67.107                  for x in server.xend.node.info()[1:]:
  67.108                      if len(x) > 1 and x[0] == 'nr_cpus':
  67.109 @@ -1260,8 +1281,9 @@ def xm_vcpu_pin(args):
  67.110          cpumap = cpu_make_map(args[2])
  67.111  
  67.112      if serverType == SERVER_XEN_API:
  67.113 +        cpumap = map(str, cpumap)        
  67.114          server.xenapi.VM.add_to_VCPUs_params_live(
  67.115 -            get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
  67.116 +            get_single_vm(dom), "cpumap%i" % int(vcpu), ",".join(cpumap))
  67.117      else:
  67.118          server.xend.domain.pincpu(dom, vcpu, cpumap)
  67.119  
  67.120 @@ -1509,7 +1531,7 @@ def xm_info(args):
  67.121          # Need to fake out old style xm info as people rely on parsing it
  67.122          
  67.123          host_record = server.xenapi.host.get_record(
  67.124 -            server.xenapi.session.get_this_host())        
  67.125 +            server.xenapi.session.get_this_host(server.getSession()))
  67.126  
  67.127          host_cpu_records = map(server.xenapi.host_cpu.get_record, host_record["host_CPUs"])
  67.128  
  67.129 @@ -1686,7 +1708,7 @@ def xm_debug_keys(args):
  67.130      
  67.131      if serverType == SERVER_XEN_API:
  67.132          server.xenapi.host.send_debug_keys(
  67.133 -            server.xenapi.session.get_this_host(),
  67.134 +            server.xenapi.session.get_this_host(server.getSession()),
  67.135              keys)
  67.136      else:
  67.137          server.xend.node.send_debug_keys(keys)
  67.138 @@ -1715,7 +1737,7 @@ def xm_dmesg(args):
  67.139          usage('dmesg')
  67.140  
  67.141      if serverType == SERVER_XEN_API:
  67.142 -        host = server.xenapi.session.get_this_host()
  67.143 +        host = server.xenapi.session.get_this_host(server.getSession())
  67.144          if use_clear:
  67.145              print server.xenapi.host.dmesg_clear(host),
  67.146          else:
  67.147 @@ -1731,7 +1753,7 @@ def xm_log(args):
  67.148  
  67.149      if serverType == SERVER_XEN_API:
  67.150          print server.xenapi.host.get_log(
  67.151 -            server.xenapi.session.get_this_host())
  67.152 +            server.xenapi.session.get_this_host(server.getSession()))
  67.153      else:
  67.154          print server.xend.node.log()
  67.155  
  67.156 @@ -2169,6 +2191,7 @@ def xm_vnet_delete(args):
  67.157  
  67.158  commands = {
  67.159      "shell": xm_shell,
  67.160 +    "event-monitor": xm_event_monitor,
  67.161      # console commands
  67.162      "console": xm_console,
  67.163      # xenstat commands
  67.164 @@ -2371,11 +2394,10 @@ def _run_cmd(cmd, cmd_name, args):
  67.165             if isinstance(e, security.ACMError):
  67.166                 err(str(e))
  67.167                 return False, 1
  67.168 -        else:
  67.169 -            print "Unexpected error:", sys.exc_info()[0]
  67.170 -            print
  67.171 -            print "Please report to xen-devel@lists.xensource.com"
  67.172 -            raise
  67.173 +        print "Unexpected error:", sys.exc_info()[0]
  67.174 +        print
  67.175 +        print "Please report to xen-devel@lists.xensource.com"
  67.176 +        raise
  67.177  
  67.178      return False, 1
  67.179  
    68.1 --- a/tools/python/xen/xm/messages/en/xen-xm.po	Fri Mar 30 10:27:15 2007 -0600
    68.2 +++ b/tools/python/xen/xm/messages/en/xen-xm.po	Fri Mar 30 17:18:42 2007 -0600
    68.3 @@ -19,7 +19,7 @@
    68.4  msgid ""
    68.5  msgstr ""
    68.6  "Project-Id-Version: Xen-xm 3.0\n"
    68.7 -"PO-Revision-Date: 2007-03-10 23:17+0000\n"
    68.8 +"PO-Revision-Date: 2007-03-29 16:13+0100\n"
    68.9  "Last-Translator: Ewan Mellor <ewan@xensource.com>\n"
   68.10  "Language-Team: xen-devel <xen-devel@lists.xensource.com>\n"
   68.11  "MIME-Version: 1.0\n"
   68.12 @@ -64,3 +64,6 @@ msgstr "The VM must be %(2)s to perform 
   68.13  
   68.14  msgid "VM_HVM_REQUIRED"
   68.15  msgstr "HVM guest support is unavailable: is VT/AMD-V supported by your CPU and enabled in your BIOS?"
   68.16 +
   68.17 +msgid "SESSION_NOT_REGISTERED"
   68.18 +msgstr "This session is not registered to receive events.  You must call event.register before event.next.  (Session handle is %(1)s.)"
    69.1 --- a/tools/python/xen/xm/opts.py	Fri Mar 30 10:27:15 2007 -0600
    69.2 +++ b/tools/python/xen/xm/opts.py	Fri Mar 30 17:18:42 2007 -0600
    69.3 @@ -24,6 +24,8 @@ import os.path
    69.4  import sys
    69.5  import types
    69.6  
    69.7 +
    69.8 +
    69.9  def _line_wrap(text, width = 70):
   69.10      lines = []
   69.11      current_line = ''
   69.12 @@ -60,6 +62,15 @@ class OptionError(Exception):
   69.13      def __str__(self):
   69.14          return self.message
   69.15  
   69.16 +class XMLFileError(Exception):
   69.17 +    """Thrown is input is an XML File"""
   69.18 +    def __init__(self, XMLFile):
   69.19 +        self.XMLFile = XMLFile
   69.20 +    def __str__(self):
   69.21 +        return "XMLFileError: %s" % self.XMLFile
   69.22 +    def getFile(self):
   69.23 +        return self.XMLFile
   69.24 +
   69.25  class Opt:
   69.26      """An individual option.
   69.27      """
   69.28 @@ -492,6 +503,14 @@ class Opts:
   69.29                  p = os.path.join(os.path.curdir, p)
   69.30              if os.path.exists(p):
   69.31                  self.info('Using config file "%s".' % p)
   69.32 +
   69.33 +                f = open(p)
   69.34 +                is_xml = (f.read(1) == '<')
   69.35 +                f.close()
   69.36 +
   69.37 +                if is_xml:
   69.38 +                    raise XMLFileError(p)
   69.39 +
   69.40                  self.load(p, help)
   69.41                  break
   69.42          else:
    70.1 --- a/tools/python/xen/xm/xenapi_create.py	Fri Mar 30 10:27:15 2007 -0600
    70.2 +++ b/tools/python/xen/xm/xenapi_create.py	Fri Mar 30 17:18:42 2007 -0600
    70.3 @@ -25,7 +25,7 @@ from xml.parsers.xmlproc import xmlproc,
    70.4  from xen.xend import sxp
    70.5  from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
    70.6       XEN_API_ON_CRASH_BEHAVIOUR
    70.7 -
    70.8 +from xen.xm.opts import OptionError
    70.9  
   70.10  import sys
   70.11  import os
   70.12 @@ -75,15 +75,20 @@ class xenapi_create:
   70.13  
   70.14          self.dtd = "/usr/lib/python/xen/xm/create.dtd"
   70.15  
   70.16 -    def create(self, filename=None, document=None):
   70.17 +    def create(self, filename=None, document=None, skipdtd=False):
   70.18          """
   70.19          Create a domain from an XML file or DOM tree
   70.20          """
   70.21 +        if skipdtd:
   70.22 +            print "Skipping DTD checks.  Dangerous!"
   70.23 +        
   70.24          if filename is not None:
   70.25 -            self.check_dtd(file)
   70.26 -            document = parse(file)
   70.27 +            if not skipdtd:
   70.28 +                self.check_dtd(filename)
   70.29 +            document = parse(filename)
   70.30          elif document is not None:
   70.31 -            self.check_dom_against_dtd(document)
   70.32 +            if not skipdtd:
   70.33 +                self.check_dom_against_dtd(document)
   70.34  
   70.35          self.check_doc(document)
   70.36  
   70.37 @@ -179,15 +184,7 @@ class xenapi_create:
   70.38          map(self.check_vif, vifs)
   70.39  
   70.40      def check_vif(self, vif):
   70.41 -        """
   70.42 -        Check that the vif has
   70.43 -        either a bridge or network
   70.44 -        name but not both
   70.45 -        """
   70.46 -        if "bridge" in vif.attributes.keys() \
   70.47 -               and "network" in vif.attributes.keys():
   70.48 -            raise "You cannot specify both a bridge and\
   70.49 -                   a network name."
   70.50 +        pass
   70.51  
   70.52      # Cleanup methods here
   70.53      def cleanup_vdis(self, vdi_refs_dict):
   70.54 @@ -265,18 +262,8 @@ class xenapi_create:
   70.55                  vm.attributes["actions_after_reboot"].value,
   70.56              "actions_after_crash":
   70.57                  vm.attributes["actions_after_crash"].value,
   70.58 -            "platform_std_VGA":
   70.59 -                vm.attributes["platform_std_VGA"].value,
   70.60 -            "platform_serial":
   70.61 -                vm.attributes["platform_serial"].value,
   70.62 -            "platform_localtime":
   70.63 -                vm.attributes["platform_localtime"].value,
   70.64 -            "platform_clock_offet":
   70.65 -                vm.attributes["platform_clock_offet"].value,
   70.66 -            "platform_enable_audio":
   70.67 -                vm.attributes["platform_enable_audio"].value,
   70.68 -            "PCI_bus":
   70.69 -                vm.attributes["platform_enable_audio"].value,
   70.70 +            "platform":
   70.71 +                get_child_nodes_as_dict(vm, "platform", "key", "value"),
   70.72              "other_config":
   70.73                  get_child_nodes_as_dict(vm, "other_config", "key", "value")
   70.74              }
   70.75 @@ -300,7 +287,7 @@ class xenapi_create:
   70.76                  "HVM_boot_policy":
   70.77                      get_child_node_attribute(vm, "hvm", "boot_policy"),
   70.78                  "HVM_boot_params":
   70.79 -                    get_child_nodes_as_dict(hvm, "boot_params", "key", "value")
   70.80 +                    get_child_nodes_as_dict(hvm, "boot_param", "key", "value")
   70.81                  })
   70.82          try:
   70.83              vm_ref = server.xenapi.VM.create(vm_record)
   70.84 @@ -308,19 +295,29 @@ class xenapi_create:
   70.85              traceback.print_exc()
   70.86              sys.exit(-1)
   70.87  
   70.88 -        # Now create vbds
   70.89 +        try:
   70.90 +            # Now create vbds
   70.91 +
   70.92 +            vbds = vm.getElementsByTagName("vbd")
   70.93  
   70.94 -        vbds = vm.getElementsByTagName("vbd")
   70.95 +            self.create_vbds(vm_ref, vbds, vdis)
   70.96  
   70.97 -        self.create_vbds(vm_ref, vbds, vdis)
   70.98 +            # Now create vifs
   70.99 +
  70.100 +            vifs = vm.getElementsByTagName("vif")
  70.101  
  70.102 -        # Now create vifs
  70.103 +            self.create_vifs(vm_ref, vifs)
  70.104  
  70.105 -        vifs = vm.getElementsByTagName("vif")
  70.106 +            # Now create consoles
  70.107 +
  70.108 +            consoles = vm.getElementsByTagName("console")
  70.109  
  70.110 -        self.create_vifs(vm_ref, vifs)
  70.111 +            self.create_consoles(vm_ref, consoles)
  70.112  
  70.113 -        return vm_ref
  70.114 +            return vm_ref
  70.115 +        except:
  70.116 +            server.xenapi.VM.destroy(vm_ref)
  70.117 +            raise
  70.118          
  70.119      def create_vbds(self, vm_ref, vbds, vdis):
  70.120          log(DEBUG, "create_vbds")
  70.121 @@ -358,13 +355,16 @@ class xenapi_create:
  70.122      def create_vif(self, vm_ref, vif):
  70.123          log(DEBUG, "create_vif")
  70.124  
  70.125 -        if "bridge" in vif.attributes.keys():
  70.126 -            raise "Not allowed to add by bridge just yet"
  70.127 -        elif "network" in vif.attributes.keys():
  70.128 -            network = [network_ref
  70.129 +        if "network" in vif.attributes.keys():
  70.130 +            networks = [network_ref
  70.131                  for network_ref in server.xenapi.network.get_all()
  70.132                  if server.xenapi.network.get_name_label(network_ref)
  70.133 -                       == vif.attributes["network"].value][0]
  70.134 +                       == vif.attributes["network"].value]
  70.135 +            if len(networks) > 0:
  70.136 +                network = networks[0]
  70.137 +            else:
  70.138 +                raise OptionError("Network %s doesn't exist"
  70.139 +                                  % vif.attributes["network"].value)
  70.140          else:
  70.141              network = self._get_network_ref()
  70.142  
  70.143 @@ -397,6 +397,26 @@ class xenapi_create:
  70.144              self._network_refs = server.xenapi.network.get_all()
  70.145              return self._network_refs.pop(0)
  70.146  
  70.147 +    def create_consoles(self, vm_ref, consoles):
  70.148 +        log(DEBUG, "create_consoles")
  70.149 +        return map(lambda console: self.create_console(vm_ref, console),
  70.150 +                   consoles)
  70.151 +
  70.152 +    def create_console(self, vm_ref, console):
  70.153 +        log(DEBUG, "create_consoles")
  70.154 +
  70.155 +        console_record = {
  70.156 +            "VM":
  70.157 +                vm_ref,
  70.158 +            "protocol":
  70.159 +                console.attributes["protocol"].value,
  70.160 +            "other_params":
  70.161 +                get_child_nodes_as_dict(console,
  70.162 +                  "other_param", "key", "value")
  70.163 +            }
  70.164 +
  70.165 +        return server.xenapi.console.create(console_record)
  70.166 +
  70.167  def get_child_by_name(exp, childname, default = None):
  70.168      try:
  70.169          return [child for child in sxp.children(exp)
  70.170 @@ -460,11 +480,6 @@ class sxp2xml:
  70.171              = actions_after_reboot
  70.172          vm.attributes["actions_after_crash"] \
  70.173              = actions_after_crash
  70.174 -        vm.attributes["platform_std_VGA"] = "false"
  70.175 -        vm.attributes["platform_serial"] = ""
  70.176 -        vm.attributes["platform_localtime"] = ""
  70.177 -        vm.attributes["platform_clock_offet"] = ""
  70.178 -        vm.attributes["platform_enable_audio"] = ""
  70.179          vm.attributes["PCI_bus"] = ""
  70.180  
  70.181          vm.attributes["vcpus_max"] \
  70.182 @@ -502,7 +517,13 @@ class sxp2xml:
  70.183              vm.appendChild(pv)
  70.184          elif image[0] == "hvm":
  70.185              hvm = document.createElement("hvm")
  70.186 -            hvm.attributes["boot_policy"] = ""
  70.187 +            hvm.attributes["boot_policy"] = "BIOS order"
  70.188 +
  70.189 +            boot_order = document.createElement("boot_param")
  70.190 +            boot_order.attributes["key"] = "order"
  70.191 +            boot_order.attributes["value"] \
  70.192 +                = get_child_by_name(image, "boot", "abcd")
  70.193 +            hvm.appendChild
  70.194  
  70.195              vm.appendChild(hvm)
  70.196  
  70.197 @@ -536,6 +557,18 @@ class sxp2xml:
  70.198  
  70.199          map(vm.appendChild, vifs)
  70.200  
  70.201 +        # Last but not least the consoles...
  70.202 +
  70.203 +        consoles = self.extract_consoles(image, document)
  70.204 +
  70.205 +        map(vm.appendChild, consoles)
  70.206 +
  70.207 +        # Platform variables...
  70.208 +
  70.209 +        platform = self.extract_platform(image, document)
  70.210 +
  70.211 +        map(vm.appendChild, platform)
  70.212 +
  70.213          # transient?
  70.214  
  70.215          if transient:
  70.216 @@ -626,13 +659,69 @@ class sxp2xml:
  70.217          vif.attributes["qos_algorithm_type"] = ""
  70.218  
  70.219          if get_child_by_name(vif_sxp, "bridge") is not None:
  70.220 -            vif.attributes["bridge"] \
  70.221 +            vif.attributes["network"] \
  70.222                  = get_child_by_name(vif_sxp, "bridge")
  70.223          
  70.224          return vif
  70.225  
  70.226      _eths = -1
  70.227  
  70.228 +    def mk_other_config(self, key, value, document):
  70.229 +        other_config = document.createElement("other_config")
  70.230 +        other_config.attributes["key"] = key
  70.231 +        other_config.attributes["value"] = value
  70.232 +        return other_config
  70.233 +
  70.234 +    def extract_consoles(self, image, document):
  70.235 +        consoles = []
  70.236 +
  70.237 +        if int(get_child_by_name(image, "nographic", "1")) == 1:
  70.238 +            return consoles
  70.239 +        
  70.240 +        if int(get_child_by_name(image, "vnc", "0")) == 1:
  70.241 +            console = document.createElement("console")
  70.242 +            console.attributes["protocol"] = "rfb"
  70.243 +            console.appendChild(self.mk_other_config(
  70.244 +                "vncunused", str(get_child_by_name(image, "vncunused", "0")),
  70.245 +                document))
  70.246 +            console.appendChild(self.mk_other_config(
  70.247 +                "vnclisten",
  70.248 +                get_child_by_name(image, "vnclisten", "127.0.0.1"),
  70.249 +                document))
  70.250 +            console.appendChild(self.mk_other_config(
  70.251 +                "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
  70.252 +                document))
  70.253 +            consoles.append(console)          
  70.254 +        if int(get_child_by_name(image, "sdl", "0")) == 1:
  70.255 +            console = document.createElement("console")
  70.256 +            console.attributes["protocol"] = "sdl"
  70.257 +            console.appendChild(self.mk_other_config(
  70.258 +                "display", get_child_by_name(image, "display", ""),
  70.259 +                document))
  70.260 +            console.appendChild(self.mk_other_config(
  70.261 +                "xauthority",
  70.262 +                get_child_by_name(image, "vxauthority", "127.0.0.1"),
  70.263 +                document))
  70.264 +            console.appendChild(self.mk_other_config(
  70.265 +                "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
  70.266 +                document))
  70.267 +            consoles.append(console)
  70.268 +            
  70.269 +        return consoles
  70.270 +
  70.271 +
  70.272 +    def extract_platform(self, image, document):
  70.273 +        platform_keys = ['acpi', 'apic', 'pae']
  70.274 +
  70.275 +        def extract_platform_key(key):
  70.276 +            platform = document.createElement("platform")
  70.277 +            platform.attributes["key"] = key
  70.278 +            platform.attributes["value"] \
  70.279 +                = str(get_child_by_name(image, key, "1"))
  70.280 +            return platform
  70.281 +        
  70.282 +        return map(extract_platform_key, platform_keys)
  70.283 +    
  70.284      def getFreshEthDevice(self):
  70.285          self._eths += 1
  70.286          return "eth%i" % self._eths
    71.1 --- a/tools/security/policies/security_policy.xsd	Fri Mar 30 10:27:15 2007 -0600
    71.2 +++ b/tools/security/policies/security_policy.xsd	Fri Mar 30 17:18:42 2007 -0600
    71.3 @@ -22,6 +22,8 @@
    71.4  				<xsd:element name="Reference" type="xsd:string" minOccurs="0" maxOccurs="1" />
    71.5  				<xsd:element name="Date" minOccurs="0" maxOccurs="1" type="xsd:string"></xsd:element>
    71.6  				<xsd:element name="NameSpaceUrl" minOccurs="0" maxOccurs="1" type="xsd:string"></xsd:element>
    71.7 +				<xsd:element name="Version" minOccurs="0" maxOccurs="1" type="VersionFormat"/>
    71.8 +				<xsd:element ref="FromPolicy" minOccurs="0" maxOccurs="1"/>
    71.9  			</xsd:sequence>
   71.10  		</xsd:complexType>
   71.11  	</xsd:element>
   71.12 @@ -116,4 +118,17 @@
   71.13  			<xsd:enumeration value="PrimaryPolicyComponent"></xsd:enumeration>
   71.14  		</xsd:restriction>
   71.15  	</xsd:simpleType>
   71.16 +	<xsd:element name="FromPolicy">
   71.17 +		<xsd:complexType>
   71.18 +			<xsd:sequence>
   71.19 +				<xsd:element name="PolicyName" minOccurs="1" maxOccurs="1" type="xsd:string"/>
   71.20 +				<xsd:element name="Version" minOccurs="1" maxOccurs="1" type="VersionFormat"/>
   71.21 +			</xsd:sequence>
   71.22 +		</xsd:complexType>
   71.23 +	</xsd:element>
   71.24 +	<xsd:simpleType name="VersionFormat">
   71.25 +		<xsd:restriction base="xsd:string">
   71.26 +			<xsd:pattern value="[0-9]{1,8}.[0-9]{1,8}"></xsd:pattern>
   71.27 +		</xsd:restriction>
   71.28 +	</xsd:simpleType>
   71.29  </xsd:schema>
    72.1 --- a/tools/security/secpol_tool.c	Fri Mar 30 10:27:15 2007 -0600
    72.2 +++ b/tools/security/secpol_tool.c	Fri Mar 30 17:18:42 2007 -0600
    72.3 @@ -57,7 +57,7 @@ void usage(char *progname)
    72.4  
    72.5  /*************************** DUMPS *******************************/
    72.6  
    72.7 -void acm_dump_chinesewall_buffer(void *buf, int buflen)
    72.8 +void acm_dump_chinesewall_buffer(void *buf, int buflen, uint16_t chwall_ref)
    72.9  {
   72.10  
   72.11      struct acm_chwall_policy_buffer *cwbuf =
   72.12 @@ -91,6 +91,8 @@ void acm_dump_chinesewall_buffer(void *b
   72.13          for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
   72.14              printf("%02x ",
   72.15                     ntohs(ssids[i * ntohl(cwbuf->chwall_max_types) + j]));
   72.16 +        if (i == chwall_ref)
   72.17 +            printf(" <-- Domain-0");
   72.18      }
   72.19      printf("\n\nConfict Sets:\n");
   72.20      conflicts =
   72.21 @@ -131,7 +133,7 @@ void acm_dump_chinesewall_buffer(void *b
   72.22      }
   72.23  }
   72.24  
   72.25 -void acm_dump_ste_buffer(void *buf, int buflen)
   72.26 +void acm_dump_ste_buffer(void *buf, int buflen, uint16_t ste_ref)
   72.27  {
   72.28  
   72.29      struct acm_ste_policy_buffer *stebuf =
   72.30 @@ -158,11 +160,14 @@ void acm_dump_ste_buffer(void *buf, int 
   72.31          for (j = 0; j < ntohl(stebuf->ste_max_types); j++)
   72.32              printf("%02x ",
   72.33                     ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j]));
   72.34 +        if (i == ste_ref)
   72.35 +            printf(" <-- Domain-0");
   72.36      }
   72.37      printf("\n\n");
   72.38  }
   72.39  
   72.40 -void acm_dump_policy_buffer(void *buf, int buflen)
   72.41 +void acm_dump_policy_buffer(void *buf, int buflen,
   72.42 +                            uint16_t chwall_ref, uint16_t ste_ref)
   72.43  {
   72.44      struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf;
   72.45      char *policy_reference_name =
   72.46 @@ -172,6 +177,9 @@ void acm_dump_policy_buffer(void *buf, i
   72.47      printf("============\n");
   72.48      printf("POLICY REFERENCE = %s.\n", policy_reference_name);
   72.49      printf("PolicyVer = %x.\n", ntohl(pol->policy_version));
   72.50 +    printf("XML Vers. = %d.%d\n",
   72.51 +           ntohl(pol->xml_pol_version.major),
   72.52 +           ntohl(pol->xml_pol_version.minor));
   72.53      printf("Magic     = %x.\n", ntohl(pol->magic));
   72.54      printf("Len       = %x.\n", ntohl(pol->len));
   72.55      printf("Primary   = %s (c=%x, off=%x).\n",
   72.56 @@ -187,13 +195,15 @@ void acm_dump_policy_buffer(void *buf, i
   72.57          acm_dump_chinesewall_buffer(ALIGN8(buf +
   72.58                                       ntohl(pol->primary_buffer_offset)),
   72.59                                      ntohl(pol->len) -
   72.60 -                                    ntohl(pol->primary_buffer_offset));
   72.61 +                                    ntohl(pol->primary_buffer_offset),
   72.62 +                                    chwall_ref);
   72.63          break;
   72.64  
   72.65      case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   72.66          acm_dump_ste_buffer(ALIGN8(buf + ntohl(pol->primary_buffer_offset)),
   72.67                              ntohl(pol->len) -
   72.68 -                            ntohl(pol->primary_buffer_offset));
   72.69 +                            ntohl(pol->primary_buffer_offset),
   72.70 +                            ste_ref);
   72.71          break;
   72.72  
   72.73      case ACM_NULL_POLICY:
   72.74 @@ -209,13 +219,15 @@ void acm_dump_policy_buffer(void *buf, i
   72.75          acm_dump_chinesewall_buffer(ALIGN8(buf +
   72.76                                       ntohl(pol->secondary_buffer_offset)),
   72.77                                      ntohl(pol->len) -
   72.78 -                                    ntohl(pol->secondary_buffer_offset));
   72.79 +                                    ntohl(pol->secondary_buffer_offset),
   72.80 +                                    chwall_ref);
   72.81          break;
   72.82  
   72.83      case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   72.84          acm_dump_ste_buffer(ALIGN8(buf + ntohl(pol->secondary_buffer_offset)),
   72.85                              ntohl(pol->len) -
   72.86 -                            ntohl(pol->secondary_buffer_offset));
   72.87 +                            ntohl(pol->secondary_buffer_offset),
   72.88 +                            ste_ref);
   72.89          break;
   72.90  
   72.91      case ACM_NULL_POLICY:
   72.92 @@ -227,6 +239,27 @@ void acm_dump_policy_buffer(void *buf, i
   72.93      }
   72.94  }
   72.95  
   72.96 +/************************** get dom0 ssidref *****************************/
   72.97 +int acm_get_ssidref(int xc_handle, int domid, uint16_t *chwall_ref,
   72.98 +                    uint16_t *ste_ref)
   72.99 +{
  72.100 +    int ret;
  72.101 +    struct acm_getssid getssid;
  72.102 +    char buf[4096];
  72.103 +    struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *)buf;
  72.104 +    getssid.interface_version = ACM_INTERFACE_VERSION;
  72.105 +    set_xen_guest_handle(getssid.ssidbuf, buf);
  72.106 +    getssid.ssidbuf_size = sizeof(buf);
  72.107 +    getssid.get_ssid_by = ACM_GETBY_domainid;
  72.108 +    getssid.id.domainid = domid;
  72.109 +    ret = xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid));
  72.110 +    if (ret == 0) {
  72.111 +        *chwall_ref = ssid->ssidref  & 0xffff;
  72.112 +        *ste_ref    = ssid->ssidref >> 16;
  72.113 +    }
  72.114 +    return ret;
  72.115 +}
  72.116 +
  72.117  /******************************* get policy ******************************/
  72.118  
  72.119  #define PULL_CACHE_SIZE		8192
  72.120 @@ -236,12 +269,16 @@ int acm_domain_getpolicy(int xc_handle)
  72.121  {
  72.122      struct acm_getpolicy getpolicy;
  72.123      int ret;
  72.124 +    uint16_t chwall_ref, ste_ref;
  72.125  
  72.126      memset(pull_buffer, 0x00, sizeof(pull_buffer));
  72.127      getpolicy.interface_version = ACM_INTERFACE_VERSION;
  72.128      set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
  72.129      getpolicy.pullcache_size = sizeof(pull_buffer);
  72.130      ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
  72.131 +    if (ret >= 0) {
  72.132 +        ret = acm_get_ssidref(xc_handle, 0, &chwall_ref, &ste_ref);
  72.133 +    }
  72.134  
  72.135      if (ret < 0) {
  72.136          printf("ACM operation failed: errno=%d\n", errno);
  72.137 @@ -251,7 +288,9 @@ int acm_domain_getpolicy(int xc_handle)
  72.138      }
  72.139  
  72.140      /* dump policy  */
  72.141 -    acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
  72.142 +    acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer),
  72.143 +                           chwall_ref, ste_ref);
  72.144 +
  72.145      return ret;
  72.146  }
  72.147  
  72.148 @@ -263,6 +302,7 @@ int acm_domain_loadpolicy(int xc_handle,
  72.149      int ret, fd;
  72.150      off_t len;
  72.151      uint8_t *buffer;
  72.152 +    uint16_t chwall_ssidref, ste_ssidref;
  72.153  
  72.154      if ((ret = stat(filename, &mystat))) {
  72.155          printf("File %s not found.\n", filename);
  72.156 @@ -279,10 +319,14 @@ int acm_domain_loadpolicy(int xc_handle,
  72.157          printf("File %s not found.\n", filename);
  72.158          goto free_out;
  72.159      }
  72.160 +    ret =acm_get_ssidref(xc_handle, 0, &chwall_ssidref, &ste_ssidref);
  72.161 +    if (ret < 0) {
  72.162 +        goto free_out;
  72.163 +    }
  72.164      if (len == read(fd, buffer, len)) {
  72.165          struct acm_setpolicy setpolicy;
  72.166          /* dump it and then push it down into xen/acm */
  72.167 -        acm_dump_policy_buffer(buffer, len);
  72.168 +        acm_dump_policy_buffer(buffer, len, chwall_ssidref, ste_ssidref);
  72.169          setpolicy.interface_version = ACM_INTERFACE_VERSION;
  72.170          set_xen_guest_handle(setpolicy.pushcache, buffer);
  72.171          setpolicy.pushcache_size = len;
    73.1 --- a/tools/security/secpol_xml2bin.c	Fri Mar 30 10:27:15 2007 -0600
    73.2 +++ b/tools/security/secpol_xml2bin.c	Fri Mar 30 17:18:42 2007 -0600
    73.3 @@ -108,26 +108,25 @@ char *policy_filename = NULL,
    73.4  
    73.5  char *policy_reference_name = NULL;
    73.6  
    73.7 +char *policy_version_string = NULL;
    73.8 +
    73.9  void walk_labels(xmlNode * start, xmlDocPtr doc, unsigned long state);
   73.10  
   73.11  void usage(char *prg)
   73.12  {
   73.13 -    printf("Usage: %s [OPTIONS] POLICYNAME\n", prg);
   73.14 -    printf
   73.15 -        ("POLICYNAME is the directory name within the policy directory\n");
   73.16 -    printf
   73.17 -        ("that contains the policy files.  The default policy directory\n");
   73.18 -    printf("is '%s' (see the '-d' option below to change it)\n",
   73.19 -           POLICY_DIR);
   73.20 -    printf
   73.21 -        ("The policy files contained in the POLICYNAME directory must be named:\n");
   73.22 -    printf("\tPOLICYNAME-security_policy.xml\n");
   73.23 -    printf("\tPOLICYNAME-security_label_template.xml\n\n");
   73.24 -    printf("OPTIONS:\n");
   73.25 -    printf("\t-d POLICYDIR\n");
   73.26 -    printf
   73.27 -        ("\t\tUse POLICYDIR as the policy directory. This directory must contain\n");
   73.28 -    printf("\t\tthe policy schema file 'security_policy.xsd'\n");
   73.29 +    printf(
   73.30 +    "Usage: %s [OPTIONS] POLICYNAME\n"
   73.31 +    "POLICYNAME is the directory name within the policy directory\n"
   73.32 +    "that contains the policy files.  The default policy directory\n"
   73.33 +    "is '%s' (see the '-d' option below to change it)\n"
   73.34 +    "The policy files contained in the POLICYNAME directory must be named:\n"
   73.35 +    "\tPOLICYNAME-security_policy.xml\n"
   73.36 +    "\tPOLICYNAME-security_label_template.xml\n\n"
   73.37 +    "OPTIONS:\n"
   73.38 +    "\t-d POLICYDIR\n"
   73.39 +    "\t\tUse POLICYDIR as the policy directory. This directory must \n"
   73.40 +    "\t\tcontain the policy schema file 'security_policy.xsd'\n",
   73.41 +    prg, POLICY_DIR);
   73.42      exit(EXIT_FAILURE);
   73.43  }
   73.44  
   73.45 @@ -300,25 +299,50 @@ void walk_policy(xmlNode * start, xmlDoc
   73.46          case XML2BIN_CHWALLTYPES:
   73.47          case XML2BIN_CONFLICTSETS:
   73.48          case XML2BIN_POLICYHEADER:
   73.49 +        case XML2BIN_FROMPOLICY:
   73.50              walk_policy(cur_node->children, doc, state | (1 << code));
   73.51              break;
   73.52  
   73.53          case XML2BIN_POLICYNAME:       /* get policy reference name .... */
   73.54 -            if (state != XML2BIN_PN_S) {
   73.55 +            if (state != XML2BIN_PN_S &&
   73.56 +                state != XML2BIN_PN_frompolicy_S) {
   73.57                  printf("ERROR: >Url< >%s< out of context.\n",
   73.58                         (char *) xmlNodeListGetString(doc,
   73.59                                                       cur_node->
   73.60                                                       xmlChildrenNode, 1));
   73.61                  exit(EXIT_FAILURE);
   73.62              }
   73.63 -            policy_reference_name = (char *)
   73.64 -                xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
   73.65 -            if (!policy_reference_name) {
   73.66 -                printf("ERROR: empty >policy reference name (Url)<!\n");
   73.67 +            if (state == XML2BIN_PN_S) {
   73.68 +                policy_reference_name = (char *)
   73.69 +                    xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
   73.70 +                if (!policy_reference_name) {
   73.71 +                    printf("ERROR: empty >policy reference name (Url)<!\n");
   73.72 +                    exit(EXIT_FAILURE);
   73.73 +                } else
   73.74 +                    printf("Policy Reference name (Url): %s\n",
   73.75 +                           policy_reference_name);
   73.76 +            }
   73.77 +            break;
   73.78 +
   73.79 +        case XML2BIN_VERSION:         /* get policy version number .... */
   73.80 +            if (state != XML2BIN_PN_S &&
   73.81 +                state != XML2BIN_PN_frompolicy_S) {
   73.82 +                printf("ERROR: >Url< >%s< out of context.\n",
   73.83 +                       (char *) xmlNodeListGetString(doc,
   73.84 +                                                     cur_node->
   73.85 +                                                     xmlChildrenNode, 1));
   73.86                  exit(EXIT_FAILURE);
   73.87 -            } else
   73.88 -                printf("Policy Reference name (Url): %s\n",
   73.89 -                       policy_reference_name);
   73.90 +            }
   73.91 +            if (state == XML2BIN_PN_S) {
   73.92 +                policy_version_string = (char *)
   73.93 +                    xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
   73.94 +                if (!policy_version_string) {
   73.95 +                    printf("ERROR: empty >policy version string <!\n");
   73.96 +                    exit(EXIT_FAILURE);
   73.97 +                } else
   73.98 +                    printf("Policy version string: %s\n",
   73.99 +                           policy_version_string);
  73.100 +            }
  73.101              break;
  73.102  
  73.103          case XML2BIN_STE:
  73.104 @@ -1135,9 +1159,13 @@ int write_binary(char *filename)
  73.105          NULL, *policy_reference_buffer = NULL;
  73.106      u_int32_t len;
  73.107      int fd, ret = 0;
  73.108 +    uint32_t major = 0, minor = 0;
  73.109  
  73.110      u_int32_t len_ste = 0, len_chwall = 0, len_pr = 0;  /* length of policy components */
  73.111  
  73.112 +    if (policy_version_string)
  73.113 +        sscanf(policy_version_string,"%d.%d", &major, &minor);
  73.114 +
  73.115      /* open binary file */
  73.116      if ((fd =
  73.117           open(filename, O_WRONLY | O_CREAT | O_TRUNC,
  73.118 @@ -1152,6 +1180,8 @@ int write_binary(char *filename)
  73.119      /* determine primary component (default chwall) */
  73.120      header.policy_version = htonl(ACM_POLICY_VERSION);
  73.121      header.magic = htonl(ACM_MAGIC);
  73.122 +    header.xml_pol_version.major = htonl(major);
  73.123 +    header.xml_pol_version.minor = htonl(minor);
  73.124  
  73.125      len = sizeof(struct acm_policy_buffer);
  73.126      if (have_chwall)
    74.1 --- a/tools/security/secpol_xml2bin.h	Fri Mar 30 10:27:15 2007 -0600
    74.2 +++ b/tools/security/secpol_xml2bin.h	Fri Mar 30 17:18:42 2007 -0600
    74.3 @@ -22,31 +22,35 @@
    74.4  #define SCHEMA_FILENAME     			"security_policy.xsd"
    74.5  
    74.6  /* basic states (used as 1 << X) */
    74.7 -#define ENDOFLIST_POS           22  /* ADAPT!! this position will be NULL; stay below 32 (bit) */
    74.8 -#define XML2BIN_SECPOL          0   /* policy tokens */
    74.9 -#define XML2BIN_STE             1
   74.10 -#define XML2BIN_CHWALL          2
   74.11 -#define XML2BIN_CONFLICTSETS    3
   74.12 -#define XML2BIN_CSTYPE          4
   74.13 -#define XML2BIN_POLICYHEADER    5
   74.14 -#define XML2BIN_NSURL           6
   74.15 -#define XML2BIN_POLICYNAME      7
   74.16 -#define XML2BIN_URL             8
   74.17 -#define XML2BIN_REFERENCE       9
   74.18 -#define XML2BIN_DATE            10
   74.19 +enum {
   74.20 +    XML2BIN_SECPOL = 0,   /* policy tokens */
   74.21 +    XML2BIN_STE,
   74.22 +    XML2BIN_CHWALL,
   74.23 +    XML2BIN_CONFLICTSETS,
   74.24 +    XML2BIN_CSTYPE,
   74.25 +    XML2BIN_POLICYHEADER,
   74.26 +    XML2BIN_NSURL,
   74.27 +    XML2BIN_POLICYNAME,
   74.28 +    XML2BIN_URL,
   74.29 +    XML2BIN_REFERENCE,
   74.30 +    XML2BIN_DATE,
   74.31 +    XML2BIN_VERSION,
   74.32 +    XML2BIN_FROMPOLICY,
   74.33  
   74.34 -#define XML2BIN_LABELTEMPLATE   11  /* label tokens */
   74.35 -#define XML2BIN_SUBJECTS        12
   74.36 -#define XML2BIN_OBJECTS         13
   74.37 -#define XML2BIN_VM              14
   74.38 -#define XML2BIN_RES             15
   74.39 -#define XML2BIN_NAME            16
   74.40 +    XML2BIN_LABELTEMPLATE,  /* label tokens */
   74.41 +    XML2BIN_SUBJECTS,
   74.42 +    XML2BIN_OBJECTS,
   74.43 +    XML2BIN_VM,
   74.44 +    XML2BIN_RES,
   74.45 +    XML2BIN_NAME,
   74.46  
   74.47 -#define XML2BIN_STETYPES        17  /* shared tokens */
   74.48 -#define XML2BIN_CHWALLTYPES     18
   74.49 -#define XML2BIN_TYPE            19
   74.50 -#define XML2BIN_TEXT            20
   74.51 -#define XML2BIN_COMMENT         21
   74.52 +    XML2BIN_STETYPES,
   74.53 +    XML2BIN_CHWALLTYPES,
   74.54 +    XML2BIN_TYPE,
   74.55 +    XML2BIN_TEXT,
   74.56 +    XML2BIN_COMMENT,
   74.57 +    ENDOFLIST_POS /* keep last ! */
   74.58 +};
   74.59  
   74.60  /* type "data type" (currently 16bit) */
   74.61  typedef u_int16_t type_t;
   74.62 @@ -68,6 +72,8 @@ char *token[32] =                       
   74.63      [XML2BIN_URL]           = "PolicyUrl",
   74.64      [XML2BIN_REFERENCE]     = "Reference",
   74.65      [XML2BIN_DATE]          = "Date",
   74.66 +    [XML2BIN_VERSION]       = "Version",
   74.67 +    [XML2BIN_FROMPOLICY]    = "FromPolicy",
   74.68  
   74.69      [XML2BIN_LABELTEMPLATE] = "SecurityLabelTemplate", /* label-template xml */
   74.70      [XML2BIN_SUBJECTS]      = "SubjectLabels",
   74.71 @@ -79,7 +85,7 @@ char *token[32] =                       
   74.72      [XML2BIN_STETYPES]      = "SimpleTypeEnforcementTypes", /* common tags */
   74.73      [XML2BIN_CHWALLTYPES]   = "ChineseWallTypes",
   74.74      [XML2BIN_TYPE]          = "Type",
   74.75 -	[XML2BIN_TEXT]          = "text",
   74.76 +    [XML2BIN_TEXT]          = "text",
   74.77      [XML2BIN_COMMENT]       = "comment",
   74.78      [ENDOFLIST_POS]         = NULL  /* End of LIST, adapt ENDOFLIST_POS
   74.79                                         when adding entries */
   74.80 @@ -112,6 +118,10 @@ char *token[32] =                       
   74.81  #define XML2BIN_PN_S ((1 << XML2BIN_SECPOL) | \
   74.82                   (1 << XML2BIN_POLICYHEADER))
   74.83  
   74.84 +#define XML2BIN_PN_frompolicy_S ((1 << XML2BIN_SECPOL) | \
   74.85 +                 (1 << XML2BIN_POLICYHEADER) | \
   74.86 +                 (1 << XML2BIN_FROMPOLICY))
   74.87 +
   74.88  /* label xml states */
   74.89  #define XML2BIN_VM_S ((1 << XML2BIN_SECPOL) | \
   74.90                   (1 << XML2BIN_LABELTEMPLATE) |	\
   74.91 @@ -147,7 +157,7 @@ char *token[32] =                       
   74.92   */
   74.93  
   74.94  /* protects from unnoticed changes in struct acm_policy_buffer */
   74.95 -#define WRITTEN_AGAINST_ACM_POLICY_VERSION  2
   74.96 +#define WRITTEN_AGAINST_ACM_POLICY_VERSION  3
   74.97  
   74.98  /* protects from unnoticed changes in struct acm_chwall_policy_buffer */
   74.99  #define WRITTEN_AGAINST_ACM_CHWALL_VERSION  1
    75.1 --- a/tools/xcutils/xc_restore.c	Fri Mar 30 10:27:15 2007 -0600
    75.2 +++ b/tools/xcutils/xc_restore.c	Fri Mar 30 17:18:42 2007 -0600
    75.3 @@ -42,8 +42,6 @@ main(int argc, char **argv)
    75.4      apic = atoi(argv[8]);
    75.5  
    75.6      if (hvm) {
    75.7 -         /* pass the memsize to xc_hvm_restore to find the store_mfn */
    75.8 -        store_mfn = hvm;
    75.9          ret = xc_hvm_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn,
   75.10                  &store_mfn, pae, apic);
   75.11      } else 
    76.1 --- a/tools/xm-test/lib/XmTestLib/XenAPIDomain.py	Fri Mar 30 10:27:15 2007 -0600
    76.2 +++ b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py	Fri Mar 30 17:18:42 2007 -0600
    76.3 @@ -22,7 +22,6 @@
    76.4  import os
    76.5  import sys
    76.6  from XmTestLib import *
    76.7 -from xen.util.xmlrpclib2 import ServerProxy
    76.8  from types import DictType
    76.9  
   76.10  
    77.1 --- a/tools/xm-test/tests/destroy/06_destroy_dom0_neg.py	Fri Mar 30 10:27:15 2007 -0600
    77.2 +++ b/tools/xm-test/tests/destroy/06_destroy_dom0_neg.py	Fri Mar 30 17:18:42 2007 -0600
    77.3 @@ -10,5 +10,5 @@ from XmTestLib import *
    77.4  status, output = traceCommand("xm destroy 0")
    77.5  if status == 0:
    77.6      FAIL("xm destroy returned bad status, expected non 0, status is: %i" % status)
    77.7 -elif not re.search("Error", output):
    77.8 +elif not re.search("Error", output, re.I):
    77.9      FAIL("xm destroy returned bad output, expected Error:, output is: %s" % output)
    78.1 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Fri Mar 30 10:27:15 2007 -0600
    78.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Fri Mar 30 17:18:42 2007 -0600
    78.3 @@ -36,6 +36,7 @@
    78.4  #include <asm/pgtable.h>
    78.5  #include <xen/interface/memory.h>
    78.6  #include <xen/features.h>
    78.7 +#include <xen/gnttab.h>
    78.8  #ifdef __ia64__
    78.9  #include <asm/xen/xencomm.h>
   78.10  #endif
   78.11 @@ -61,9 +62,11 @@ MODULE_LICENSE("GPL");
   78.12  unsigned long *phys_to_machine_mapping;
   78.13  EXPORT_SYMBOL(phys_to_machine_mapping);
   78.14  
   78.15 +static unsigned long shared_info_frame;
   78.16 +static uint64_t callback_via;
   78.17 +
   78.18  static int __devinit init_xen_info(void)
   78.19  {
   78.20 -	unsigned long shared_info_frame;
   78.21  	struct xen_add_to_physmap xatp;
   78.22  	extern void *shared_info_area;
   78.23  
   78.24 @@ -219,7 +222,6 @@ static int __devinit platform_pci_init(s
   78.25  	int i, ret;
   78.26  	long ioaddr, iolen;
   78.27  	long mmio_addr, mmio_len;
   78.28 -	uint64_t callback_via;
   78.29  
   78.30  	i = pci_enable_device(pdev);
   78.31  	if (i)
   78.32 @@ -303,6 +305,35 @@ static struct pci_driver platform_driver
   78.33  
   78.34  static int pci_device_registered;
   78.35  
   78.36 +void platform_pci_suspend(void)
   78.37 +{
   78.38 +	gnttab_suspend();
   78.39 +}
   78.40 +EXPORT_SYMBOL_GPL(platform_pci_suspend);
   78.41 +
   78.42 +void platform_pci_resume(void)
   78.43 +{
   78.44 +	struct xen_add_to_physmap xatp;
   78.45 +	phys_to_machine_mapping = NULL;
   78.46 +
   78.47 +	/* do 2 things for PV driver restore on HVM
   78.48 +	 * 1: rebuild share info
   78.49 +	 * 2: set callback irq again
   78.50 +	 */
   78.51 +	xatp.domid = DOMID_SELF;
   78.52 +	xatp.idx = 0;
   78.53 +	xatp.space = XENMAPSPACE_shared_info;
   78.54 +	xatp.gpfn = shared_info_frame;
   78.55 +	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
   78.56 +		BUG();
   78.57 +
   78.58 +	if (( set_callback_via(callback_via)))
   78.59 +		printk("platform_pci_resume failure!\n");
   78.60 +
   78.61 +	gnttab_resume();
   78.62 +}
   78.63 +EXPORT_SYMBOL_GPL(platform_pci_resume);
   78.64 +
   78.65  static int __init platform_pci_module_init(void)
   78.66  {
   78.67  	int rc;
    79.1 --- a/xen/acm/acm_chinesewall_hooks.c	Fri Mar 30 10:27:15 2007 -0600
    79.2 +++ b/xen/acm/acm_chinesewall_hooks.c	Fri Mar 30 17:18:42 2007 -0600
    79.3 @@ -41,6 +41,9 @@
    79.4  #include <acm/acm_core.h>
    79.5  #include <acm/acm_hooks.h>
    79.6  #include <acm/acm_endian.h>
    79.7 +#include <acm/acm_core.h>
    79.8 +
    79.9 +ssidref_t dom0_chwall_ssidref = 0x0001;
   79.10  
   79.11  /* local cache structures for chinese wall policy */
   79.12  struct chwall_binary_policy chwall_bin_pol;
   79.13 @@ -53,7 +56,7 @@ int acm_init_chwall_policy(void)
   79.14  {
   79.15      /* minimal startup policy; policy write-locked already */
   79.16      chwall_bin_pol.max_types = 1;
   79.17 -    chwall_bin_pol.max_ssidrefs = 2;
   79.18 +    chwall_bin_pol.max_ssidrefs = 1 + dom0_chwall_ssidref;
   79.19      chwall_bin_pol.max_conflictsets = 1;
   79.20      chwall_bin_pol.ssidrefs =
   79.21          (domaintype_t *) xmalloc_array(domaintype_t,
   79.22 @@ -254,7 +257,7 @@ chwall_init_state(struct acm_chwall_poli
   79.23       * more than one type is currently running */
   79.24  }
   79.25  
   79.26 -static int chwall_set_policy(u8 * buf, u32 buf_size)
   79.27 +static int chwall_set_policy(u8 * buf, u32 buf_size, int is_bootpolicy)
   79.28  {
   79.29      /* policy write-locked already */
   79.30      struct acm_chwall_policy_buffer *chwall_buf =
   79.31 @@ -286,6 +289,12 @@ static int chwall_set_policy(u8 * buf, u
   79.32          (chwall_buf->policy_version != ACM_CHWALL_VERSION))
   79.33          return -EINVAL;
   79.34  
   79.35 +    /* during boot dom0_chwall_ssidref is set */
   79.36 +    if (is_bootpolicy &&
   79.37 +        (dom0_chwall_ssidref >= chwall_buf->chwall_max_ssidrefs)) {
   79.38 +        goto error_free;
   79.39 +    }
   79.40 +
   79.41      /* 1. allocate new buffers */
   79.42      ssids =
   79.43          xmalloc_array(domaintype_t,
    80.1 --- a/xen/acm/acm_core.c	Fri Mar 30 10:27:15 2007 -0600
    80.2 +++ b/xen/acm/acm_core.c	Fri Mar 30 17:18:42 2007 -0600
    80.3 @@ -62,18 +62,63 @@ struct acm_binary_policy acm_bin_pol;
    80.4  /* acm binary policy lock */
    80.5  DEFINE_RWLOCK(acm_bin_pol_rwlock);
    80.6  
    80.7 +/* ACM's only accepted policy name */
    80.8 +char polname[80];
    80.9 +char *acm_accepted_boot_policy_name = NULL;
   80.10 +
   80.11 +static void __init set_dom0_ssidref(const char *val)
   80.12 +{
   80.13 +    /* expected format:
   80.14 +         ssidref=<hex number>:<policy name>
   80.15 +         Policy name must not have a 'space'.
   80.16 +     */
   80.17 +    const char *c;
   80.18 +    int lo, hi;
   80.19 +    int i;
   80.20 +    int dom0_ssidref = simple_strtoull(val, &c, 0);
   80.21 +
   80.22 +    if (!strncmp(&c[0],":sHype:", 7)) {
   80.23 +        lo = dom0_ssidref & 0xffff;
   80.24 +        if (lo < ACM_MAX_NUM_TYPES && lo >= 1)
   80.25 +            dom0_chwall_ssidref = lo;
   80.26 +        hi = dom0_ssidref >> 16;
   80.27 +        if (hi < ACM_MAX_NUM_TYPES && hi >= 1)
   80.28 +            dom0_ste_ssidref = hi;
   80.29 +        for (i = 0; i < sizeof(polname); i++) {
   80.30 +            polname[i] = c[7+i];
   80.31 +            if (polname[i] == '\0' || polname[i] == '\t' ||
   80.32 +                polname[i] == '\n' || polname[i] == ' '  ||
   80.33 +                polname[i] == ':') {
   80.34 +                break;
   80.35 +            }
   80.36 +        }
   80.37 +        polname[i] = 0;
   80.38 +        acm_accepted_boot_policy_name = polname;
   80.39 +    }
   80.40 +}
   80.41 +
   80.42 +custom_param("ssidref", set_dom0_ssidref);
   80.43 +
   80.44  int
   80.45  acm_set_policy_reference(u8 *buf, u32 buf_size)
   80.46  {
   80.47 +    char *name = (char *)(buf + sizeof(struct acm_policy_reference_buffer));
   80.48      struct acm_policy_reference_buffer *pr = (struct acm_policy_reference_buffer *)buf;
   80.49 +
   80.50 +    if (acm_accepted_boot_policy_name != NULL) {
   80.51 +        if (strcmp(acm_accepted_boot_policy_name, name)) {
   80.52 +            printk("Policy's name '%s' is not the expected one '%s'.\n",
   80.53 +                   name, acm_accepted_boot_policy_name);
   80.54 +            return ACM_ERROR;
   80.55 +        }
   80.56 +    }
   80.57 +
   80.58      acm_bin_pol.policy_reference_name = (char *)xmalloc_array(u8, be32_to_cpu(pr->len));
   80.59  
   80.60      if (!acm_bin_pol.policy_reference_name)
   80.61          return -ENOMEM;
   80.62 +    strlcpy(acm_bin_pol.policy_reference_name, name, be32_to_cpu(pr->len));
   80.63  
   80.64 -    strlcpy(acm_bin_pol.policy_reference_name,
   80.65 -            (char *)(buf + sizeof(struct acm_policy_reference_buffer)),
   80.66 -            be32_to_cpu(pr->len));
   80.67      printk("%s: Activating policy %s\n", __func__,
   80.68             acm_bin_pol.policy_reference_name);
   80.69      return 0;
   80.70 @@ -190,7 +235,8 @@ acm_is_policy(char *buf, unsigned long l
   80.71  
   80.72  static int
   80.73  acm_setup(char *policy_start,
   80.74 -          unsigned long policy_len)
   80.75 +          unsigned long policy_len,
   80.76 +          int is_bootpolicy)
   80.77  {
   80.78      int rc = ACM_OK;
   80.79      struct acm_policy_buffer *pol;
   80.80 @@ -202,7 +248,8 @@ acm_setup(char *policy_start,
   80.81      if (be32_to_cpu(pol->magic) != ACM_MAGIC)
   80.82          return rc;
   80.83  
   80.84 -    rc = do_acm_set_policy((void *)policy_start, (u32)policy_len);
   80.85 +    rc = do_acm_set_policy((void *)policy_start, (u32)policy_len,
   80.86 +                           is_bootpolicy);
   80.87      if (rc == ACM_OK)
   80.88      {
   80.89          printkd("Policy len  0x%lx, start at %p.\n",policy_len,policy_start);
   80.90 @@ -224,7 +271,10 @@ acm_init(char *policy_start,
   80.91      int ret = ACM_OK;
   80.92  
   80.93      /* first try to load the boot policy (uses its own locks) */
   80.94 -    acm_setup(policy_start, policy_len);
   80.95 +    acm_setup(policy_start, policy_len, 1);
   80.96 +
   80.97 +    /* a user-provided policy may have any name; only matched during boot */
   80.98 +    acm_accepted_boot_policy_name = NULL;
   80.99  
  80.100      if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
  80.101      {
  80.102 @@ -236,6 +286,9 @@ acm_init(char *policy_start,
  80.103      printk("%s: Loading default policy (%s).\n",
  80.104             __func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY));
  80.105  
  80.106 +    /* (re-)set dom-0 ssidref to default */
  80.107 +    dom0_ste_ssidref = dom0_chwall_ssidref = 0x0001;
  80.108 +
  80.109      if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) {
  80.110          ret = -EINVAL;
  80.111          goto out;
    81.1 --- a/xen/acm/acm_null_hooks.c	Fri Mar 30 10:27:15 2007 -0600
    81.2 +++ b/xen/acm/acm_null_hooks.c	Fri Mar 30 17:18:42 2007 -0600
    81.3 @@ -33,7 +33,7 @@ null_dump_binary_policy(u8 *buf, u32 buf
    81.4  }
    81.5  
    81.6  static int
    81.7 -null_set_binary_policy(u8 *buf, u32 buf_size)
    81.8 +null_set_binary_policy(u8 *buf, u32 buf_size, int is_bootpolicy)
    81.9  { 
   81.10      return ACM_OK;
   81.11  }
    82.1 --- a/xen/acm/acm_policy.c	Fri Mar 30 10:27:15 2007 -0600
    82.2 +++ b/xen/acm/acm_policy.c	Fri Mar 30 17:18:42 2007 -0600
    82.3 @@ -50,7 +50,7 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
    82.4          printk("%s: Error copying!\n",__func__);
    82.5          goto error_free;
    82.6      }
    82.7 -    ret = do_acm_set_policy(policy_buffer, buf_size);
    82.8 +    ret = do_acm_set_policy(policy_buffer, buf_size, 0);
    82.9  
   82.10   error_free:
   82.11      xfree(policy_buffer);
   82.12 @@ -59,9 +59,10 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
   82.13  
   82.14  
   82.15  int
   82.16 -do_acm_set_policy(void *buf, u32 buf_size)
   82.17 +do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy)
   82.18  {
   82.19      struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
   82.20 +    uint32_t offset, length;
   82.21      /* some sanity checking */
   82.22      if ((be32_to_cpu(pol->magic) != ACM_MAGIC) ||
   82.23          (buf_size != be32_to_cpu(pol->len)) ||
   82.24 @@ -92,24 +93,35 @@ do_acm_set_policy(void *buf, u32 buf_siz
   82.25      /* get bin_policy lock and rewrite policy (release old one) */
   82.26      write_lock(&acm_bin_pol_rwlock);
   82.27  
   82.28 +    offset = be32_to_cpu(pol->policy_reference_offset);
   82.29 +    length = be32_to_cpu(pol->primary_buffer_offset) - offset;
   82.30 +
   82.31      /* set label reference name */
   82.32 -    if (acm_set_policy_reference(buf + be32_to_cpu(pol->policy_reference_offset),
   82.33 -                                 be32_to_cpu(pol->primary_buffer_offset) -
   82.34 -                                 be32_to_cpu(pol->policy_reference_offset)))
   82.35 +    if ( (offset + length) > buf_size ||
   82.36 +         acm_set_policy_reference(buf + offset, length))
   82.37          goto error_lock_free;
   82.38  
   82.39      /* set primary policy data */
   82.40 -    if (acm_primary_ops->set_binary_policy(buf + be32_to_cpu(pol->primary_buffer_offset),
   82.41 -                                           be32_to_cpu(pol->secondary_buffer_offset) -
   82.42 -                                           be32_to_cpu(pol->primary_buffer_offset)))
   82.43 +    offset = be32_to_cpu(pol->primary_buffer_offset);
   82.44 +    length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
   82.45 +
   82.46 +    if ( (offset + length) > buf_size ||
   82.47 +         acm_primary_ops->set_binary_policy(buf + offset, length,
   82.48 +                                            is_bootpolicy))
   82.49          goto error_lock_free;
   82.50  
   82.51      /* set secondary policy data */
   82.52 -    if (acm_secondary_ops->set_binary_policy(buf + be32_to_cpu(pol->secondary_buffer_offset),
   82.53 -                                             be32_to_cpu(pol->len) - 
   82.54 -                                             be32_to_cpu(pol->secondary_buffer_offset)))
   82.55 +    offset = be32_to_cpu(pol->secondary_buffer_offset);
   82.56 +    length = be32_to_cpu(pol->len) - offset;
   82.57 +    if ( (offset + length) > buf_size ||
   82.58 +         acm_secondary_ops->set_binary_policy(buf + offset, length,
   82.59 +                                              is_bootpolicy))
   82.60          goto error_lock_free;
   82.61  
   82.62 +    memcpy(&acm_bin_pol.xml_pol_version,
   82.63 +           &pol->xml_pol_version,
   82.64 +           sizeof(acm_bin_pol.xml_pol_version));
   82.65 +
   82.66      write_unlock(&acm_bin_pol_rwlock);
   82.67      return ACM_OK;
   82.68  
   82.69 @@ -126,7 +138,7 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu
   82.70      u8 *policy_buffer;
   82.71      int ret;
   82.72      struct acm_policy_buffer *bin_pol;
   82.73 - 
   82.74 +
   82.75      if (buf_size < sizeof(struct acm_policy_buffer))
   82.76          return -EFAULT;
   82.77  
   82.78 @@ -145,6 +157,10 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu
   82.79      bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
   82.80      bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
   82.81       
   82.82 +    memcpy(&bin_pol->xml_pol_version,
   82.83 +           &acm_bin_pol.xml_pol_version,
   82.84 +           sizeof(struct acm_policy_version));
   82.85 +
   82.86      ret = acm_dump_policy_reference(policy_buffer + be32_to_cpu(bin_pol->policy_reference_offset),
   82.87                                      buf_size - be32_to_cpu(bin_pol->policy_reference_offset));
   82.88      if (ret < 0)
    83.1 --- a/xen/acm/acm_simple_type_enforcement_hooks.c	Fri Mar 30 10:27:15 2007 -0600
    83.2 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c	Fri Mar 30 17:18:42 2007 -0600
    83.3 @@ -31,6 +31,9 @@
    83.4  #include <acm/acm_hooks.h>
    83.5  #include <asm/atomic.h>
    83.6  #include <acm/acm_endian.h>
    83.7 +#include <acm/acm_core.h>
    83.8 +
    83.9 +ssidref_t dom0_ste_ssidref = 0x0001;
   83.10  
   83.11  /* local cache structures for STE policy */
   83.12  struct ste_binary_policy ste_bin_pol;
   83.13 @@ -74,15 +77,21 @@ int acm_init_ste_policy(void)
   83.14  {
   83.15      /* minimal startup policy; policy write-locked already */
   83.16      ste_bin_pol.max_types = 1;
   83.17 -    ste_bin_pol.max_ssidrefs = 2;
   83.18 -    ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2);
   83.19 -    memset(ste_bin_pol.ssidrefs, 0, 2);
   83.20 +    ste_bin_pol.max_ssidrefs = 1 + dom0_ste_ssidref;
   83.21 +    ste_bin_pol.ssidrefs =
   83.22 +            (domaintype_t *)xmalloc_array(domaintype_t,
   83.23 +                                          ste_bin_pol.max_types *
   83.24 +                                          ste_bin_pol.max_ssidrefs);
   83.25  
   83.26      if (ste_bin_pol.ssidrefs == NULL)
   83.27          return ACM_INIT_SSID_ERROR;
   83.28  
   83.29 - /* initialize state so that dom0 can start up and communicate with itself */
   83.30 -    ste_bin_pol.ssidrefs[1] = 1;
   83.31 +    memset(ste_bin_pol.ssidrefs, 0, sizeof(domaintype_t) *
   83.32 +                                    ste_bin_pol.max_types *
   83.33 +                                    ste_bin_pol.max_ssidrefs);
   83.34 +
   83.35 +    /* initialize state so that dom0 can start up and communicate with itself */
   83.36 +    ste_bin_pol.ssidrefs[ste_bin_pol.max_types * dom0_ste_ssidref] = 1;
   83.37  
   83.38      /* init stats */
   83.39      atomic_set(&(ste_bin_pol.ec_eval_count), 0);
   83.40 @@ -274,7 +283,7 @@ ste_init_state(struct acm_ste_policy_buf
   83.41  
   83.42  /* set new policy; policy write-locked already */
   83.43  static int
   83.44 -ste_set_policy(u8 *buf, u32 buf_size)
   83.45 +ste_set_policy(u8 *buf, u32 buf_size, int is_bootpolicy)
   83.46  {
   83.47      struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf;
   83.48      void *ssidrefsbuf;
   83.49 @@ -305,6 +314,11 @@ ste_set_policy(u8 *buf, u32 buf_size)
   83.50      if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size)
   83.51          goto error_free;
   83.52  
   83.53 +    /* during boot dom0_chwall_ssidref is set */
   83.54 +    if (is_bootpolicy && (dom0_ste_ssidref >= ste_buf->ste_max_ssidrefs)) {
   83.55 +        goto error_free;
   83.56 +    }
   83.57 +
   83.58      arrcpy(ssidrefsbuf, 
   83.59             buf + ste_buf->ste_ssid_offset,
   83.60             sizeof(domaintype_t),
    84.1 --- a/xen/arch/ia64/asm-offsets.c	Fri Mar 30 10:27:15 2007 -0600
    84.2 +++ b/xen/arch/ia64/asm-offsets.c	Fri Mar 30 17:18:42 2007 -0600
    84.3 @@ -223,10 +223,11 @@ void foo(void)
    84.4  
    84.5  #ifdef PERF_COUNTERS
    84.6  	BLANK();
    84.7 -	DEFINE(RECOVER_TO_PAGE_FAULT_PERFC_OFS, offsetof (struct perfcounter, recover_to_page_fault));
    84.8 -	DEFINE(RECOVER_TO_BREAK_FAULT_PERFC_OFS, offsetof (struct perfcounter, recover_to_break_fault));
    84.9 -	DEFINE(FAST_HYPERPRIVOP_PERFC_OFS, offsetof (struct perfcounter, fast_hyperprivop));
   84.10 -	DEFINE(FAST_REFLECT_PERFC_OFS, offsetof (struct perfcounter, fast_reflect));
   84.11 +	DEFINE(IA64_PERFC_recover_to_page_fault, PERFC_recover_to_page_fault);
   84.12 +	DEFINE(IA64_PERFC_recover_to_break_fault, PERFC_recover_to_break_fault);
   84.13 +	DEFINE(IA64_PERFC_fast_vhpt_translate, PERFC_fast_vhpt_translate);
   84.14 +	DEFINE(IA64_PERFC_fast_hyperprivop, PERFC_fast_hyperprivop);
   84.15 +	DEFINE(IA64_PERFC_fast_reflect, PERFC_fast_reflect);
   84.16  #endif
   84.17  
   84.18  	BLANK();
    85.1 --- a/xen/arch/ia64/linux-xen/irq_ia64.c	Fri Mar 30 10:27:15 2007 -0600
    85.2 +++ b/xen/arch/ia64/linux-xen/irq_ia64.c	Fri Mar 30 17:18:42 2007 -0600
    85.3 @@ -113,7 +113,7 @@ ia64_handle_irq (ia64_vector vector, str
    85.4  	unsigned long saved_tpr;
    85.5  
    85.6  #ifdef XEN
    85.7 -	perfc_incrc(irqs);
    85.8 +	perfc_incr(irqs);
    85.9  #endif
   85.10  #if IRQ_DEBUG
   85.11  #ifdef XEN
    86.1 --- a/xen/arch/ia64/linux-xen/mca.c	Fri Mar 30 10:27:15 2007 -0600
    86.2 +++ b/xen/arch/ia64/linux-xen/mca.c	Fri Mar 30 17:18:42 2007 -0600
    86.3 @@ -397,16 +397,6 @@ ia64_log_queue(int sal_info_type, int vi
    86.4  
    86.5  #ifdef XEN
    86.6  /**
    86.7 - *	Copy from linux/include/asm-generic/bug.h
    86.8 - */
    86.9 -#define WARN_ON(condition) do { \
   86.10 -	if (unlikely((condition)!=0)) { \
   86.11 -		printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
   86.12 -		dump_stack(); \
   86.13 -	} \
   86.14 -} while (0)
   86.15 -
   86.16 -/**
   86.17   *	Copy from linux/kernel/irq/manage.c
   86.18   *
   86.19   *	disable_irq_nosync - disable an irq without waiting
    87.1 --- a/xen/arch/ia64/linux-xen/smp.c	Fri Mar 30 10:27:15 2007 -0600
    87.2 +++ b/xen/arch/ia64/linux-xen/smp.c	Fri Mar 30 17:18:42 2007 -0600
    87.3 @@ -148,7 +148,7 @@ handle_IPI (int irq, void *dev_id, struc
    87.4  	unsigned long ops;
    87.5  
    87.6  #ifdef XEN
    87.7 -	perfc_incrc(ipis);
    87.8 +	perfc_incr(ipis);
    87.9  #endif
   87.10  	mb();	/* Order interrupt and bit testing. */
   87.11  	while ((ops = xchg(pending_ipis, 0)) != 0) {
    88.1 --- a/xen/arch/ia64/vmx/pal_emul.c	Fri Mar 30 10:27:15 2007 -0600
    88.2 +++ b/xen/arch/ia64/vmx/pal_emul.c	Fri Mar 30 17:18:42 2007 -0600
    88.3 @@ -37,7 +37,7 @@ pal_emul(struct vcpu *vcpu)
    88.4  	vcpu_get_gr_nat(vcpu, 30, &gr30); 
    88.5  	vcpu_get_gr_nat(vcpu, 31, &gr31);
    88.6  
    88.7 -	perfc_incrc(vmx_pal_emul);
    88.8 +	perfc_incr(vmx_pal_emul);
    88.9  	result = xen_pal_emulator(gr28, gr29, gr30, gr31);
   88.10  
   88.11  	vcpu_set_gr(vcpu, 8, result.status, 0);
    89.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Fri Mar 30 10:27:15 2007 -0600
    89.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Fri Mar 30 17:18:42 2007 -0600
    89.3 @@ -692,8 +692,8 @@ static void vlsapic_write_ipi(VCPU *vcpu
    89.4      if (targ == NULL)
    89.5          panic_domain(NULL, "Unknown IPI cpu\n");
    89.6  
    89.7 -    if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags) ||
    89.8 -        test_bit(_VCPUF_down, &targ->vcpu_flags)) {
    89.9 +    if (!targ->is_initialised ||
   89.10 +        test_bit(_VPF_down, &targ->pause_flags)) {
   89.11  
   89.12          struct pt_regs *targ_regs = vcpu_regs(targ);
   89.13          struct vcpu_guest_context c;
   89.14 @@ -709,7 +709,7 @@ static void vlsapic_write_ipi(VCPU *vcpu
   89.15          targ_regs->cr_iip = d->arch.sal_data->boot_rdv_ip;
   89.16          targ_regs->r1 = d->arch.sal_data->boot_rdv_r1;
   89.17  
   89.18 -        if (test_and_clear_bit(_VCPUF_down,&targ->vcpu_flags)) {
   89.19 +        if (test_and_clear_bit(_VPF_down,&targ->pause_flags)) {
   89.20              vcpu_wake(targ);
   89.21              printk(XENLOG_DEBUG "arch_boot_vcpu: vcpu %d awaken %016lx!\n",
   89.22                     targ->vcpu_id, targ_regs->cr_iip);
   89.23 @@ -717,7 +717,7 @@ static void vlsapic_write_ipi(VCPU *vcpu
   89.24              printk("arch_boot_vcpu: huh, already awake!");
   89.25          }
   89.26      } else {
   89.27 -        int running = test_bit(_VCPUF_running, &targ->vcpu_flags);
   89.28 +        int running = targ->is_running;
   89.29          vlsapic_deliver_ipi(targ, ((ipi_d_t)value).dm, 
   89.30                              ((ipi_d_t)value).vector);
   89.31          vcpu_unblock(targ);
    90.1 --- a/xen/arch/ia64/vmx/vmmu.c	Fri Mar 30 10:27:15 2007 -0600
    90.2 +++ b/xen/arch/ia64/vmx/vmmu.c	Fri Mar 30 17:18:42 2007 -0600
    90.3 @@ -598,7 +598,7 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u6
    90.4      vcpu_get_rr(vcpu, va, &args.rid);
    90.5      args.ps = ps;
    90.6      for_each_vcpu (d, v) {
    90.7 -        if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
    90.8 +        if (!v->is_initialised)
    90.9              continue;
   90.10  
   90.11          args.vcpu = v;
    91.1 --- a/xen/arch/ia64/vmx/vmx_process.c	Fri Mar 30 10:27:15 2007 -0600
    91.2 +++ b/xen/arch/ia64/vmx/vmx_process.c	Fri Mar 30 17:18:42 2007 -0600
    91.3 @@ -151,7 +151,7 @@ vmx_ia64_handle_break (unsigned long ifa
    91.4      struct domain *d = current->domain;
    91.5      struct vcpu *v = current;
    91.6  
    91.7 -    perfc_incrc(vmx_ia64_handle_break);
    91.8 +    perfc_incr(vmx_ia64_handle_break);
    91.9  #ifdef CRASH_DEBUG
   91.10      if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
   91.11          IS_VMM_ADDRESS(regs->cr_iip)) {
    92.1 --- a/xen/arch/ia64/vmx/vmx_support.c	Fri Mar 30 10:27:15 2007 -0600
    92.2 +++ b/xen/arch/ia64/vmx/vmx_support.c	Fri Mar 30 17:18:42 2007 -0600
    92.3 @@ -82,12 +82,12 @@ void vmx_send_assist_req(struct vcpu *v)
    92.4              p->state != STATE_IOREQ_INPROCESS)
    92.5              break;
    92.6  
    92.7 -        set_bit(_VCPUF_blocked_in_xen, &current->vcpu_flags);
    92.8 +        set_bit(_VPF_blocked_in_xen, &current->pause_flags);
    92.9          mb(); /* set blocked status /then/ re-evaluate condition */
   92.10          if (p->state != STATE_IOREQ_READY &&
   92.11              p->state != STATE_IOREQ_INPROCESS)
   92.12          {
   92.13 -            clear_bit(_VCPUF_blocked_in_xen, &current->vcpu_flags);
   92.14 +            clear_bit(_VPF_blocked_in_xen, &current->pause_flags);
   92.15              break;
   92.16          }
   92.17  
    93.1 --- a/xen/arch/ia64/vmx/vmx_virt.c	Fri Mar 30 10:27:15 2007 -0600
    93.2 +++ b/xen/arch/ia64/vmx/vmx_virt.c	Fri Mar 30 17:18:42 2007 -0600
    93.3 @@ -1401,159 +1401,159 @@ if ( (cause == 0xff && opcode == 0x1e000
    93.4  
    93.5      switch(cause) {
    93.6      case EVENT_RSM:
    93.7 -        perfc_incrc(vmx_rsm);
    93.8 +        perfc_incr(vmx_rsm);
    93.9          status=vmx_emul_rsm(vcpu, inst);
   93.10          break;
   93.11      case EVENT_SSM:
   93.12 -        perfc_incrc(vmx_ssm);
   93.13 +        perfc_incr(vmx_ssm);
   93.14          status=vmx_emul_ssm(vcpu, inst);
   93.15          break;
   93.16      case EVENT_MOV_TO_PSR:
   93.17 -        perfc_incrc(vmx_mov_to_psr);
   93.18 +        perfc_incr(vmx_mov_to_psr);
   93.19          status=vmx_emul_mov_to_psr(vcpu, inst);
   93.20          break;
   93.21      case EVENT_MOV_FROM_PSR:
   93.22 -        perfc_incrc(vmx_mov_from_psr);
   93.23 +        perfc_incr(vmx_mov_from_psr);
   93.24          status=vmx_emul_mov_from_psr(vcpu, inst);
   93.25          break;
   93.26      case EVENT_MOV_FROM_CR:
   93.27 -        perfc_incrc(vmx_mov_from_cr);
   93.28 +        perfc_incr(vmx_mov_from_cr);
   93.29          status=vmx_emul_mov_from_cr(vcpu, inst);
   93.30          break;
   93.31      case EVENT_MOV_TO_CR:
   93.32 -        perfc_incrc(vmx_mov_to_cr);
   93.33 +        perfc_incr(vmx_mov_to_cr);
   93.34          status=vmx_emul_mov_to_cr(vcpu, inst);
   93.35          break;
   93.36      case EVENT_BSW_0:
   93.37 -        perfc_incrc(vmx_bsw0);
   93.38 +        perfc_incr(vmx_bsw0);
   93.39          status=vmx_emul_bsw0(vcpu, inst);
   93.40          break;
   93.41      case EVENT_BSW_1:
   93.42 -        perfc_incrc(vmx_bsw1);
   93.43 +        perfc_incr(vmx_bsw1);
   93.44          status=vmx_emul_bsw1(vcpu, inst);
   93.45          break;
   93.46      case EVENT_COVER:
   93.47 -        perfc_incrc(vmx_cover);
   93.48 +        perfc_incr(vmx_cover);
   93.49          status=vmx_emul_cover(vcpu, inst);
   93.50          break;
   93.51      case EVENT_RFI:
   93.52 -        perfc_incrc(vmx_rfi);
   93.53 +        perfc_incr(vmx_rfi);
   93.54          status=vmx_emul_rfi(vcpu, inst);
   93.55          break;
   93.56      case EVENT_ITR_D:
   93.57 -        perfc_incrc(vmx_itr_d);
   93.58 +        perfc_incr(vmx_itr_d);
   93.59          status=vmx_emul_itr_d(vcpu, inst);
   93.60          break;
   93.61      case EVENT_ITR_I:
   93.62 -        perfc_incrc(vmx_itr_i);
   93.63 +        perfc_incr(vmx_itr_i);
   93.64          status=vmx_emul_itr_i(vcpu, inst);
   93.65          break;
   93.66      case EVENT_PTR_D:
   93.67 -        perfc_incrc(vmx_ptr_d);
   93.68 +        perfc_incr(vmx_ptr_d);
   93.69          status=vmx_emul_ptr_d(vcpu, inst);
   93.70          break;
   93.71      case EVENT_PTR_I:
   93.72 -        perfc_incrc(vmx_ptr_i);
   93.73 +        perfc_incr(vmx_ptr_i);
   93.74          status=vmx_emul_ptr_i(vcpu, inst);
   93.75          break;
   93.76      case EVENT_ITC_D:
   93.77 -        perfc_incrc(vmx_itc_d);
   93.78 +        perfc_incr(vmx_itc_d);
   93.79          status=vmx_emul_itc_d(vcpu, inst);
   93.80          break;
   93.81      case EVENT_ITC_I:
   93.82 -        perfc_incrc(vmx_itc_i);
   93.83 +        perfc_incr(vmx_itc_i);
   93.84          status=vmx_emul_itc_i(vcpu, inst);
   93.85          break;
   93.86      case EVENT_PTC_L:
   93.87 -        perfc_incrc(vmx_ptc_l);
   93.88 +        perfc_incr(vmx_ptc_l);
   93.89          status=vmx_emul_ptc_l(vcpu, inst);
   93.90          break;
   93.91      case EVENT_PTC_G:
   93.92 -        perfc_incrc(vmx_ptc_g);
   93.93 +        perfc_incr(vmx_ptc_g);
   93.94          status=vmx_emul_ptc_g(vcpu, inst);
   93.95          break;
   93.96      case EVENT_PTC_GA:
   93.97 -        perfc_incrc(vmx_ptc_ga);
   93.98 +        perfc_incr(vmx_ptc_ga);
   93.99          status=vmx_emul_ptc_ga(vcpu, inst);
  93.100          break;
  93.101      case EVENT_PTC_E:
  93.102 -        perfc_incrc(vmx_ptc_e);
  93.103 +        perfc_incr(vmx_ptc_e);
  93.104          status=vmx_emul_ptc_e(vcpu, inst);
  93.105          break;
  93.106      case EVENT_MOV_TO_RR:
  93.107 -        perfc_incrc(vmx_mov_to_rr);
  93.108 +        perfc_incr(vmx_mov_to_rr);
  93.109          status=vmx_emul_mov_to_rr(vcpu, inst);
  93.110          break;
  93.111      case EVENT_MOV_FROM_RR:
  93.112 -        perfc_incrc(vmx_mov_from_rr);
  93.113 +        perfc_incr(vmx_mov_from_rr);
  93.114          status=vmx_emul_mov_from_rr(vcpu, inst);
  93.115          break;
  93.116      case EVENT_THASH:
  93.117 -        perfc_incrc(vmx_thash);
  93.118 +        perfc_incr(vmx_thash);
  93.119          status=vmx_emul_thash(vcpu, inst);
  93.120          break;
  93.121      case EVENT_TTAG:
  93.122 -        perfc_incrc(vmx_ttag);
  93.123 +        perfc_incr(vmx_ttag);
  93.124          status=vmx_emul_ttag(vcpu, inst);
  93.125          break;
  93.126      case EVENT_TPA:
  93.127 -        perfc_incrc(vmx_tpa);
  93.128 +        perfc_incr(vmx_tpa);
  93.129          status=vmx_emul_tpa(vcpu, inst);
  93.130          break;
  93.131      case EVENT_TAK:
  93.132 -        perfc_incrc(vmx_tak);
  93.133 +        perfc_incr(vmx_tak);
  93.134          status=vmx_emul_tak(vcpu, inst);
  93.135          break;
  93.136      case EVENT_MOV_TO_AR_IMM:
  93.137 -        perfc_incrc(vmx_mov_to_ar_imm);
  93.138 +        perfc_incr(vmx_mov_to_ar_imm);
  93.139          status=vmx_emul_mov_to_ar_imm(vcpu, inst);
  93.140          break;
  93.141      case EVENT_MOV_TO_AR:
  93.142 -        perfc_incrc(vmx_mov_to_ar_reg);
  93.143 +        perfc_incr(vmx_mov_to_ar_reg);
  93.144          status=vmx_emul_mov_to_ar_reg(vcpu, inst);
  93.145          break;
  93.146      case EVENT_MOV_FROM_AR:
  93.147 -        perfc_incrc(vmx_mov_from_ar_reg);
  93.148 +        perfc_incr(vmx_mov_from_ar_reg);
  93.149          status=vmx_emul_mov_from_ar_reg(vcpu, inst);
  93.150          break;
  93.151      case EVENT_MOV_TO_DBR:
  93.152 -        perfc_incrc(vmx_mov_to_dbr);
  93.153 +        perfc_incr(vmx_mov_to_dbr);
  93.154          status=vmx_emul_mov_to_dbr(vcpu, inst);
  93.155          break;
  93.156      case EVENT_MOV_TO_IBR:
  93.157 -        perfc_incrc(vmx_mov_to_ibr);
  93.158 +        perfc_incr(vmx_mov_to_ibr);
  93.159          status=vmx_emul_mov_to_ibr(vcpu, inst);
  93.160          break;
  93.161      case EVENT_MOV_TO_PMC:
  93.162 -        perfc_incrc(vmx_mov_to_pmc);
  93.163 +        perfc_incr(vmx_mov_to_pmc);
  93.164          status=vmx_emul_mov_to_pmc(vcpu, inst);
  93.165          break;
  93.166      case EVENT_MOV_TO_PMD:
  93.167 -        perfc_incrc(vmx_mov_to_pmd);
  93.168 +        perfc_incr(vmx_mov_to_pmd);
  93.169          status=vmx_emul_mov_to_pmd(vcpu, inst);
  93.170          break;
  93.171      case EVENT_MOV_TO_PKR:
  93.172 -        perfc_incrc(vmx_mov_to_pkr);
  93.173 +        perfc_incr(vmx_mov_to_pkr);
  93.174          status=vmx_emul_mov_to_pkr(vcpu, inst);
  93.175          break;
  93.176      case EVENT_MOV_FROM_DBR:
  93.177 -        perfc_incrc(vmx_mov_from_dbr);
  93.178 +        perfc_incr(vmx_mov_from_dbr);
  93.179          status=vmx_emul_mov_from_dbr(vcpu, inst);
  93.180          break;
  93.181      case EVENT_MOV_FROM_IBR:
  93.182 -        perfc_incrc(vmx_mov_from_ibr);
  93.183 +        perfc_incr(vmx_mov_from_ibr);
  93.184          status=vmx_emul_mov_from_ibr(vcpu, inst);
  93.185          break;
  93.186      case EVENT_MOV_FROM_PMC:
  93.187 -        perfc_incrc(vmx_mov_from_pmc);
  93.188 +        perfc_incr(vmx_mov_from_pmc);
  93.189          status=vmx_emul_mov_from_pmc(vcpu, inst);
  93.190          break;
  93.191      case EVENT_MOV_FROM_PKR:
  93.192 -        perfc_incrc(vmx_mov_from_pkr);
  93.193 +        perfc_incr(vmx_mov_from_pkr);
  93.194          status=vmx_emul_mov_from_pkr(vcpu, inst);
  93.195          break;
  93.196      case EVENT_MOV_FROM_CPUID:
  93.197 -        perfc_incrc(vmx_mov_from_cpuid);
  93.198 +        perfc_incr(vmx_mov_from_cpuid);
  93.199          status=vmx_emul_mov_from_cpuid(vcpu, inst);
  93.200          break;
  93.201      case EVENT_VMSW:
    94.1 --- a/xen/arch/ia64/xen/dom0_ops.c	Fri Mar 30 10:27:15 2007 -0600
    94.2 +++ b/xen/arch/ia64/xen/dom0_ops.c	Fri Mar 30 17:18:42 2007 -0600
    94.3 @@ -372,7 +372,7 @@ do_dom0vp_op(unsigned long cmd,
    94.4          } else {
    94.5              ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
    94.6          }
    94.7 -        perfc_incrc(dom0vp_phystomach);
    94.8 +        perfc_incr(dom0vp_phystomach);
    94.9          break;
   94.10      case IA64_DOM0VP_machtophys:
   94.11          if (!mfn_valid(arg0)) {
   94.12 @@ -380,7 +380,7 @@ do_dom0vp_op(unsigned long cmd,
   94.13              break;
   94.14          }
   94.15          ret = get_gpfn_from_mfn(arg0);
   94.16 -        perfc_incrc(dom0vp_machtophys);
   94.17 +        perfc_incr(dom0vp_machtophys);
   94.18          break;
   94.19      case IA64_DOM0VP_zap_physmap:
   94.20          ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
    95.1 --- a/xen/arch/ia64/xen/domain.c	Fri Mar 30 10:27:15 2007 -0600
    95.2 +++ b/xen/arch/ia64/xen/domain.c	Fri Mar 30 17:18:42 2007 -0600
    95.3 @@ -131,11 +131,11 @@ static void flush_vtlb_for_context_switc
    95.4  		if (vhpt_is_flushed || NEED_FLUSH(__get_cpu_var(tlbflush_time),
    95.5  		                                  last_tlbflush_timestamp)) {
    95.6  			local_flush_tlb_all();
    95.7 -			perfc_incrc(tlbflush_clock_cswitch_purge);
    95.8 +			perfc_incr(tlbflush_clock_cswitch_purge);
    95.9  		} else {
   95.10 -			perfc_incrc(tlbflush_clock_cswitch_skip);
   95.11 +			perfc_incr(tlbflush_clock_cswitch_skip);
   95.12  		}
   95.13 -		perfc_incrc(flush_vtlb_for_context_switch);
   95.14 +		perfc_incr(flush_vtlb_for_context_switch);
   95.15  	}
   95.16  }
   95.17  
   95.18 @@ -658,7 +658,7 @@ int arch_set_info_guest(struct vcpu *v, 
   95.19  		v->arch.iva = er->iva;
   95.20  	}
   95.21  
   95.22 -	if (test_bit(_VCPUF_initialised, &v->vcpu_flags))
   95.23 +	if (v->is_initialised)
   95.24  		return 0;
   95.25  
   95.26  	if (d->arch.is_vti) {
   95.27 @@ -677,10 +677,12 @@ int arch_set_info_guest(struct vcpu *v, 
   95.28  	/* This overrides some registers. */
   95.29  	vcpu_init_regs(v);
   95.30  
   95.31 -	/* Don't redo final setup. Auto-online VCPU0. */
   95.32 -	if (!test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
   95.33 -	    (v->vcpu_id == 0))
   95.34 -		clear_bit(_VCPUF_down, &v->vcpu_flags);
   95.35 +	if (!v->is_initialised) {
   95.36 +		v->is_initialised = 1;
   95.37 +		/* Auto-online VCPU0 when it is initialised. */
   95.38 +		if (v->vcpu_id == 0)
   95.39 +			clear_bit(_VPF_down, &v->pause_flags);
   95.40 +	}
   95.41  
   95.42  	return 0;
   95.43  }
   95.44 @@ -1068,7 +1070,7 @@ int construct_dom0(struct domain *d,
   95.45  	/* Sanity! */
   95.46  	BUG_ON(d != dom0);
   95.47  	BUG_ON(d->vcpu[0] == NULL);
   95.48 -	BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
   95.49 +	BUG_ON(v->is_initialised);
   95.50  
   95.51  	printk("*** LOADING DOMAIN 0 ***\n");
   95.52  
   95.53 @@ -1189,8 +1191,8 @@ int construct_dom0(struct domain *d,
   95.54  
   95.55  	printk("Dom0: 0x%lx\n", (u64)dom0);
   95.56  
   95.57 -	set_bit(_VCPUF_initialised, &v->vcpu_flags);
   95.58 -	clear_bit(_VCPUF_down, &v->vcpu_flags);
   95.59 +	v->is_initialised = 1;
   95.60 +	clear_bit(_VPF_down, &v->pause_flags);
   95.61  
   95.62  	/* Build firmware.
   95.63  	   Note: Linux kernel reserve memory used by start_info, so there is
    96.1 --- a/xen/arch/ia64/xen/faults.c	Fri Mar 30 10:27:15 2007 -0600
    96.2 +++ b/xen/arch/ia64/xen/faults.c	Fri Mar 30 17:18:42 2007 -0600
    96.3 @@ -187,7 +187,7 @@ static int handle_lazy_cover(struct vcpu
    96.4  	if (!PSCB(v, interrupt_collection_enabled)) {
    96.5  		PSCB(v, ifs) = regs->cr_ifs;
    96.6  		regs->cr_ifs = 0;
    96.7 -		perfc_incrc(lazy_cover);
    96.8 +		perfc_incr(lazy_cover);
    96.9  		return 1;	// retry same instruction with cr.ifs off
   96.10  	}
   96.11  	return 0;
    97.1 --- a/xen/arch/ia64/xen/fw_emul.c	Fri Mar 30 10:27:15 2007 -0600
    97.2 +++ b/xen/arch/ia64/xen/fw_emul.c	Fri Mar 30 17:18:42 2007 -0600
    97.3 @@ -374,7 +374,7 @@ sal_emulator (long index, unsigned long 
    97.4  		printk("*** CALLED SAL_UPDATE_PAL.  IGNORED...\n");
    97.5  		break;
    97.6  	    case SAL_XEN_SAL_RETURN:
    97.7 -	        if (!test_and_set_bit(_VCPUF_down, &current->vcpu_flags))
    97.8 +	        if (!test_and_set_bit(_VPF_down, &current->pause_flags))
    97.9  			vcpu_sleep_nosync(current);
   97.10  		break;
   97.11  	    case SN_SAL_GET_MASTER_NASID:
   97.12 @@ -725,7 +725,7 @@ xen_pal_emulator(unsigned long index, u6
   97.13  			console_start_sync();
   97.14  			(*efi.reset_system)(EFI_RESET_SHUTDOWN,0,0,NULL);
   97.15  		} else {
   97.16 -			set_bit(_VCPUF_down, &current->vcpu_flags);
   97.17 +			set_bit(_VPF_down, &current->pause_flags);
   97.18  			vcpu_sleep_nosync(current);
   97.19  			status = PAL_STATUS_SUCCESS;
   97.20  		}
    98.1 --- a/xen/arch/ia64/xen/hypercall.c	Fri Mar 30 10:27:15 2007 -0600
    98.2 +++ b/xen/arch/ia64/xen/hypercall.c	Fri Mar 30 17:18:42 2007 -0600
    98.3 @@ -81,11 +81,11 @@ fw_hypercall_ipi (struct pt_regs *regs)
    98.4  		return;
    98.5  
    98.6    	if (vector == XEN_SAL_BOOT_RENDEZ_VEC
    98.7 -	    && (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)
    98.8 -		|| test_bit(_VCPUF_down, &targ->vcpu_flags))) {
    98.9 +	    && (!targ->is_initialised
   98.10 +		|| test_bit(_VPF_down, &targ->pause_flags))) {
   98.11  
   98.12  		/* First start: initialize vpcu.  */
   98.13 -		if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
   98.14 +		if (!targ->is_initialised) {
   98.15  			struct vcpu_guest_context c;
   98.16  		
   98.17  			memset (&c, 0, sizeof (c));
   98.18 @@ -102,8 +102,8 @@ fw_hypercall_ipi (struct pt_regs *regs)
   98.19  		vcpu_regs (targ)->r1 = d->arch.sal_data->boot_rdv_r1;
   98.20  		vcpu_regs (targ)->b0 = FW_HYPERCALL_SAL_RETURN_PADDR;
   98.21  
   98.22 -		if (test_and_clear_bit(_VCPUF_down,
   98.23 -				       &targ->vcpu_flags)) {
   98.24 +		if (test_and_clear_bit(_VPF_down,
   98.25 +				       &targ->pause_flags)) {
   98.26  			vcpu_wake(targ);
   98.27  			printk(XENLOG_INFO "arch_boot_vcpu: vcpu %d awaken\n",
   98.28  			       targ->vcpu_id);
   98.29 @@ -112,9 +112,7 @@ fw_hypercall_ipi (struct pt_regs *regs)
   98.30  			printk ("arch_boot_vcpu: huu, already awaken!\n");
   98.31  	}
   98.32  	else {
   98.33 -		int running = test_bit(_VCPUF_running,
   98.34 -				       &targ->vcpu_flags);
   98.35 -		
   98.36 +		int running = targ->is_running;
   98.37  		vcpu_pend_interrupt(targ, vector);
   98.38  		vcpu_unblock(targ);
   98.39  		if (running)
   98.40 @@ -161,7 +159,7 @@ ia64_hypercall(struct pt_regs *regs)
   98.41  		if (regs->r28 == PAL_HALT_LIGHT) {
   98.42  			if (vcpu_deliverable_interrupts(v) ||
   98.43  				event_pending(v)) {
   98.44 -				perfc_incrc(idle_when_pending);
   98.45 +				perfc_incr(idle_when_pending);
   98.46  				vcpu_pend_unspecified_interrupt(v);
   98.47  //printk("idle w/int#%d pending!\n",pi);
   98.48  //this shouldn't happen, but it apparently does quite a bit!  so don't
   98.49 @@ -170,7 +168,7 @@ ia64_hypercall(struct pt_regs *regs)
   98.50  //as deliver_pending_interrupt is called on the way out and will deliver it
   98.51  			}
   98.52  			else {
   98.53 -				perfc_incrc(pal_halt_light);
   98.54 +				perfc_incr(pal_halt_light);
   98.55  				migrate_timer(&v->arch.hlt_timer,
   98.56  				              v->processor);
   98.57  				set_timer(&v->arch.hlt_timer,
   98.58 @@ -209,7 +207,7 @@ ia64_hypercall(struct pt_regs *regs)
   98.59  		regs->r10 = x.r10; regs->r11 = x.r11;
   98.60  		break;
   98.61  	case FW_HYPERCALL_SAL_RETURN:
   98.62 -	        if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
   98.63 +	        if ( !test_and_set_bit(_VPF_down, &v->pause_flags) )
   98.64  			vcpu_sleep_nosync(v);
   98.65  		break;
   98.66  	case FW_HYPERCALL_EFI_CALL:
    99.1 --- a/xen/arch/ia64/xen/hyperprivop.S	Fri Mar 30 10:27:15 2007 -0600
    99.2 +++ b/xen/arch/ia64/xen/hyperprivop.S	Fri Mar 30 17:18:42 2007 -0600
    99.3 @@ -26,8 +26,7 @@
    99.4  # define FAST_HYPERPRIVOPS
    99.5  # ifdef PERF_COUNTERS
    99.6  #  define FAST_HYPERPRIVOP_CNT
    99.7 -#  define FAST_HYPERPRIVOP_PERFC(N) \
    99.8 -	(perfcounters + FAST_HYPERPRIVOP_PERFC_OFS + (4 * N))
    99.9 +#  define FAST_HYPERPRIVOP_PERFC(N) PERFC(fast_hyperprivop + N)
   99.10  #  define FAST_REFLECT_CNT
   99.11  # endif
   99.12  	
   99.13 @@ -364,7 +363,7 @@ GLOBAL_ENTRY(fast_tick_reflect)
   99.14  	mov rp=r29;;
   99.15  	mov cr.itm=r26;;	// ensure next tick
   99.16  #ifdef FAST_REFLECT_CNT
   99.17 -	movl r20=perfcounters+FAST_REFLECT_PERFC_OFS+((0x3000>>8)*4);;
   99.18 +	movl r20=PERFC(fast_reflect + (0x3000>>8));;
   99.19  	ld4 r21=[r20];;
   99.20  	adds r21=1,r21;;
   99.21  	st4 [r20]=r21;;
   99.22 @@ -597,7 +596,7 @@ END(fast_break_reflect)
   99.23  //	r31 == pr
   99.24  ENTRY(fast_reflect)
   99.25  #ifdef FAST_REFLECT_CNT
   99.26 -	movl r22=perfcounters+FAST_REFLECT_PERFC_OFS;
   99.27 +	movl r22=PERFC(fast_reflect);
   99.28  	shr r23=r20,8-2;;
   99.29  	add r22=r22,r23;;
   99.30  	ld4 r21=[r22];;
   99.31 @@ -938,7 +937,7 @@ 1:	// check the guest VHPT
   99.32  (p7)	br.cond.spnt.few page_not_present;;
   99.33  
   99.34  #ifdef FAST_REFLECT_CNT
   99.35 -	movl r21=perfcounter+FAST_VHPT_TRANSLATE_PERFC_OFS;;
   99.36 +	movl r21=PERFC(fast_vhpt_translate);;
   99.37  	ld4 r22=[r21];;
   99.38  	adds r22=1,r22;;
   99.39  	st4 [r21]=r22;;
   99.40 @@ -968,7 +967,7 @@ END(fast_tlb_miss_reflect)
   99.41  // we get here if fast_insert fails (e.g. due to metaphysical lookup)
   99.42  ENTRY(recover_and_page_fault)
   99.43  #ifdef PERF_COUNTERS
   99.44 -	movl r21=perfcounters + RECOVER_TO_PAGE_FAULT_PERFC_OFS;;
   99.45 +	movl r21=PERFC(recover_to_page_fault);;
   99.46  	ld4 r22=[r21];;
   99.47  	adds r22=1,r22;;
   99.48  	st4 [r21]=r22;;
   99.49 @@ -1832,7 +1831,7 @@ END(hyper_ptc_ga)
   99.50  // recovery block for hyper_itc metaphysical memory lookup
   99.51  ENTRY(recover_and_dispatch_break_fault)
   99.52  #ifdef PERF_COUNTERS
   99.53 -	movl r21=perfcounters + RECOVER_TO_BREAK_FAULT_PERFC_OFS;;
   99.54 +	movl r21=PERFC(recover_to_break_fault);;
   99.55  	ld4 r22=[r21];;
   99.56  	adds r22=1,r22;;
   99.57  	st4 [r21]=r22;;
   100.1 --- a/xen/arch/ia64/xen/mm.c	Fri Mar 30 10:27:15 2007 -0600
   100.2 +++ b/xen/arch/ia64/xen/mm.c	Fri Mar 30 17:18:42 2007 -0600
   100.3 @@ -400,7 +400,7 @@ share_xen_page_with_guest(struct page_in
   100.4      ASSERT(page->count_info == 0);
   100.5  
   100.6      /* Only add to the allocation list if the domain isn't dying. */
   100.7 -    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
   100.8 +    if ( !d->is_dying )
   100.9      {
  100.10          page->count_info |= PGC_allocated | 1;
  100.11          if ( unlikely(d->xenheap_pages++ == 0) )
  100.12 @@ -1131,7 +1131,7 @@ assign_domain_page_replace(struct domain
  100.13              domain_put_page(d, mpaddr, pte, old_pte, 1);
  100.14          }
  100.15      }
  100.16 -    perfc_incrc(assign_domain_page_replace);
  100.17 +    perfc_incr(assign_domain_page_replace);
  100.18  }
  100.19  
  100.20  // caller must get_page(new_page) before
  100.21 @@ -1207,7 +1207,7 @@ assign_domain_page_cmpxchg_rel(struct do
  100.22      }
  100.23  
  100.24      domain_page_flush_and_put(d, mpaddr, pte, old_pte, old_page);
  100.25 -    perfc_incrc(assign_domain_pge_cmpxchg_rel);
  100.26 +    perfc_incr(assign_domain_pge_cmpxchg_rel);
  100.27      return 0;
  100.28  }
  100.29  
  100.30 @@ -1266,7 +1266,7 @@ zap_domain_page_one(struct domain *d, un
  100.31  
  100.32      BUG_ON(clear_PGC_allocate && (page_get_owner(page) == NULL));
  100.33      domain_put_page(d, mpaddr, pte, old_pte, clear_PGC_allocate);
  100.34 -    perfc_incrc(zap_dcomain_page_one);
  100.35 +    perfc_incr(zap_dcomain_page_one);
  100.36  }
  100.37  
  100.38  unsigned long
  100.39 @@ -1279,7 +1279,7 @@ dom0vp_zap_physmap(struct domain *d, uns
  100.40      }
  100.41  
  100.42      zap_domain_page_one(d, gpfn << PAGE_SHIFT, 1, INVALID_MFN);
  100.43 -    perfc_incrc(dom0vp_zap_physmap);
  100.44 +    perfc_incr(dom0vp_zap_physmap);
  100.45      return 0;
  100.46  }
  100.47  
  100.48 @@ -1333,7 +1333,7 @@ static unsigned long
  100.49             get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
  100.50      assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags);
  100.51      //don't update p2m table because this page belongs to rd, not d.
  100.52 -    perfc_incrc(dom0vp_add_physmap);
  100.53 +    perfc_incr(dom0vp_add_physmap);
  100.54  out1:
  100.55      put_domain(rd);
  100.56      return error;
  100.57 @@ -1503,7 +1503,7 @@ create_grant_host_mapping(unsigned long 
  100.58  #endif
  100.59                                 ((flags & GNTMAP_readonly) ?
  100.60                                  ASSIGN_readonly : ASSIGN_writable));
  100.61 -    perfc_incrc(create_grant_host_mapping);
  100.62 +    perfc_incr(create_grant_host_mapping);
  100.63      return GNTST_okay;
  100.64  }
  100.65  
  100.66 @@ -1568,7 +1568,7 @@ destroy_grant_host_mapping(unsigned long
  100.67      BUG_ON(pte_pgc_allocated(old_pte));
  100.68      domain_page_flush_and_put(d, gpaddr, pte, old_pte, page);
  100.69  
  100.70 -    perfc_incrc(destroy_grant_host_mapping);
  100.71 +    perfc_incr(destroy_grant_host_mapping);
  100.72      return GNTST_okay;
  100.73  }
  100.74  
  100.75 @@ -1629,7 +1629,7 @@ steal_page(struct domain *d, struct page
  100.76              free_domheap_page(new);
  100.77              return -1;
  100.78          }
  100.79 -        perfc_incrc(steal_page_refcount);
  100.80 +        perfc_incr(steal_page_refcount);
  100.81      }
  100.82  
  100.83      spin_lock(&d->page_alloc_lock);
  100.84 @@ -1693,7 +1693,7 @@ steal_page(struct domain *d, struct page
  100.85      list_del(&page->list);
  100.86  
  100.87      spin_unlock(&d->page_alloc_lock);
  100.88 -    perfc_incrc(steal_page);
  100.89 +    perfc_incr(steal_page);
  100.90      return 0;
  100.91  }
  100.92  
  100.93 @@ -1710,7 +1710,7 @@ guest_physmap_add_page(struct domain *d,
  100.94  
  100.95      //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT));
  100.96  
  100.97 -    perfc_incrc(guest_physmap_add_page);
  100.98 +    perfc_incr(guest_physmap_add_page);
  100.99  }
 100.100  
 100.101  void
 100.102 @@ -1719,7 +1719,7 @@ guest_physmap_remove_page(struct domain 
 100.103  {
 100.104      BUG_ON(mfn == 0);//XXX
 100.105      zap_domain_page_one(d, gpfn << PAGE_SHIFT, 0, mfn);
 100.106 -    perfc_incrc(guest_physmap_remove_page);
 100.107 +    perfc_incr(guest_physmap_remove_page);
 100.108  }
 100.109  
 100.110  static void
 100.111 @@ -1799,7 +1799,7 @@ domain_page_flush_and_put(struct domain*
 100.112          break;
 100.113      }
 100.114  #endif
 100.115 -    perfc_incrc(domain_page_flush_and_put);
 100.116 +    perfc_incr(domain_page_flush_and_put);
 100.117  }
 100.118  
 100.119  int
 100.120 @@ -1935,8 +1935,7 @@ void put_page_type(struct page_info *pag
 100.121           * page-table pages if we detect a referential loop.
 100.122           * See domain.c:relinquish_list().
 100.123           */
 100.124 -        ASSERT((x & PGT_validated) ||
 100.125 -               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
 100.126 +        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
 100.127  
 100.128          if ( unlikely((nx & PGT_count_mask) == 0) )
 100.129          {
 100.130 @@ -1996,7 +1995,7 @@ int get_page_type(struct page_info *page
 100.131  
 100.132                  if ( unlikely(!cpus_empty(mask)) )
 100.133                  {
 100.134 -                    perfc_incrc(need_flush_tlb_flush);
 100.135 +                    perfc_incr(need_flush_tlb_flush);
 100.136                      flush_tlb_mask(mask);
 100.137                  }
 100.138  
   101.1 --- a/xen/arch/ia64/xen/privop.c	Fri Mar 30 10:27:15 2007 -0600
   101.2 +++ b/xen/arch/ia64/xen/privop.c	Fri Mar 30 17:18:42 2007 -0600
   101.3 @@ -641,15 +641,15 @@ static IA64FAULT priv_handle_op(VCPU * v
   101.4  			if (inst.M29.x3 != 0)
   101.5  				break;
   101.6  			if (inst.M30.x4 == 8 && inst.M30.x2 == 2) {
   101.7 -				perfc_incrc(mov_to_ar_imm);
   101.8 +				perfc_incr(mov_to_ar_imm);
   101.9  				return priv_mov_to_ar_imm(vcpu, inst);
  101.10  			}
  101.11  			if (inst.M44.x4 == 6) {
  101.12 -				perfc_incrc(ssm);
  101.13 +				perfc_incr(ssm);
  101.14  				return priv_ssm(vcpu, inst);
  101.15  			}
  101.16  			if (inst.M44.x4 == 7) {
  101.17 -				perfc_incrc(rsm);
  101.18 +				perfc_incr(rsm);
  101.19  				return priv_rsm(vcpu, inst);
  101.20  			}
  101.21  			break;
  101.22 @@ -658,9 +658,9 @@ static IA64FAULT priv_handle_op(VCPU * v
  101.23  		x6 = inst.M29.x6;
  101.24  		if (x6 == 0x2a) {
  101.25  			if (privify_en && inst.M29.r2 > 63 && inst.M29.ar3 < 8)
  101.26 -				perfc_incrc(mov_from_ar); // privified mov from kr
  101.27 +				perfc_incr(mov_from_ar); // privified mov from kr
  101.28  			else
  101.29 -				perfc_incrc(mov_to_ar_reg);
  101.30 +				perfc_incr(mov_to_ar_reg);
  101.31  			return priv_mov_to_ar_reg(vcpu, inst);
  101.32  		}
  101.33  		if (inst.M29.x3 != 0)
  101.34 @@ -676,9 +676,9 @@ static IA64FAULT priv_handle_op(VCPU * v
  101.35  			}
  101.36  		}
  101.37  		if (privify_en && x6 == 52 && inst.M28.r3 > 63)
  101.38 -			perfc_incrc(fc);
  101.39 +			perfc_incr(fc);
  101.40  		else if (privify_en && x6 == 16 && inst.M43.r3 > 63)
  101.41 -			perfc_incrc(cpuid);
  101.42 +			perfc_incr(cpuid);
  101.43  		else
  101.44  			perfc_incra(misc_privop, x6);
  101.45  		return (*pfunc) (vcpu, inst);
  101.46 @@ -688,23 +688,23 @@ static IA64FAULT priv_handle_op(VCPU * v
  101.47  			break;
  101.48  		if (inst.B8.x6 == 0x08) {
  101.49  			IA64FAULT fault;
  101.50 -			perfc_incrc(rfi);
  101.51 +			perfc_incr(rfi);
  101.52  			fault = priv_rfi(vcpu, inst);
  101.53  			if (fault == IA64_NO_FAULT)
  101.54  				fault = IA64_RFI_IN_PROGRESS;
  101.55  			return fault;
  101.56  		}
  101.57  		if (inst.B8.x6 == 0x0c) {
  101.58 -			perfc_incrc(bsw0);
  101.59 +			perfc_incr(bsw0);
  101.60  			return priv_bsw0(vcpu, inst);
  101.61  		}
  101.62  		if (inst.B8.x6 == 0x0d) {
  101.63 -			perfc_incrc(bsw1);
  101.64 +			perfc_incr(bsw1);
  101.65  			return priv_bsw1(vcpu, inst);
  101.66  		}
  101.67  		if (inst.B8.x6 == 0x0) {
  101.68  			// break instr for privified cover
  101.69 -			perfc_incrc(cover);
  101.70 +			perfc_incr(cover);
  101.71  			return priv_cover(vcpu, inst);
  101.72  		}
  101.73  		break;
  101.74 @@ -713,7 +713,7 @@ static IA64FAULT priv_handle_op(VCPU * v
  101.75  			break;
  101.76  #if 0
  101.77  		if (inst.I26.x6 == 0 && inst.I26.x3 == 0) {
  101.78 -			perfc_incrc(cover);
  101.79 +			perfc_incr(cover);
  101.80  			return priv_cover(vcpu, inst);
  101.81  		}
  101.82  #endif
  101.83 @@ -721,13 +721,13 @@ static IA64FAULT priv_handle_op(VCPU * v
  101.84  			break;	// I26.x3 == I27.x3
  101.85  		if (inst.I26.x6 == 0x2a) {
  101.86  			if (privify_en && inst.I26.r2 > 63 && inst.I26.ar3 < 8)
  101.87 -				perfc_incrc(mov_from_ar);	// privified mov from kr
  101.88 +				perfc_incr(mov_from_ar);	// privified mov from kr
  101.89  			else
  101.90 -				perfc_incrc(mov_to_ar_reg);
  101.91 +				perfc_incr(mov_to_ar_reg);
  101.92  			return priv_mov_to_ar_reg(vcpu, inst);
  101.93  		}
  101.94  		if (inst.I27.x6 == 0x0a) {
  101.95 -			perfc_incrc(mov_to_ar_imm);
  101.96 +			perfc_incr(mov_to_ar_imm);
  101.97  			return priv_mov_to_ar_imm(vcpu, inst);
  101.98  		}
  101.99  		break;
   102.1 --- a/xen/arch/ia64/xen/privop_stat.c	Fri Mar 30 10:27:15 2007 -0600
   102.2 +++ b/xen/arch/ia64/xen/privop_stat.c	Fri Mar 30 17:18:42 2007 -0600
   102.3 @@ -10,48 +10,39 @@ struct privop_addr_count {
   102.4  	unsigned long addr[PRIVOP_COUNT_NADDRS];
   102.5  	unsigned int count[PRIVOP_COUNT_NADDRS];
   102.6  	unsigned int overflow;
   102.7 -	atomic_t *perfc_addr;
   102.8 -	atomic_t *perfc_count;
   102.9 -	atomic_t *perfc_overflow;
  102.10  };
  102.11  
  102.12 -#undef  PERFCOUNTER
  102.13 -#define PERFCOUNTER(var, name)
  102.14 +struct privop_addr_info {
  102.15 +	enum perfcounter perfc_addr;
  102.16 +	enum perfcounter perfc_count;
  102.17 +	enum perfcounter perfc_overflow;
  102.18 +};
  102.19  
  102.20 -#undef  PERFCOUNTER_CPU
  102.21 -#define PERFCOUNTER_CPU(var, name)
  102.22 -
  102.23 -#undef  PERFCOUNTER_ARRAY
  102.24 +#define PERFCOUNTER(var, name)
  102.25  #define PERFCOUNTER_ARRAY(var, name, size)
  102.26  
  102.27 -#undef  PERFSTATUS
  102.28  #define PERFSTATUS(var, name)
  102.29 -
  102.30 -#undef  PERFSTATUS_CPU
  102.31 -#define PERFSTATUS_CPU(var, name)
  102.32 -
  102.33 -#undef  PERFSTATUS_ARRAY
  102.34  #define PERFSTATUS_ARRAY(var, name, size)
  102.35  
  102.36 -#undef PERFPRIVOPADDR
  102.37  #define PERFPRIVOPADDR(name)                        \
  102.38      {                                               \
  102.39 -        { 0 }, { 0 }, 0,                            \
  102.40 -        perfcounters.privop_addr_##name##_addr,     \
  102.41 -        perfcounters.privop_addr_##name##_count,    \
  102.42 -        perfcounters.privop_addr_##name##_overflow  \
  102.43 +        PERFC_privop_addr_##name##_addr,            \
  102.44 +        PERFC_privop_addr_##name##_count,           \
  102.45 +        PERFC_privop_addr_##name##_overflow         \
  102.46      },
  102.47  
  102.48 -static struct privop_addr_count privop_addr_counter[] = {
  102.49 +static const struct privop_addr_info privop_addr_info[] = {
  102.50  #include <asm/perfc_defn.h>
  102.51  };
  102.52  
  102.53  #define PRIVOP_COUNT_NINSTS \
  102.54 -        (sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0]))
  102.55 +        (sizeof(privop_addr_info) / sizeof(privop_addr_info[0]))
  102.56 +
  102.57 +static DEFINE_PER_CPU(struct privop_addr_count[PRIVOP_COUNT_NINSTS], privop_addr_counter);
  102.58  
  102.59  void privop_count_addr(unsigned long iip, enum privop_inst inst)
  102.60  {
  102.61 -	struct privop_addr_count *v = &privop_addr_counter[inst];
  102.62 +	struct privop_addr_count *v = this_cpu(privop_addr_counter) + inst;
  102.63  	int i;
  102.64  
  102.65  	if (inst >= PRIVOP_COUNT_NINSTS)
  102.66 @@ -72,31 +63,44 @@ void privop_count_addr(unsigned long iip
  102.67  
  102.68  void gather_privop_addrs(void)
  102.69  {
  102.70 -	int i, j;
  102.71 -	atomic_t *v;
  102.72 -	for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
  102.73 -		/* Note: addresses are truncated!  */
  102.74 -		v = privop_addr_counter[i].perfc_addr;
  102.75 -		for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
  102.76 -			atomic_set(&v[j], privop_addr_counter[i].addr[j]);
  102.77 +	unsigned int cpu;
  102.78 +
  102.79 +	for_each_cpu ( cpu ) {
  102.80 +		perfc_t *perfcounters = per_cpu(perfcounters, cpu);
  102.81 +		struct privop_addr_count *s = per_cpu(privop_addr_counter, cpu);
  102.82 +		int i, j;
  102.83 +
  102.84 +		for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, s++) {
  102.85 +			perfc_t *d;
  102.86  
  102.87 -		v = privop_addr_counter[i].perfc_count;
  102.88 -		for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
  102.89 -			atomic_set(&v[j], privop_addr_counter[i].count[j]);
  102.90 +			/* Note: addresses are truncated!  */
  102.91 +			d = perfcounters + privop_addr_info[i].perfc_addr;
  102.92 +			for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
  102.93 +				d[j] = s->addr[j];
  102.94 +
  102.95 +			d = perfcounters + privop_addr_info[i].perfc_count;
  102.96 +			for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
  102.97 +				d[j] = s->count[j];
  102.98  		
  102.99 -		atomic_set(privop_addr_counter[i].perfc_overflow,
 102.100 -		           privop_addr_counter[i].overflow);
 102.101 +			perfcounters[privop_addr_info[i].perfc_overflow] =
 102.102 +				s->overflow;
 102.103 +		}
 102.104  	}
 102.105  }
 102.106  
 102.107  void reset_privop_addrs(void)
 102.108  {
 102.109 -	int i, j;
 102.110 -	for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
 102.111 -		struct privop_addr_count *v = &privop_addr_counter[i];
 102.112 -		for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
 102.113 -			v->addr[j] = v->count[j] = 0;
 102.114 -		v->overflow = 0;
 102.115 +	unsigned int cpu;
 102.116 +
 102.117 +	for_each_cpu ( cpu ) {
 102.118 +		struct privop_addr_count *v = per_cpu(privop_addr_counter, cpu);
 102.119 +		int i, j;
 102.120 +
 102.121 +		for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, v++) {
 102.122 +			for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
 102.123 +				v->addr[j] = v->count[j] = 0;
 102.124 +			v->overflow = 0;
 102.125 +		}
 102.126  	}
 102.127  }
 102.128  #endif
   103.1 --- a/xen/arch/ia64/xen/tlb_track.c	Fri Mar 30 10:27:15 2007 -0600
   103.2 +++ b/xen/arch/ia64/xen/tlb_track.c	Fri Mar 30 17:18:42 2007 -0600
   103.3 @@ -216,14 +216,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
   103.4      TLB_TRACK_RET_T ret = TLB_TRACK_NOT_FOUND;
   103.5  
   103.6  #if 0 /* this is done at vcpu_tlb_track_insert_or_dirty() */
   103.7 -    perfc_incrc(tlb_track_iod);
   103.8 +    perfc_incr(tlb_track_iod);
   103.9      if (!pte_tlb_tracking(old_pte)) {
  103.10 -        perfc_incrc(tlb_track_iod_not_tracked);
  103.11 +        perfc_incr(tlb_track_iod_not_tracked);
  103.12          return TLB_TRACK_NOT_TRACKED;
  103.13      }
  103.14  #endif
  103.15      if (pte_tlb_inserted_many(old_pte)) {
  103.16 -        perfc_incrc(tlb_track_iod_tracked_many);
  103.17 +        perfc_incr(tlb_track_iod_tracked_many);
  103.18          return TLB_TRACK_MANY;
  103.19      }
  103.20  
  103.21 @@ -260,7 +260,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.22              if (entry->vaddr == vaddr && entry->rid == rid) {
  103.23                  // tlb_track_printd("TLB_TRACK_FOUND\n");
  103.24                  ret = TLB_TRACK_FOUND;
  103.25 -                perfc_incrc(tlb_track_iod_found);
  103.26 +                perfc_incr(tlb_track_iod_found);
  103.27  #ifdef CONFIG_TLB_TRACK_CNT
  103.28                  entry->cnt++;
  103.29                  if (entry->cnt > TLB_TRACK_CNT_FORCE_MANY) {
  103.30 @@ -276,7 +276,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.31                       */
  103.32                       // tlb_track_entry_printf(entry);
  103.33                       // tlb_track_printd("cnt = %ld\n", entry->cnt);
  103.34 -                    perfc_incrc(tlb_track_iod_force_many);
  103.35 +                    perfc_incr(tlb_track_iod_force_many);
  103.36                      goto force_many;
  103.37                  }
  103.38  #endif
  103.39 @@ -294,14 +294,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.40                  if (pte_val(ret_pte) != pte_val(old_pte)) {
  103.41                      // tlb_track_printd("TLB_TRACK_AGAIN\n");
  103.42                      ret = TLB_TRACK_AGAIN;
  103.43 -                    perfc_incrc(tlb_track_iod_again);
  103.44 +                    perfc_incr(tlb_track_iod_again);
  103.45                  } else {
  103.46                      // tlb_track_printd("TLB_TRACK_MANY del entry 0x%p\n",
  103.47                      //                  entry);
  103.48                      ret = TLB_TRACK_MANY;
  103.49                      list_del(&entry->list);
  103.50                      // tlb_track_entry_printf(entry);
  103.51 -                    perfc_incrc(tlb_track_iod_tracked_many_del);
  103.52 +                    perfc_incr(tlb_track_iod_tracked_many_del);
  103.53                  }
  103.54                  goto out;
  103.55              }
  103.56 @@ -314,7 +314,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.57           */
  103.58          // tlb_track_printd("TLB_TRACK_AGAIN\n");
  103.59          ret = TLB_TRACK_AGAIN;
  103.60 -        perfc_incrc(tlb_track_iod_again);
  103.61 +        perfc_incr(tlb_track_iod_again);
  103.62          goto out;
  103.63      }
  103.64  
  103.65 @@ -323,7 +323,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.66          /* Other thread else removed the tlb_track_entry after we got old_pte
  103.67             before we got spin lock. */
  103.68          ret = TLB_TRACK_AGAIN;
  103.69 -        perfc_incrc(tlb_track_iod_again);
  103.70 +        perfc_incr(tlb_track_iod_again);
  103.71          goto out;
  103.72      }
  103.73      if (new_entry == NULL && bit_to_be_set == _PAGE_TLB_INSERTED) {
  103.74 @@ -334,10 +334,10 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.75              /* entry can't be allocated.
  103.76                 fall down into full flush mode. */
  103.77              bit_to_be_set |= _PAGE_TLB_INSERTED_MANY;
  103.78 -            perfc_incrc(tlb_track_iod_new_failed);
  103.79 +            perfc_incr(tlb_track_iod_new_failed);
  103.80          }
  103.81          // tlb_track_printd("new_entry 0x%p\n", new_entry);
  103.82 -        perfc_incrc(tlb_track_iod_new_entry);
  103.83 +        perfc_incr(tlb_track_iod_new_entry);
  103.84          goto again;
  103.85      }
  103.86  
  103.87 @@ -348,7 +348,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.88          if (tlb_track_pte_zapped(old_pte, ret_pte)) {
  103.89              // tlb_track_printd("zapped TLB_TRACK_AGAIN\n");
  103.90              ret = TLB_TRACK_AGAIN;
  103.91 -            perfc_incrc(tlb_track_iod_again);
  103.92 +            perfc_incr(tlb_track_iod_again);
  103.93              goto out;
  103.94          }
  103.95  
  103.96 @@ -359,7 +359,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
  103.97              // tlb_track_printd("iserted TLB_TRACK_MANY\n");
  103.98              BUG_ON(!pte_tlb_inserted(ret_pte));
  103.99              ret = TLB_TRACK_MANY;
 103.100 -            perfc_incrc(tlb_track_iod_new_many);
 103.101 +            perfc_incr(tlb_track_iod_new_many);
 103.102              goto out;
 103.103          }
 103.104          BUG_ON(pte_tlb_inserted(ret_pte));
 103.105 @@ -381,7 +381,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
 103.106  #ifdef CONFIG_TLB_TRACK_CNT
 103.107          entry->cnt = 0;
 103.108  #endif
 103.109 -        perfc_incrc(tlb_track_iod_insert);
 103.110 +        perfc_incr(tlb_track_iod_insert);
 103.111          // tlb_track_entry_printf(entry);
 103.112      } else {
 103.113          goto out;
 103.114 @@ -392,7 +392,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
 103.115      cpu_set(v->processor, entry->pcpu_dirty_mask);
 103.116      BUG_ON(v->vcpu_id >= NR_CPUS);
 103.117      vcpu_set(v->vcpu_id, entry->vcpu_dirty_mask);
 103.118 -    perfc_incrc(tlb_track_iod_dirtied);
 103.119 +    perfc_incr(tlb_track_iod_dirtied);
 103.120  
 103.121   out:
 103.122      spin_unlock(&tlb_track->hash_lock);
 103.123 @@ -432,19 +432,19 @@ tlb_track_search_and_remove(struct tlb_t
 103.124      struct list_head* head = tlb_track_hash_head(tlb_track, ptep);
 103.125      struct tlb_track_entry* entry;
 103.126  
 103.127 -    perfc_incrc(tlb_track_sar);
 103.128 +    perfc_incr(tlb_track_sar);
 103.129      if (!pte_tlb_tracking(old_pte)) {
 103.130 -        perfc_incrc(tlb_track_sar_not_tracked);
 103.131 +        perfc_incr(tlb_track_sar_not_tracked);
 103.132          return TLB_TRACK_NOT_TRACKED;
 103.133      }
 103.134      if (!pte_tlb_inserted(old_pte)) {
 103.135          BUG_ON(pte_tlb_inserted_many(old_pte));
 103.136 -        perfc_incrc(tlb_track_sar_not_found);
 103.137 +        perfc_incr(tlb_track_sar_not_found);
 103.138          return TLB_TRACK_NOT_FOUND;
 103.139      }
 103.140      if (pte_tlb_inserted_many(old_pte)) {
 103.141          BUG_ON(!pte_tlb_inserted(old_pte));
 103.142 -        perfc_incrc(tlb_track_sar_many);
 103.143 +        perfc_incr(tlb_track_sar_many);
 103.144          return TLB_TRACK_MANY;
 103.145      }
 103.146  
 103.147 @@ -475,14 +475,14 @@ tlb_track_search_and_remove(struct tlb_t
 103.148                           pte_tlb_inserted(current_pte))) {
 103.149                  BUG_ON(pte_tlb_inserted_many(current_pte));
 103.150                  spin_unlock(&tlb_track->hash_lock);
 103.151 -                perfc_incrc(tlb_track_sar_many);
 103.152 +                perfc_incr(tlb_track_sar_many);
 103.153                  return TLB_TRACK_MANY;
 103.154              }
 103.155  
 103.156              list_del(&entry->list);
 103.157              spin_unlock(&tlb_track->hash_lock);
 103.158              *entryp = entry;
 103.159 -            perfc_incrc(tlb_track_sar_found);
 103.160 +            perfc_incr(tlb_track_sar_found);
 103.161              // tlb_track_entry_printf(entry);
 103.162  #ifdef CONFIG_TLB_TRACK_CNT
 103.163              // tlb_track_printd("cnt = %ld\n", entry->cnt);
   104.1 --- a/xen/arch/ia64/xen/vcpu.c	Fri Mar 30 10:27:15 2007 -0600
   104.2 +++ b/xen/arch/ia64/xen/vcpu.c	Fri Mar 30 17:18:42 2007 -0600
   104.3 @@ -1616,7 +1616,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
   104.4  			*pteval = (address & _PAGE_PPN_MASK) |
   104.5  				__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
   104.6  			*itir = PAGE_SHIFT << 2;
   104.7 -			perfc_incrc(phys_translate);
   104.8 +			perfc_incr(phys_translate);
   104.9  			return IA64_NO_FAULT;
  104.10  		}
  104.11  	} else if (!region && warn_region0_address) {
  104.12 @@ -1637,7 +1637,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
  104.13  		if (trp != NULL) {
  104.14  			*pteval = trp->pte.val;
  104.15  			*itir = trp->itir;
  104.16 -			perfc_incrc(tr_translate);
  104.17 +			perfc_incr(tr_translate);
  104.18  			return IA64_NO_FAULT;
  104.19  		}
  104.20  	}
  104.21 @@ -1647,7 +1647,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
  104.22  		if (trp != NULL) {
  104.23  			*pteval = trp->pte.val;
  104.24  			*itir = trp->itir;
  104.25 -			perfc_incrc(tr_translate);
  104.26 +			perfc_incr(tr_translate);
  104.27  			return IA64_NO_FAULT;
  104.28  		}
  104.29  	}
  104.30 @@ -1660,7 +1660,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
  104.31  	    && vcpu_match_tr_entry_no_p(trp, address, rid)) {
  104.32  		*pteval = pte.val;
  104.33  		*itir = trp->itir;
  104.34 -		perfc_incrc(dtlb_translate);
  104.35 +		perfc_incr(dtlb_translate);
  104.36  		return IA64_USE_TLB;
  104.37  	}
  104.38  
  104.39 @@ -1709,7 +1709,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
  104.40  out:
  104.41  	*itir = rr & RR_PS_MASK;
  104.42  	*pteval = pte.val;
  104.43 -	perfc_incrc(vhpt_translate);
  104.44 +	perfc_incr(vhpt_translate);
  104.45  	return IA64_NO_FAULT;
  104.46  }
  104.47  
   105.1 --- a/xen/arch/ia64/xen/vhpt.c	Fri Mar 30 10:27:15 2007 -0600
   105.2 +++ b/xen/arch/ia64/xen/vhpt.c	Fri Mar 30 17:18:42 2007 -0600
   105.3 @@ -48,14 +48,14 @@ local_vhpt_flush(void)
   105.4  	/* this must be after flush */
   105.5  	tlbflush_update_time(&__get_cpu_var(vhpt_tlbflush_timestamp),
   105.6  	                     flush_time);
   105.7 -	perfc_incrc(local_vhpt_flush);
   105.8 +	perfc_incr(local_vhpt_flush);
   105.9  }
  105.10  
  105.11  void
  105.12  vcpu_vhpt_flush(struct vcpu* v)
  105.13  {
  105.14  	__vhpt_flush(vcpu_vhpt_maddr(v));
  105.15 -	perfc_incrc(vcpu_vhpt_flush);
  105.16 +	perfc_incr(vcpu_vhpt_flush);
  105.17  }
  105.18  
  105.19  static void
  105.20 @@ -184,7 +184,7 @@ domain_purge_swtc_entries(struct domain 
  105.21  {
  105.22  	struct vcpu* v;
  105.23  	for_each_vcpu(d, v) {
  105.24 -		if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
  105.25 +		if (!v->is_initialised)
  105.26  			continue;
  105.27  
  105.28  		/* Purge TC entries.
  105.29 @@ -202,7 +202,7 @@ domain_purge_swtc_entries_vcpu_dirty_mas
  105.30  
  105.31  	for_each_vcpu_mask(vcpu, vcpu_dirty_mask) {
  105.32  		struct vcpu* v = d->vcpu[vcpu];
  105.33 -		if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
  105.34 +		if (!v->is_initialised)
  105.35  			continue;
  105.36  
  105.37  		/* Purge TC entries.
  105.38 @@ -248,7 +248,7 @@ void vcpu_flush_vtlb_all(struct vcpu *v)
  105.39  	   not running on this processor.  There is currently no easy way to
  105.40  	   check this.  */
  105.41  
  105.42 -	perfc_incrc(vcpu_flush_vtlb_all);
  105.43 +	perfc_incr(vcpu_flush_vtlb_all);
  105.44  }
  105.45  
  105.46  static void __vcpu_flush_vtlb_all(void *vcpu)
  105.47 @@ -263,7 +263,7 @@ void domain_flush_vtlb_all(struct domain
  105.48  	struct vcpu *v;
  105.49  
  105.50  	for_each_vcpu(d, v) {
  105.51 -		if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
  105.52 +		if (!v->is_initialised)
  105.53  			continue;
  105.54  
  105.55  		if (v->processor == cpu)
  105.56 @@ -280,7 +280,7 @@ void domain_flush_vtlb_all(struct domain
  105.57  						 __vcpu_flush_vtlb_all,
  105.58  						 v, 1, 1);
  105.59  	}
  105.60 -	perfc_incrc(domain_flush_vtlb_all);
  105.61 +	perfc_incr(domain_flush_vtlb_all);
  105.62  }
  105.63  
  105.64  // Callers may need to call smp_mb() before/after calling this.
  105.65 @@ -322,7 +322,7 @@ void vcpu_flush_tlb_vhpt_range (u64 vadr
  105.66  		                     vadr, 1UL << log_range);
  105.67  	ia64_ptcl(vadr, log_range << 2);
  105.68  	ia64_srlz_i();
  105.69 -	perfc_incrc(vcpu_flush_tlb_vhpt_range);
  105.70 +	perfc_incr(vcpu_flush_tlb_vhpt_range);
  105.71  }
  105.72  
  105.73  void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
  105.74 @@ -341,7 +341,7 @@ void domain_flush_vtlb_range (struct dom
  105.75  	smp_mb();
  105.76  
  105.77  	for_each_vcpu (d, v) {
  105.78 -		if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
  105.79 +		if (!v->is_initialised)
  105.80  			continue;
  105.81  
  105.82  		if (HAS_PERVCPU_VHPT(d)) {
  105.83 @@ -361,7 +361,7 @@ void domain_flush_vtlb_range (struct dom
  105.84  
  105.85  	/* ptc.ga  */
  105.86  	platform_global_tlb_purge(vadr, vadr + addr_range, PAGE_SHIFT);
  105.87 -	perfc_incrc(domain_flush_vtlb_range);
  105.88 +	perfc_incr(domain_flush_vtlb_range);
  105.89  }
  105.90  
  105.91  #ifdef CONFIG_XEN_IA64_TLB_TRACK
  105.92 @@ -391,11 +391,11 @@ void
  105.93  	 */
  105.94  	vcpu_get_rr(current, VRN7 << VRN_SHIFT, &rr7_rid);
  105.95  	if (likely(rr7_rid == entry->rid)) {
  105.96 -		perfc_incrc(tlb_track_use_rr7);
  105.97 +		perfc_incr(tlb_track_use_rr7);
  105.98  	} else {
  105.99  		swap_rr0 = 1;
 105.100  		vaddr = (vaddr << 3) >> 3;// force vrn0
 105.101 -		perfc_incrc(tlb_track_swap_rr0);
 105.102 +		perfc_incr(tlb_track_swap_rr0);
 105.103  	}
 105.104  
 105.105  	// tlb_track_entry_printf(entry);
 105.106 @@ -407,7 +407,7 @@ void
 105.107  	if (HAS_PERVCPU_VHPT(d)) {
 105.108  		for_each_vcpu_mask(vcpu, entry->vcpu_dirty_mask) {
 105.109  			v = d->vcpu[vcpu];
 105.110 -			if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
 105.111 +			if (!v->is_initialised)
 105.112  				continue;
 105.113  
 105.114  			/* Invalidate VHPT entries.  */
 105.115 @@ -435,18 +435,18 @@ void
 105.116  	/* ptc.ga  */
 105.117  	if (local_purge) {
 105.118  		ia64_ptcl(vaddr, PAGE_SHIFT << 2);
 105.119 -		perfc_incrc(domain_flush_vtlb_local);
 105.120 +		perfc_incr(domain_flush_vtlb_local);
 105.121  	} else {
 105.122  		/* ptc.ga has release semantics. */
 105.123  		platform_global_tlb_purge(vaddr, vaddr + PAGE_SIZE,
 105.124  		                          PAGE_SHIFT);
 105.125 -		perfc_incrc(domain_flush_vtlb_global);
 105.126 +		perfc_incr(domain_flush_vtlb_global);
 105.127  	}
 105.128  
 105.129  	if (swap_rr0) {
 105.130  		vcpu_set_rr(current, 0, old_rid);
 105.131  	}
 105.132 -	perfc_incrc(domain_flush_vtlb_track_entry);
 105.133 +	perfc_incr(domain_flush_vtlb_track_entry);
 105.134  }
 105.135  
 105.136  void
 105.137 @@ -512,7 +512,7 @@ void gather_vhpt_stats(void)
 105.138  		for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
 105.139  			if (!(v->ti_tag & INVALID_TI_TAG))
 105.140  				vhpt_valid++;
 105.141 -		perfc_seta(vhpt_valid_entries, cpu, vhpt_valid);
 105.142 +		per_cpu(perfcounters, cpu)[PERFC_vhpt_valid_entries] = vhpt_valid;
 105.143  	}
 105.144  }
 105.145  #endif
   106.1 --- a/xen/arch/powerpc/backtrace.c	Fri Mar 30 10:27:15 2007 -0600
   106.2 +++ b/xen/arch/powerpc/backtrace.c	Fri Mar 30 17:18:42 2007 -0600
   106.3 @@ -205,21 +205,6 @@ void show_backtrace_regs(struct cpu_user
   106.4      console_end_sync();
   106.5  }
   106.6  
   106.7 -void __warn(char *file, int line)
   106.8 -{
   106.9 -    ulong sp;
  106.10 -    ulong lr;
  106.11 -
  106.12 -    console_start_sync();
  106.13 -    printk("WARN at %s:%d\n", file, line);
  106.14 -
  106.15 -    sp = (ulong)__builtin_frame_address(0);
  106.16 -    lr = (ulong)__builtin_return_address(0);
  106.17 -    backtrace(sp, lr, lr);
  106.18 -
  106.19 -    console_end_sync();
  106.20 -}
  106.21 -
  106.22  void dump_execution_state(void)
  106.23  {
  106.24      struct cpu_user_regs *regs = guest_cpu_user_regs();
   107.1 --- a/xen/arch/powerpc/domain.c	Fri Mar 30 10:27:15 2007 -0600
   107.2 +++ b/xen/arch/powerpc/domain.c	Fri Mar 30 17:18:42 2007 -0600
   107.3 @@ -168,10 +168,13 @@ int arch_set_info_guest(struct vcpu *v, 
   107.4      d->shared_info->wc_nsec = dom0->shared_info->wc_nsec;
   107.5      d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase;
   107.6  
   107.7 -    /* Auto-online VCPU0 when it is initialised. */
   107.8 -    if ( !test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
   107.9 -         (v->vcpu_id == 0) )
  107.10 -        clear_bit(_VCPUF_down, &v->vcpu_flags);
  107.11 +    if ( !v->is_initialised )
  107.12 +    {
  107.13 +        v->is_initialised = 1;
  107.14 +        /* Auto-online VCPU0 when it is initialised. */
  107.15 +        if ( v->vcpu_id == 0 )
  107.16 +            clear_bit(_VPF_down, &v->pause_flags);
  107.17 +    }
  107.18  
  107.19      cpu_init_vcpu(v);
  107.20  
   108.1 --- a/xen/arch/powerpc/domain_build.c	Fri Mar 30 10:27:15 2007 -0600
   108.2 +++ b/xen/arch/powerpc/domain_build.c	Fri Mar 30 17:18:42 2007 -0600
   108.3 @@ -273,8 +273,8 @@ int construct_dom0(struct domain *d,
   108.4  
   108.5      ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
   108.6  
   108.7 -    set_bit(_VCPUF_initialised, &v->vcpu_flags);
   108.8 -    clear_bit(_VCPUF_down, &v->vcpu_flags);
   108.9 +    v->is_initialised = 1;
  108.10 +    clear_bit(_VPF_down, &v->pause_flags);
  108.11  
  108.12      rc = 0;
  108.13  
   109.1 --- a/xen/arch/powerpc/mm.c	Fri Mar 30 10:27:15 2007 -0600
   109.2 +++ b/xen/arch/powerpc/mm.c	Fri Mar 30 17:18:42 2007 -0600
   109.3 @@ -106,7 +106,7 @@ void share_xen_page_with_guest(
   109.4      ASSERT(page->count_info == 0);
   109.5  
   109.6      /* Only add to the allocation list if the domain isn't dying. */
   109.7 -    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
   109.8 +    if ( !d->is_dying )
   109.9      {
  109.10          page->count_info |= PGC_allocated | 1;
  109.11          if ( unlikely(d->xenheap_pages++ == 0) )
  109.12 @@ -218,8 +218,7 @@ void put_page_type(struct page_info *pag
  109.13           * page-table pages if we detect a referential loop.
  109.14           * See domain.c:relinquish_list().
  109.15           */
  109.16 -        ASSERT((x & PGT_validated) || 
  109.17 -               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
  109.18 +        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
  109.19  
  109.20          if ( unlikely((nx & PGT_count_mask) == 0) )
  109.21          {
  109.22 @@ -261,7 +260,7 @@ int get_page_type(struct page_info *page
  109.23  
  109.24                  if ( unlikely(!cpus_empty(mask)) )
  109.25                  {
  109.26 -                    perfc_incrc(need_flush_tlb_flush);
  109.27 +                    perfc_incr(need_flush_tlb_flush);
  109.28                      flush_tlb_mask(mask);
  109.29                  }
  109.30  
  109.31 @@ -402,7 +401,7 @@ int allocate_rma(struct domain *d, unsig
  109.32  void free_rma_check(struct page_info *page)
  109.33  {
  109.34      if (test_bit(_PGC_page_RMA, &page->count_info)) {
  109.35 -        if (!test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags)) {
  109.36 +        if (!page_get_owner(page)->is_dying) {
  109.37              panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
  109.38          } else {
  109.39              clear_bit(_PGC_page_RMA, &page->count_info);
  109.40 @@ -439,8 +438,7 @@ ulong pfn2mfn(struct domain *d, ulong pf
  109.41              mfn = d->arch.p2m[pfn];
  109.42          }
  109.43  #ifdef DEBUG
  109.44 -        if (t != PFN_TYPE_NONE &&
  109.45 -            (d->domain_flags & DOMF_dying) &&
  109.46 +        if (t != PFN_TYPE_NONE && d->is_dying &&
  109.47              page_get_owner(mfn_to_page(mfn)) != d) {
  109.48              printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
  109.49                     __func__, t,
   110.1 --- a/xen/arch/x86/Rules.mk	Fri Mar 30 10:27:15 2007 -0600
   110.2 +++ b/xen/arch/x86/Rules.mk	Fri Mar 30 17:18:42 2007 -0600
   110.3 @@ -59,6 +59,4 @@ HDRS += $(wildcard $(BASEDIR)/include/as
   110.4  HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/vmx/*.h)
   110.5  
   110.6  # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
   110.7 -ifneq ($(call cc-ver,$(CC),0x030400),y)
   110.8 -$(error Xen requires at least gcc-3.4)
   110.9 -endif
  110.10 +$(call cc-ver-check,CC,0x030400,"Xen requires at least gcc-3.4")
   111.1 --- a/xen/arch/x86/apic.c	Fri Mar 30 10:27:15 2007 -0600
   111.2 +++ b/xen/arch/x86/apic.c	Fri Mar 30 17:18:42 2007 -0600
   111.3 @@ -1076,7 +1076,7 @@ int reprogram_timer(s_time_t timeout)
   111.4  fastcall void smp_apic_timer_interrupt(struct cpu_user_regs * regs)
   111.5  {
   111.6      ack_APIC_irq();
   111.7 -    perfc_incrc(apic_timer);
   111.8 +    perfc_incr(apic_timer);
   111.9      raise_softirq(TIMER_SOFTIRQ);
  111.10  }
  111.11  
   112.1 --- a/xen/arch/x86/domain.c	Fri Mar 30 10:27:15 2007 -0600
   112.2 +++ b/xen/arch/x86/domain.c	Fri Mar 30 17:18:42 2007 -0600
   112.3 @@ -274,7 +274,7 @@ int switch_native(struct domain *d)
   112.4      if ( !IS_COMPAT(d) )
   112.5          return 0;
   112.6  
   112.7 -    clear_bit(_DOMF_compat, &d->domain_flags);
   112.8 +    d->is_compat = 0;
   112.9      release_arg_xlat_area(d);
  112.10  
  112.11      /* switch gdt */
  112.12 @@ -306,7 +306,7 @@ int switch_compat(struct domain *d)
  112.13      if ( IS_COMPAT(d) )
  112.14          return 0;
  112.15  
  112.16 -    set_bit(_DOMF_compat, &d->domain_flags);
  112.17 +    d->is_compat = 1;
  112.18  
  112.19      /* switch gdt */
  112.20      gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
  112.21 @@ -563,9 +563,7 @@ int arch_set_info_guest(
  112.22  #endif
  112.23      }
  112.24  
  112.25 -    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
  112.26 -    if ( flags & VGCF_I387_VALID )
  112.27 -        set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
  112.28 +    v->fpu_initialised = !!(flags & VGCF_I387_VALID);
  112.29  
  112.30      v->arch.flags &= ~TF_kernel_mode;
  112.31      if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
  112.32 @@ -600,7 +598,7 @@ int arch_set_info_guest(
  112.33          hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
  112.34      }
  112.35  
  112.36 -    if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  112.37 +    if ( v->is_initialised )
  112.38          goto out;
  112.39  
  112.40      memset(v->arch.guest_context.debugreg, 0,
  112.41 @@ -699,7 +697,7 @@ int arch_set_info_guest(
  112.42          update_domain_wallclock_time(d);
  112.43  
  112.44      /* Don't redo final setup */
  112.45 -    set_bit(_VCPUF_initialised, &v->vcpu_flags);
  112.46 +    v->is_initialised = 1;
  112.47  
  112.48      if ( paging_mode_enabled(d) )
  112.49          paging_update_paging_modes(v);
  112.50 @@ -708,9 +706,9 @@ int arch_set_info_guest(
  112.51  
  112.52   out:
  112.53      if ( flags & VGCF_online )
  112.54 -        clear_bit(_VCPUF_down, &v->vcpu_flags);
  112.55 +        clear_bit(_VPF_down, &v->pause_flags);
  112.56      else
  112.57 -        set_bit(_VCPUF_down, &v->vcpu_flags);
  112.58 +        set_bit(_VPF_down, &v->pause_flags);
  112.59      return 0;
  112.60  #undef c
  112.61  }
   113.1 --- a/xen/arch/x86/domain_build.c	Fri Mar 30 10:27:15 2007 -0600
   113.2 +++ b/xen/arch/x86/domain_build.c	Fri Mar 30 17:18:42 2007 -0600
   113.3 @@ -254,7 +254,7 @@ int construct_dom0(struct domain *d,
   113.4      /* Sanity! */
   113.5      BUG_ON(d->domain_id != 0);
   113.6      BUG_ON(d->vcpu[0] == NULL);
   113.7 -    BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
   113.8 +    BUG_ON(v->is_initialised);
   113.9  
  113.10      printk("*** LOADING DOMAIN 0 ***\n");
  113.11  
  113.12 @@ -324,7 +324,7 @@ int construct_dom0(struct domain *d,
  113.13      {
  113.14          l1_pgentry_t gdt_l1e;
  113.15  
  113.16 -        set_bit(_DOMF_compat, &d->domain_flags);
  113.17 +        d->is_compat = 1;
  113.18          v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
  113.19  
  113.20          if ( nr_pages != (unsigned int)nr_pages )
  113.21 @@ -901,8 +901,8 @@ int construct_dom0(struct domain *d,
  113.22  
  113.23      update_domain_wallclock_time(d);
  113.24  
  113.25 -    set_bit(_VCPUF_initialised, &v->vcpu_flags);
  113.26 -    clear_bit(_VCPUF_down, &v->vcpu_flags);
  113.27 +    v->is_initialised = 1;
  113.28 +    clear_bit(_VPF_down, &v->pause_flags);
  113.29  
  113.30      /*
  113.31       * Initial register values:
   114.1 --- a/xen/arch/x86/domctl.c	Fri Mar 30 10:27:15 2007 -0600
   114.2 +++ b/xen/arch/x86/domctl.c	Fri Mar 30 17:18:42 2007 -0600
   114.3 @@ -448,9 +448,9 @@ void arch_get_info_guest(struct vcpu *v,
   114.4  #endif
   114.5  
   114.6      c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
   114.7 -    if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
   114.8 +    if ( v->fpu_initialised )
   114.9          c(flags |= VGCF_i387_valid);
  114.10 -    if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
  114.11 +    if ( !test_bit(_VPF_down, &v->pause_flags) )
  114.12          c(flags |= VGCF_online);
  114.13  
  114.14      if ( is_hvm_vcpu(v) )
   115.1 --- a/xen/arch/x86/extable.c	Fri Mar 30 10:27:15 2007 -0600
   115.2 +++ b/xen/arch/x86/extable.c	Fri Mar 30 17:18:42 2007 -0600
   115.3 @@ -72,7 +72,7 @@ search_pre_exception_table(struct cpu_us
   115.4      if ( fixup )
   115.5      {
   115.6          dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
   115.7 -        perfc_incrc(exception_fixed);
   115.8 +        perfc_incr(exception_fixed);
   115.9      }
  115.10      return fixup;
  115.11  }
   116.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Mar 30 10:27:15 2007 -0600
   116.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Mar 30 17:18:42 2007 -0600
   116.3 @@ -59,11 +59,14 @@ struct hvm_function_table hvm_funcs __re
   116.4  /* I/O permission bitmap is globally shared by all HVM guests. */
   116.5  char __attribute__ ((__section__ (".bss.page_aligned")))
   116.6      hvm_io_bitmap[3*PAGE_SIZE];
   116.7 +/* MSR permission bitmap is globally shared by all HVM guests. */
   116.8 +char __attribute__ ((__section__ (".bss.page_aligned")))
   116.9 +    hvm_msr_bitmap[PAGE_SIZE];
  116.10  
  116.11  void hvm_enable(struct hvm_function_table *fns)
  116.12  {
  116.13 -    if ( hvm_enabled )
  116.14 -        return;
  116.15 +    BUG_ON(hvm_enabled);
  116.16 +    printk("HVM: %s enabled\n", fns->name);
  116.17  
  116.18      /*
  116.19       * Allow direct access to the PC debug port (it is often used for I/O
  116.20 @@ -72,6 +75,9 @@ void hvm_enable(struct hvm_function_tabl
  116.21      memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap));
  116.22      clear_bit(0x80, hvm_io_bitmap);
  116.23  
  116.24 +    /* All MSR accesses are intercepted by default. */
  116.25 +    memset(hvm_msr_bitmap, ~0, sizeof(hvm_msr_bitmap));
  116.26 +
  116.27      hvm_funcs   = *fns;
  116.28      hvm_enabled = 1;
  116.29  }
  116.30 @@ -85,7 +91,7 @@ void hvm_disable(void)
  116.31  void hvm_stts(struct vcpu *v)
  116.32  {
  116.33      /* FPU state already dirty? Then no need to setup_fpu() lazily. */
  116.34 -    if ( !test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
  116.35 +    if ( !v->fpu_dirtied )
  116.36          hvm_funcs.stts(v);
  116.37  }
  116.38  
  116.39 @@ -238,7 +244,7 @@ static int hvm_save_cpu_ctxt(struct doma
  116.40      {
  116.41          /* We don't need to save state for a vcpu that is down; the restore 
  116.42           * code will leave it down if there is nothing saved. */
  116.43 -        if ( test_bit(_VCPUF_down, &v->vcpu_flags) ) 
  116.44 +        if ( test_bit(_VPF_down, &v->pause_flags) ) 
  116.45              continue;
  116.46  
  116.47          hvm_funcs.save_cpu_ctxt(v, &ctxt);
  116.48 @@ -269,7 +275,7 @@ static int hvm_load_cpu_ctxt(struct doma
  116.49          return -EINVAL;
  116.50  
  116.51      /* Auxiliary processors should be woken immediately. */
  116.52 -    if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
  116.53 +    if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
  116.54          vcpu_wake(v);
  116.55  
  116.56      return 0;
  116.57 @@ -331,11 +337,11 @@ void hvm_vcpu_reset(struct vcpu *v)
  116.58  
  116.59      hvm_funcs.vcpu_initialise(v);
  116.60  
  116.61 -    set_bit(_VCPUF_down, &v->vcpu_flags);
  116.62 -    clear_bit(_VCPUF_initialised, &v->vcpu_flags);
  116.63 -    clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
  116.64 -    clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
  116.65 -    clear_bit(_VCPUF_blocked, &v->vcpu_flags);
  116.66 +    set_bit(_VPF_down, &v->pause_flags);
  116.67 +    clear_bit(_VPF_blocked, &v->pause_flags);
  116.68 +    v->fpu_initialised = 0;
  116.69 +    v->fpu_dirtied     = 0;
  116.70 +    v->is_initialised  = 0;
  116.71  
  116.72      vcpu_unpause(v);
  116.73  }
  116.74 @@ -350,13 +356,13 @@ static void hvm_vcpu_down(void)
  116.75             d->domain_id, v->vcpu_id);
  116.76  
  116.77      /* Doesn't halt us immediately, but we'll never return to guest context. */
  116.78 -    set_bit(_VCPUF_down, &v->vcpu_flags);
  116.79 +    set_bit(_VPF_down, &v->pause_flags);
  116.80      vcpu_sleep_nosync(v);
  116.81  
  116.82      /* Any other VCPUs online? ... */
  116.83      LOCK_BIGLOCK(d);
  116.84      for_each_vcpu ( d, v )
  116.85 -        if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
  116.86 +        if ( !test_bit(_VPF_down, &v->pause_flags) )
  116.87              online_count++;
  116.88      UNLOCK_BIGLOCK(d);
  116.89  
  116.90 @@ -556,6 +562,7 @@ static hvm_hypercall_t *hvm_hypercall_ta
  116.91      HYPERCALL(multicall),
  116.92      HYPERCALL(xen_version),
  116.93      HYPERCALL(event_channel_op),
  116.94 +    HYPERCALL(sched_op),
  116.95      HYPERCALL(hvm_op)
  116.96  };
  116.97  
  116.98 @@ -722,7 +729,7 @@ int hvm_bringup_ap(int vcpuid, int tramp
  116.99  
 116.100      LOCK_BIGLOCK(d);
 116.101      rc = -EEXIST;
 116.102 -    if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
 116.103 +    if ( !v->is_initialised )
 116.104          rc = boot_vcpu(d, vcpuid, ctxt);
 116.105      UNLOCK_BIGLOCK(d);
 116.106  
 116.107 @@ -733,7 +740,7 @@ int hvm_bringup_ap(int vcpuid, int tramp
 116.108          goto out;
 116.109      }
 116.110  
 116.111 -    if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
 116.112 +    if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
 116.113          vcpu_wake(v);
 116.114      gdprintk(XENLOG_INFO, "AP %d bringup suceeded.\n", vcpuid);
 116.115  
   117.1 --- a/xen/arch/x86/hvm/io.c	Fri Mar 30 10:27:15 2007 -0600
   117.2 +++ b/xen/arch/x86/hvm/io.c	Fri Mar 30 17:18:42 2007 -0600
   117.3 @@ -287,12 +287,18 @@ static void set_reg_value (int size, int
   117.4  }
   117.5  #endif
   117.6  
   117.7 -extern long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs);
   117.8 +long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs);
   117.9  
  117.10  static inline void set_eflags_CF(int size, unsigned long v1,
  117.11                                   unsigned long v2, struct cpu_user_regs *regs)
  117.12  {
  117.13 -    unsigned long mask = (1 << (8 * size)) - 1;
  117.14 +    unsigned long mask;
  117.15 +
  117.16 +    if ( size == BYTE_64 )
  117.17 +        size = BYTE;
  117.18 +    ASSERT((size <= sizeof(mask)) && (size > 0));
  117.19 +
  117.20 +    mask = ~0UL >> (8 * (sizeof(mask) - size));
  117.21  
  117.22      if ((v1 & mask) > (v2 & mask))
  117.23          regs->eflags |= X86_EFLAGS_CF;
  117.24 @@ -301,14 +307,24 @@ static inline void set_eflags_CF(int siz
  117.25  }
  117.26  
  117.27  static inline void set_eflags_OF(int size, unsigned long v1,
  117.28 -                                 unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
  117.29 +                                 unsigned long v2, unsigned long v3,
  117.30 +                                 struct cpu_user_regs *regs)
  117.31  {
  117.32 -    if ((v3 ^ v2) & (v3 ^ v1) & (1 << ((8 * size) - 1)))
  117.33 +    unsigned long mask;
  117.34 +
  117.35 +    if ( size == BYTE_64 )
  117.36 +        size = BYTE;
  117.37 +    ASSERT((size <= sizeof(mask)) && (size > 0));
  117.38 +
  117.39 +    mask = ~0UL >> (8 * (sizeof(mask) - size));
  117.40 +
  117.41 +    if ((v3 ^ v2) & (v3 ^ v1) & mask)
  117.42          regs->eflags |= X86_EFLAGS_OF;
  117.43  }
  117.44  
  117.45  static inline void set_eflags_AF(int size, unsigned long v1,
  117.46 -                                 unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
  117.47 +                                 unsigned long v2, unsigned long v3,
  117.48 +                                 struct cpu_user_regs *regs)
  117.49  {
  117.50      if ((v1 ^ v2 ^ v3) & 0x10)
  117.51          regs->eflags |= X86_EFLAGS_AF;
  117.52 @@ -317,7 +333,13 @@ static inline void set_eflags_AF(int siz
  117.53  static inline void set_eflags_ZF(int size, unsigned long v1,
  117.54                                   struct cpu_user_regs *regs)
  117.55  {
  117.56 -    unsigned long mask = (1 << (8 * size)) - 1;
  117.57 +    unsigned long mask;
  117.58 +
  117.59 +    if ( size == BYTE_64 )
  117.60 +        size = BYTE;
  117.61 +    ASSERT((size <= sizeof(mask)) && (size > 0));
  117.62 +
  117.63 +    mask = ~0UL >> (8 * (sizeof(mask) - size));
  117.64  
  117.65      if ((v1 & mask) == 0)
  117.66          regs->eflags |= X86_EFLAGS_ZF;
  117.67 @@ -326,7 +348,15 @@ static inline void set_eflags_ZF(int siz
  117.68  static inline void set_eflags_SF(int size, unsigned long v1,
  117.69                                   struct cpu_user_regs *regs)
  117.70  {
  117.71 -    if (v1 & (1 << ((8 * size) - 1)))
  117.72 +    unsigned long mask;
  117.73 +
  117.74 +    if ( size == BYTE_64 )
  117.75 +        size = BYTE;
  117.76 +    ASSERT((size <= sizeof(mask)) && (size > 0));
  117.77 +
  117.78 +    mask = ~0UL >> (8 * (sizeof(mask) - size));
  117.79 +
  117.80 +    if (v1 & mask)
  117.81          regs->eflags |= X86_EFLAGS_SF;
  117.82  }
  117.83  
  117.84 @@ -375,14 +405,14 @@ static void hvm_pio_assist(struct cpu_us
  117.85                  if ( hvm_paging_enabled(current) )
  117.86                  {
  117.87                      int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
  117.88 -                    if ( rv != 0 ) 
  117.89 +                    if ( rv != 0 )
  117.90                      {
  117.91                          /* Failed on the page-spanning copy.  Inject PF into
  117.92                           * the guest for the address where we failed. */
  117.93                          addr += p->size - rv;
  117.94                          gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side "
  117.95                                   "of a page-spanning PIO: va=%#lx\n", addr);
  117.96 -                        hvm_inject_exception(TRAP_page_fault, 
  117.97 +                        hvm_inject_exception(TRAP_page_fault,
  117.98                                               PFEC_write_access, addr);
  117.99                          return;
 117.100                      }
 117.101 @@ -505,14 +535,14 @@ static void hvm_mmio_assist(struct cpu_u
 117.102              if (hvm_paging_enabled(current))
 117.103              {
 117.104                  int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
 117.105 -                if ( rv != 0 ) 
 117.106 +                if ( rv != 0 )
 117.107                  {
 117.108                      /* Failed on the page-spanning copy.  Inject PF into
 117.109                       * the guest for the address where we failed. */
 117.110                      addr += p->size - rv;
 117.111                      gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side of "
 117.112                               "a page-spanning MMIO: va=%#lx\n", addr);
 117.113 -                    hvm_inject_exception(TRAP_page_fault, 
 117.114 +                    hvm_inject_exception(TRAP_page_fault,
 117.115                                           PFEC_write_access, addr);
 117.116                      return;
 117.117                  }
 117.118 @@ -718,14 +748,14 @@ static void hvm_mmio_assist(struct cpu_u
 117.119  
 117.120      case INSTR_PUSH:
 117.121          mmio_opp->addr += hvm_get_segment_base(current, x86_seg_ss);
 117.122 -        { 
 117.123 +        {
 117.124              unsigned long addr = mmio_opp->addr;
 117.125              int rv = hvm_copy_to_guest_virt(addr, &p->data, size);
 117.126 -            if ( rv != 0 ) 
 117.127 +            if ( rv != 0 )
 117.128              {
 117.129                  addr += p->size - rv;
 117.130 -                gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO: "
 117.131 -                         "va=%#lx\n", addr);
 117.132 +                gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO:"
 117.133 +                         " va=%#lx\n", addr);
 117.134                  hvm_inject_exception(TRAP_page_fault, PFEC_write_access, addr);
 117.135                  return;
 117.136              }
 117.137 @@ -767,7 +797,7 @@ void hvm_io_assist(struct vcpu *v)
 117.138      memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
 117.139  
 117.140      /* Has memory been dirtied? */
 117.141 -    if ( p->dir == IOREQ_READ && p->data_is_ptr ) 
 117.142 +    if ( p->dir == IOREQ_READ && p->data_is_ptr )
 117.143      {
 117.144          gmfn = get_mfn_from_gpfn(paging_gva_to_gfn(v, p->data));
 117.145          mark_dirty(v->domain, gmfn);
   118.1 --- a/xen/arch/x86/hvm/save.c	Fri Mar 30 10:27:15 2007 -0600
   118.2 +++ b/xen/arch/x86/hvm/save.c	Fri Mar 30 17:18:42 2007 -0600
   118.3 @@ -185,7 +185,7 @@ int hvm_load(struct domain *d, hvm_domai
   118.4  
   118.5      /* Down all the vcpus: we only re-enable the ones that had state saved. */
   118.6      for_each_vcpu(d, v) 
   118.7 -        if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
   118.8 +        if ( test_and_set_bit(_VPF_down, &v->pause_flags) )
   118.9              vcpu_sleep_nosync(v);
  118.10  
  118.11      while(1) {
   119.1 --- a/xen/arch/x86/hvm/svm/emulate.c	Fri Mar 30 10:27:15 2007 -0600
   119.2 +++ b/xen/arch/x86/hvm/svm/emulate.c	Fri Mar 30 17:18:42 2007 -0600
   119.3 @@ -373,6 +373,7 @@ MAKE_INSTR(HLT,    1, 0xf4);
   119.4  MAKE_INSTR(CLTS,   2, 0x0f, 0x06);
   119.5  MAKE_INSTR(LMSW,   3, 0x0f, 0x01, 0x00);
   119.6  MAKE_INSTR(SMSW,   3, 0x0f, 0x01, 0x00);
   119.7 +MAKE_INSTR(INT3,   1, 0xcc);
   119.8  
   119.9  static const u8 *opc_bytes[INSTR_MAX_COUNT] = 
  119.10  {
  119.11 @@ -405,7 +406,8 @@ static const u8 *opc_bytes[INSTR_MAX_COU
  119.12      [INSTR_CLTS]   = OPCODE_CLTS,
  119.13      [INSTR_HLT]    = OPCODE_HLT,
  119.14      [INSTR_LMSW]   = OPCODE_LMSW,
  119.15 -    [INSTR_SMSW]   = OPCODE_SMSW
  119.16 +    [INSTR_SMSW]   = OPCODE_SMSW,
  119.17 +    [INSTR_INT3]   = OPCODE_INT3
  119.18  };
  119.19  
  119.20  /* 
   120.1 --- a/xen/arch/x86/hvm/svm/intr.c	Fri Mar 30 10:27:15 2007 -0600
   120.2 +++ b/xen/arch/x86/hvm/svm/intr.c	Fri Mar 30 17:18:42 2007 -0600
   120.3 @@ -64,87 +64,73 @@ asmlinkage void svm_intr_assist(void)
   120.4  {
   120.5      struct vcpu *v = current;
   120.6      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   120.7 -    struct periodic_time *pt;
   120.8      int intr_type = APIC_DM_EXTINT;
   120.9      int intr_vector = -1;
  120.10 -    int re_injecting = 0;
  120.11  
  120.12 -    /* Check if an Injection is active */
  120.13 -    /* Previous Interrupt delivery caused this Intercept? */
  120.14 +    /*
  120.15 +     * Previous Interrupt delivery caused this intercept?
  120.16 +     * This will happen if the injection is latched by the processor (hence
  120.17 +     * clearing vintr.fields.irq) but then subsequently a fault occurs (e.g.,
  120.18 +     * due to lack of shadow mapping of guest IDT or guest-kernel stack).
  120.19 +     * 
  120.20 +     * NB. Exceptions that fault during delivery are lost. This needs to be
  120.21 +     * fixed but we'll usually get away with it since faults are usually
  120.22 +     * idempotent. But this isn't the case for e.g. software interrupts!
  120.23 +     */
  120.24      if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) )
  120.25      {
  120.26 -        v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector;
  120.27 +        intr_vector = vmcb->exitintinfo.fields.vector;
  120.28          vmcb->exitintinfo.bytes = 0;
  120.29 -        re_injecting = 1;
  120.30 +        HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
  120.31 +        svm_inject_extint(v, intr_vector);
  120.32 +        return;
  120.33      }
  120.34  
  120.35 -    /* Previous interrupt still pending? */
  120.36 +    /*
  120.37 +     * Previous interrupt still pending? This occurs if we return from VMRUN
  120.38 +     * very early in the entry-to-guest process. Usually this is because an
  120.39 +     * external physical interrupt was pending when we executed VMRUN.
  120.40 +     */
  120.41      if ( vmcb->vintr.fields.irq )
  120.42 -    {
  120.43 -        intr_vector = vmcb->vintr.fields.vector;
  120.44 -        vmcb->vintr.bytes = 0;
  120.45 -        re_injecting = 1;
  120.46 -    }
  120.47 -    /* Pending IRQ saved at last VMExit? */
  120.48 -    else if ( v->arch.hvm_svm.saved_irq_vector >= 0 )
  120.49 -    {
  120.50 -        intr_vector = v->arch.hvm_svm.saved_irq_vector;
  120.51 -        v->arch.hvm_svm.saved_irq_vector = -1;
  120.52 -        re_injecting = 1;
  120.53 -    }
  120.54 -    /* Now let's check for newer interrrupts  */
  120.55 -    else
  120.56 -    {
  120.57 -        pt_update_irq(v);
  120.58 +        return;
  120.59 +
  120.60 +    /* Crank the handle on interrupt state and check for new interrrupts. */
  120.61 +    pt_update_irq(v);
  120.62 +    hvm_set_callback_irq_level();
  120.63 +    if ( !cpu_has_pending_irq(v) )
  120.64 +        return;
  120.65  
  120.66 -        hvm_set_callback_irq_level();
  120.67 -
  120.68 -        if ( cpu_has_pending_irq(v) )
  120.69 -        {
  120.70 -            /*
  120.71 -             * Create a 'fake' virtual interrupt on to intercept as soon
  120.72 -             * as the guest _can_ take interrupts.  Do not obtain the next
  120.73 -             * interrupt from the vlapic/pic if unable to inject.
  120.74 -             */
  120.75 -            if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )  
  120.76 -            {
  120.77 -                vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
  120.78 -                HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
  120.79 -                svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */
  120.80 -                return;
  120.81 -            }
  120.82 -            intr_vector = cpu_get_interrupt(v, &intr_type);
  120.83 -        }
  120.84 +    /*
  120.85 +     * If the guest can't take an interrupt right now, create a 'fake'
  120.86 +     * virtual interrupt on to intercept as soon as the guest _can_ take
  120.87 +     * interrupts.  Do not obtain the next interrupt from the vlapic/pic
  120.88 +     * if unable to inject.
  120.89 +     *
  120.90 +     * Also do this if there is an exception pending.  This is because
  120.91 +     * the delivery of the exception can arbitrarily delay the injection
  120.92 +     * of the vintr (for example, if the exception is handled via an
  120.93 +     * interrupt gate, hence zeroing RFLAGS.IF). In the meantime:
  120.94 +     * - the vTPR could be modified upwards, so we need to wait until the
  120.95 +     *   exception is delivered before we can safely decide that an
  120.96 +     *   interrupt is deliverable; and
  120.97 +     * - the guest might look at the APIC/PIC state, so we ought not to have 
  120.98 +     *   cleared the interrupt out of the IRR.
  120.99 +     */
 120.100 +    if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow 
 120.101 +         || vmcb->eventinj.fields.v )  
 120.102 +    {
 120.103 +        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
 120.104 +        HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
 120.105 +        svm_inject_extint(v, 0x0); /* actual vector doesn't matter */
 120.106 +        return;
 120.107      }
 120.108  
 120.109 -    /* have we got an interrupt to inject? */
 120.110 -    if ( intr_vector < 0 )
 120.111 -        return;
 120.112 +    /* Okay, we can deliver the interrupt: grab it and update PIC state. */
 120.113 +    intr_vector = cpu_get_interrupt(v, &intr_type);
 120.114 +    BUG_ON(intr_vector < 0);
 120.115  
 120.116 -    switch ( intr_type )
 120.117 -    {
 120.118 -    case APIC_DM_EXTINT:
 120.119 -    case APIC_DM_FIXED:
 120.120 -    case APIC_DM_LOWEST:
 120.121 -        /* Re-injecting a PIT interruptt? */
 120.122 -        if ( re_injecting && (pt = is_pt_irq(v, intr_vector, intr_type)) )
 120.123 -            ++pt->pending_intr_nr;
 120.124 -        /* let's inject this interrupt */
 120.125 -        if (re_injecting)
 120.126 -            HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
 120.127 -        else
 120.128 -            HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
 120.129 -        svm_inject_extint(v, intr_vector);
 120.130 -        break;
 120.131 -    case APIC_DM_SMI:
 120.132 -    case APIC_DM_NMI:
 120.133 -    case APIC_DM_INIT:
 120.134 -    case APIC_DM_STARTUP:
 120.135 -    default:
 120.136 -        printk("Unsupported interrupt type: %d\n", intr_type);
 120.137 -        BUG();
 120.138 -        break;
 120.139 -    }
 120.140 +    HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
 120.141 +    svm_inject_extint(v, intr_vector);
 120.142  
 120.143      pt_intr_post(v, intr_vector, intr_type);
 120.144  }
   121.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Mar 30 10:27:15 2007 -0600
   121.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Mar 30 17:18:42 2007 -0600
   121.3 @@ -15,7 +15,6 @@
   121.4   * You should have received a copy of the GNU General Public License along with
   121.5   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   121.6   * Place - Suite 330, Boston, MA 02111-1307 USA.
   121.7 - *
   121.8   */
   121.9  
  121.10  #include <xen/config.h>
  121.11 @@ -50,22 +49,15 @@
  121.12  #include <asm/hvm/trace.h>
  121.13  #include <asm/hap.h>
  121.14  
  121.15 -#define SVM_EXTRA_DEBUG
  121.16 -
  121.17  #define set_segment_register(name, value)  \
  121.18 -       __asm__ __volatile__ ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
  121.19 -
  121.20 -/* External functions. We should move these to some suitable header file(s) */
  121.21 +    asm volatile ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
  121.22  
  121.23 -extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
  121.24 -                                int inst_len);
  121.25 -extern asmlinkage void do_IRQ(struct cpu_user_regs *);
  121.26 -extern void svm_dump_inst(unsigned long eip);
  121.27 -extern int svm_dbg_on;
  121.28 -void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
  121.29 +int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
  121.30 +                         int inst_len);
  121.31 +asmlinkage void do_IRQ(struct cpu_user_regs *);
  121.32  
  121.33 -static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
  121.34 -                                            struct cpu_user_regs *regs);
  121.35 +static int svm_reset_to_realmode(struct vcpu *v,
  121.36 +                                 struct cpu_user_regs *regs);
  121.37  
  121.38  /* va of hardware host save area     */
  121.39  static void *hsa[NR_CPUS] __read_mostly;
  121.40 @@ -78,7 +70,6 @@ u64 root_vmcb_pa[NR_CPUS] __read_mostly;
  121.41  
  121.42  /* hardware assisted paging bits */
  121.43  extern int opt_hap_enabled;
  121.44 -extern int hap_capable_system;
  121.45  
  121.46  static inline void svm_inject_exception(struct vcpu *v, int trap, 
  121.47                                          int ev, int error_code)
  121.48 @@ -213,7 +204,7 @@ static inline int long_mode_do_msr_write
  121.49      switch ( ecx )
  121.50      {
  121.51      case MSR_EFER:
  121.52 -        /* offending reserved bit will cause #GP */
  121.53 +        /* Offending reserved bit will cause #GP. */
  121.54          if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
  121.55          {
  121.56              gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
  121.57 @@ -221,53 +212,33 @@ static inline int long_mode_do_msr_write
  121.58              goto gp_fault;
  121.59          }
  121.60  
  121.61 -        /* 
  121.62 -         * update the VMCB's EFER with the intended value along with
  121.63 -         * that crucial EFER.SVME bit =)
  121.64 -         */
  121.65 -        vmcb->efer = msr_content | EFER_SVME;
  121.66 -
  121.67  #ifdef __x86_64__
  121.68 -
  121.69 -        /*
  121.70 -         * Check for EFER.LME transitions from 0->1 or 1->0.  Do the
  121.71 -         * sanity checks and then make sure that both EFER.LME and
  121.72 -         * EFER.LMA are cleared. (EFER.LME can't be set in the vmcb
  121.73 -         * until the guest also sets CR0.PG, since even if the guest has
  121.74 -         * paging "disabled", the vmcb's CR0 always has PG set.)
  121.75 -         */
  121.76          if ( (msr_content & EFER_LME) && !svm_lme_is_set(v) )
  121.77          {
  121.78 -            /* EFER.LME transition from 0 to 1 */
  121.79 -            
  121.80 -            if ( svm_paging_enabled(v) ||
  121.81 -                 !svm_cr4_pae_is_set(v) )
  121.82 +            /* EFER.LME transition from 0 to 1. */
  121.83 +            if ( svm_paging_enabled(v) || !svm_cr4_pae_is_set(v) )
  121.84              {
  121.85                  gdprintk(XENLOG_WARNING, "Trying to set LME bit when "
  121.86                           "in paging mode or PAE bit is not set\n");
  121.87                  goto gp_fault;
  121.88              }
  121.89 -
  121.90 -            vmcb->efer &= ~(EFER_LME | EFER_LMA);
  121.91          }
  121.92          else if ( !(msr_content & EFER_LME) && svm_lme_is_set(v) )
  121.93          {
  121.94 -            /* EFER.LME transistion from 1 to 0 */
  121.95 -            
  121.96 +            /* EFER.LME transistion from 1 to 0. */
  121.97              if ( svm_paging_enabled(v) )
  121.98              {
  121.99                  gdprintk(XENLOG_WARNING, 
 121.100                           "Trying to clear EFER.LME while paging enabled\n");
 121.101                  goto gp_fault;
 121.102              }
 121.103 -
 121.104 -            vmcb->efer &= ~(EFER_LME | EFER_LMA);
 121.105          }
 121.106 -
 121.107  #endif /* __x86_64__ */
 121.108  
 121.109 -        /* update the guest EFER's shadow with the intended value */
 121.110          v->arch.hvm_svm.cpu_shadow_efer = msr_content;
 121.111 +        vmcb->efer = msr_content | EFER_SVME;
 121.112 +        if ( !svm_paging_enabled(v) )
 121.113 +            vmcb->efer &= ~(EFER_LME | EFER_LMA);
 121.114  
 121.115          break;
 121.116  
 121.117 @@ -324,9 +295,9 @@ static inline int long_mode_do_msr_write
 121.118  
 121.119  
 121.120  #define loaddebug(_v,_reg) \
 121.121 -    __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
 121.122 +    asm volatile ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
 121.123  #define savedebug(_v,_reg) \
 121.124 -    __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r" ((_v)->debugreg[_reg]))
 121.125 +    asm volatile ("mov %%db" #_reg ",%0" : : "r" ((_v)->debugreg[_reg]))
 121.126  
 121.127  static inline void svm_save_dr(struct vcpu *v)
 121.128  {
 121.129 @@ -733,7 +704,7 @@ static void svm_stts(struct vcpu *v)
 121.130       */
 121.131      if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
 121.132      {
 121.133 -        v->arch.hvm_svm.vmcb->exception_intercepts |= EXCEPTION_BITMAP_NM;
 121.134 +        v->arch.hvm_svm.vmcb->exception_intercepts |= 1U << TRAP_no_device;
 121.135          vmcb->cr0 |= X86_CR0_TS;
 121.136      }
 121.137  }
 121.138 @@ -749,19 +720,21 @@ static void svm_init_ap_context(
 121.139      struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
 121.140  {
 121.141      struct vcpu *v;
 121.142 +    struct vmcb_struct *vmcb;
 121.143      cpu_user_regs_t *regs;
 121.144      u16 cs_sel;
 121.145  
 121.146      /* We know this is safe because hvm_bringup_ap() does it */
 121.147      v = current->domain->vcpu[vcpuid];
 121.148 +    vmcb = v->arch.hvm_svm.vmcb;
 121.149      regs = &v->arch.guest_context.user_regs;
 121.150  
 121.151      memset(ctxt, 0, sizeof(*ctxt));
 121.152  
 121.153      /*
 121.154       * We execute the trampoline code in real mode. The trampoline vector
 121.155 -     * passed to us is page alligned and is the physicall frame number for
 121.156 -     * the code. We will execute this code in real mode. 
 121.157 +     * passed to us is page alligned and is the physical frame number for
 121.158 +     * the code. We will execute this code in real mode.
 121.159       */
 121.160      cs_sel = trampoline_vector << 8;
 121.161      ctxt->user_regs.eip = 0x0;
 121.162 @@ -771,11 +744,11 @@ static void svm_init_ap_context(
 121.163       * This is the launch of an AP; set state so that we begin executing
 121.164       * the trampoline code in real-mode.
 121.165       */
 121.166 -    svm_do_vmmcall_reset_to_realmode(v, regs);  
 121.167 +    svm_reset_to_realmode(v, regs);  
 121.168      /* Adjust the vmcb's hidden register state. */
 121.169 -    v->arch.hvm_svm.vmcb->rip = 0;
 121.170 -    v->arch.hvm_svm.vmcb->cs.sel = cs_sel;
 121.171 -    v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
 121.172 +    vmcb->rip = 0;
 121.173 +    vmcb->cs.sel = cs_sel;
 121.174 +    vmcb->cs.base = (cs_sel << 4);
 121.175  }
 121.176  
 121.177  static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
 121.178 @@ -800,75 +773,10 @@ static void svm_init_hypercall_page(stru
 121.179      *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
 121.180  }
 121.181  
 121.182 -
 121.183 -int svm_dbg_on = 0;
 121.184 -
 121.185 -static inline int svm_do_debugout(unsigned long exit_code)
 121.186 -{
 121.187 -    int i;
 121.188 -
 121.189 -    static unsigned long counter = 0;
 121.190 -    static unsigned long works[] =
 121.191 -    {
 121.192 -        VMEXIT_IOIO,
 121.193 -        VMEXIT_HLT,
 121.194 -        VMEXIT_CPUID,
 121.195 -        VMEXIT_DR0_READ,
 121.196 -        VMEXIT_DR1_READ,
 121.197 -        VMEXIT_DR2_READ,
 121.198 -        VMEXIT_DR3_READ,
 121.199 -        VMEXIT_DR6_READ,
 121.200 -        VMEXIT_DR7_READ,
 121.201 -        VMEXIT_DR0_WRITE,
 121.202 -        VMEXIT_DR1_WRITE,
 121.203 -        VMEXIT_DR2_WRITE,
 121.204 -        VMEXIT_DR3_WRITE,
 121.205 -        VMEXIT_CR0_READ,
 121.206 -        VMEXIT_CR0_WRITE,
 121.207 -        VMEXIT_CR3_READ,
 121.208 -        VMEXIT_CR4_READ, 
 121.209 -        VMEXIT_MSR,
 121.210 -        VMEXIT_CR0_WRITE,
 121.211 -        VMEXIT_CR3_WRITE,
 121.212 -        VMEXIT_CR4_WRITE,
 121.213 -        VMEXIT_EXCEPTION_PF,
 121.214 -        VMEXIT_INTR,
 121.215 -        VMEXIT_INVLPG,
 121.216 -        VMEXIT_EXCEPTION_NM
 121.217 -    };
 121.218 -
 121.219 -
 121.220 -#if 0
 121.221 -    if (svm_dbg_on && exit_code != 0x7B)
 121.222 -        return 1;
 121.223 -#endif
 121.224 -
 121.225 -    counter++;
 121.226 -
 121.227 -#if 0
 121.228 -    if ((exit_code == 0x4E 
 121.229 -         || exit_code == VMEXIT_CR0_READ 
 121.230 -         || exit_code == VMEXIT_CR0_WRITE) 
 121.231 -        && counter < 200000)
 121.232 -        return 0;
 121.233 -
 121.234 -    if ((exit_code == 0x4E) && counter < 500000)
 121.235 -        return 0;
 121.236 -#endif
 121.237 -
 121.238 -    for (i = 0; i < sizeof(works) / sizeof(works[0]); i++)
 121.239 -        if (exit_code == works[i])
 121.240 -            return 0;
 121.241 -
 121.242 -    return 1;
 121.243 -}
 121.244 -
 121.245  static void save_svm_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *ctxt)
 121.246  {
 121.247      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.248  
 121.249 -    ASSERT(vmcb);
 121.250 -
 121.251      ctxt->eax = vmcb->rax;
 121.252      ctxt->ss = vmcb->ss.sel;
 121.253      ctxt->esp = vmcb->rsp;
 121.254 @@ -882,42 +790,16 @@ static void save_svm_cpu_user_regs(struc
 121.255      ctxt->ds = vmcb->ds.sel;
 121.256  }
 121.257  
 121.258 -static void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v)
 121.259 +static void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
 121.260  {
 121.261      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.262 -
 121.263 -    regs->eip    = vmcb->rip;
 121.264 -    regs->esp    = vmcb->rsp;
 121.265 -    regs->eflags = vmcb->rflags;
 121.266 -    regs->cs     = vmcb->cs.sel;
 121.267 -    regs->ds     = vmcb->ds.sel;
 121.268 -    regs->es     = vmcb->es.sel;
 121.269 -    regs->ss     = vmcb->ss.sel;
 121.270 -}
 121.271 -
 121.272 -/* XXX Use svm_load_cpu_guest_regs instead */
 121.273 -static void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
 121.274 -{ 
 121.275 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.276 -    u32 *intercepts = &v->arch.hvm_svm.vmcb->exception_intercepts;
 121.277      
 121.278 -    /* Write the guest register value into VMCB */
 121.279      vmcb->rax      = regs->eax;
 121.280      vmcb->ss.sel   = regs->ss;
 121.281      vmcb->rsp      = regs->esp;   
 121.282      vmcb->rflags   = regs->eflags | 2UL;
 121.283      vmcb->cs.sel   = regs->cs;
 121.284      vmcb->rip      = regs->eip;
 121.285 -    if (regs->eflags & EF_TF)
 121.286 -        *intercepts |= EXCEPTION_BITMAP_DB;
 121.287 -    else
 121.288 -        *intercepts &= ~EXCEPTION_BITMAP_DB;
 121.289 -}
 121.290 -
 121.291 -static void svm_load_cpu_guest_regs(
 121.292 -    struct vcpu *v, struct cpu_user_regs *regs)
 121.293 -{
 121.294 -    svm_load_cpu_user_regs(v, regs);
 121.295  }
 121.296  
 121.297  static void svm_ctxt_switch_from(struct vcpu *v)
 121.298 @@ -941,8 +823,20 @@ static void svm_ctxt_switch_to(struct vc
 121.299      svm_restore_dr(v);
 121.300  }
 121.301  
 121.302 -static void arch_svm_do_resume(struct vcpu *v) 
 121.303 +static void svm_do_resume(struct vcpu *v) 
 121.304  {
 121.305 +    bool_t debug_state = v->domain->debugger_attached;
 121.306 +
 121.307 +    if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
 121.308 +    {
 121.309 +        uint32_t mask = (1U << TRAP_debug) | (1U << TRAP_int3);
 121.310 +        v->arch.hvm_vcpu.debug_state_latch = debug_state;
 121.311 +        if ( debug_state )
 121.312 +            v->arch.hvm_svm.vmcb->exception_intercepts |= mask;
 121.313 +        else
 121.314 +            v->arch.hvm_svm.vmcb->exception_intercepts &= ~mask;
 121.315 +    }
 121.316 +
 121.317      if ( v->arch.hvm_svm.launch_core != smp_processor_id() )
 121.318      {
 121.319          v->arch.hvm_svm.launch_core = smp_processor_id();
 121.320 @@ -957,12 +851,10 @@ static int svm_vcpu_initialise(struct vc
 121.321  {
 121.322      int rc;
 121.323  
 121.324 -    v->arch.schedule_tail    = arch_svm_do_resume;
 121.325 +    v->arch.schedule_tail    = svm_do_resume;
 121.326      v->arch.ctxt_switch_from = svm_ctxt_switch_from;
 121.327      v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
 121.328  
 121.329 -    v->arch.hvm_svm.saved_irq_vector = -1;
 121.330 -
 121.331      v->arch.hvm_svm.launch_core = -1;
 121.332  
 121.333      if ( (rc = svm_create_vmcb(v)) != 0 )
 121.334 @@ -997,6 +889,7 @@ static int svm_event_injection_faulted(s
 121.335  }
 121.336  
 121.337  static struct hvm_function_table svm_function_table = {
 121.338 +    .name                 = "SVM",
 121.339      .disable              = stop_svm,
 121.340      .vcpu_initialise      = svm_vcpu_initialise,
 121.341      .vcpu_destroy         = svm_vcpu_destroy,
 121.342 @@ -1026,16 +919,13 @@ void svm_npt_detect(void)
 121.343  {
 121.344      u32 eax, ebx, ecx, edx;
 121.345  
 121.346 -    /* check CPUID for nested paging support */
 121.347 +    /* Check CPUID for nested paging support. */
 121.348      cpuid(0x8000000A, &eax, &ebx, &ecx, &edx);
 121.349 -    if ( edx & 0x01 ) /* nested paging */
 121.350 +
 121.351 +    if ( !(edx & 1) && opt_hap_enabled )
 121.352      {
 121.353 -        hap_capable_system = 1;
 121.354 -    }
 121.355 -    else if ( opt_hap_enabled )
 121.356 -    {
 121.357 -        printk(" nested paging is not supported by this CPU.\n");
 121.358 -        hap_capable_system = 0; /* no nested paging, we disable flag. */
 121.359 +        printk("SVM: Nested paging is not supported by this CPU.\n");
 121.360 +        opt_hap_enabled = 0;
 121.361      }
 121.362  }
 121.363  
 121.364 @@ -1050,7 +940,7 @@ int start_svm(void)
 121.365      ecx = cpuid_ecx(0x80000001);
 121.366      boot_cpu_data.x86_capability[5] = ecx;
 121.367      
 121.368 -    if (!(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)))
 121.369 +    if ( !(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)) )
 121.370          return 0;
 121.371  
 121.372      /* check whether SVM feature is disabled in BIOS */
 121.373 @@ -1061,14 +951,13 @@ int start_svm(void)
 121.374          return 0;
 121.375      }
 121.376  
 121.377 -    if (!hsa[cpu])
 121.378 -        if (!(hsa[cpu] = alloc_host_save_area()))
 121.379 -            return 0;
 121.380 -    
 121.381 +    if ( ((hsa[cpu] = alloc_host_save_area()) == NULL) ||
 121.382 +         ((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
 121.383 +        return 0;
 121.384 +
 121.385      rdmsr(MSR_EFER, eax, edx);
 121.386      eax |= EFER_SVME;
 121.387      wrmsr(MSR_EFER, eax, edx);
 121.388 -    printk("AMD SVM Extension is enabled for cpu %d.\n", cpu );
 121.389  
 121.390      svm_npt_detect();
 121.391  
 121.392 @@ -1077,14 +966,13 @@ int start_svm(void)
 121.393      phys_hsa_lo = (u32) phys_hsa;
 121.394      phys_hsa_hi = (u32) (phys_hsa >> 32);    
 121.395      wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
 121.396 +
 121.397 +    root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
 121.398    
 121.399 -    if (!root_vmcb[cpu])
 121.400 -        if (!(root_vmcb[cpu] = alloc_vmcb())) 
 121.401 -            return 0;
 121.402 -    root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
 121.403 +    if ( cpu != 0 )
 121.404 +        return 1;
 121.405  
 121.406 -    if (cpu == 0)
 121.407 -        setup_vmcb_dump();
 121.408 +    setup_vmcb_dump();
 121.409  
 121.410      hvm_enable(&svm_function_table);
 121.411  
 121.412 @@ -1102,63 +990,17 @@ static int svm_do_nested_pgfault(paddr_t
 121.413      return 0;
 121.414  }
 121.415  
 121.416 -
 121.417 -static int svm_do_page_fault(unsigned long va, struct cpu_user_regs *regs) 
 121.418 -{
 121.419 -    HVM_DBG_LOG(DBG_LEVEL_VMMU, 
 121.420 -                "svm_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
 121.421 -                va, (unsigned long)current->arch.hvm_svm.vmcb->rip,
 121.422 -                (unsigned long)regs->error_code);
 121.423 -    return paging_fault(va, regs); 
 121.424 -}
 121.425 -
 121.426 -
 121.427  static void svm_do_no_device_fault(struct vmcb_struct *vmcb)
 121.428  {
 121.429      struct vcpu *v = current;
 121.430  
 121.431      setup_fpu(v);    
 121.432 -    vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
 121.433 +    vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
 121.434  
 121.435      if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
 121.436          vmcb->cr0 &= ~X86_CR0_TS;
 121.437  }
 121.438  
 121.439 -
 121.440 -static void svm_do_general_protection_fault(struct vcpu *v, 
 121.441 -                                            struct cpu_user_regs *regs) 
 121.442 -{
 121.443 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.444 -    unsigned long eip, error_code;
 121.445 -
 121.446 -    ASSERT(vmcb);
 121.447 -
 121.448 -    eip = vmcb->rip;
 121.449 -    error_code = vmcb->exitinfo1;
 121.450 -
 121.451 -    if (vmcb->idtr.limit == 0) {
 121.452 -        printk("Huh? We got a GP Fault with an invalid IDTR!\n");
 121.453 -        svm_dump_vmcb(__func__, vmcb);
 121.454 -        svm_dump_regs(__func__, regs);
 121.455 -        svm_dump_inst(svm_rip2pointer(v));
 121.456 -        domain_crash(v->domain);
 121.457 -        return;
 121.458 -    }
 121.459 -
 121.460 -    HVM_DBG_LOG(DBG_LEVEL_1,
 121.461 -                "svm_general_protection_fault: eip = %lx, erro_code = %lx",
 121.462 -                eip, error_code);
 121.463 -
 121.464 -    HVM_DBG_LOG(DBG_LEVEL_1, 
 121.465 -                "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
 121.466 -                (unsigned long)regs->eax, (unsigned long)regs->ebx,
 121.467 -                (unsigned long)regs->ecx, (unsigned long)regs->edx,
 121.468 -                (unsigned long)regs->esi, (unsigned long)regs->edi);
 121.469 -      
 121.470 -    /* Reflect it back into the guest */
 121.471 -    svm_inject_exception(v, TRAP_gp_fault, 1, error_code);
 121.472 -}
 121.473 -
 121.474  /* Reserved bits ECX: [31:14], [12:4], [2:1]*/
 121.475  #define SVM_VCPU_CPUID_L1_ECX_RESERVED 0xffffdff6
 121.476  /* Reserved bits EDX: [31:29], [27], [22:20], [18], [10] */
 121.477 @@ -1172,8 +1014,6 @@ static void svm_vmexit_do_cpuid(struct v
 121.478      struct vcpu *v = current;
 121.479      int inst_len;
 121.480  
 121.481 -    ASSERT(vmcb);
 121.482 -
 121.483      hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
 121.484  
 121.485      if ( input == 0x00000001 )
 121.486 @@ -1305,8 +1145,8 @@ static inline unsigned long *get_reg_p(
 121.487  }
 121.488  
 121.489  
 121.490 -static inline unsigned long get_reg(unsigned int gpreg, 
 121.491 -                                    struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
 121.492 +static inline unsigned long get_reg(
 121.493 +    unsigned int gpreg, struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
 121.494  {
 121.495      unsigned long *gp;
 121.496      gp = get_reg_p(gpreg, regs, vmcb);
 121.497 @@ -1314,8 +1154,9 @@ static inline unsigned long get_reg(unsi
 121.498  }
 121.499  
 121.500  
 121.501 -static inline void set_reg(unsigned int gpreg, unsigned long value, 
 121.502 -                           struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
 121.503 +static inline void set_reg(
 121.504 +    unsigned int gpreg, unsigned long value, 
 121.505 +    struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
 121.506  {
 121.507      unsigned long *gp;
 121.508      gp = get_reg_p(gpreg, regs, vmcb);
 121.509 @@ -1585,7 +1426,6 @@ static void svm_io_instruction(struct vc
 121.510      ioio_info_t info;
 121.511      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.512  
 121.513 -    ASSERT(vmcb);
 121.514      pio_opp = &current->arch.hvm_vcpu.io_op;
 121.515      pio_opp->instr = INSTR_PIO;
 121.516      pio_opp->flags = 0;
 121.517 @@ -1729,228 +1569,97 @@ static void svm_io_instruction(struct vc
 121.518      }
 121.519  }
 121.520  
 121.521 -static int npt_set_cr0(unsigned long value) 
 121.522 -{
 121.523 -    struct vcpu *v = current;
 121.524 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.525 -  
 121.526 -    ASSERT(vmcb);
 121.527 -
 121.528 -    /* ET is reserved and should be always be 1*/
 121.529 -    value |= X86_CR0_ET;
 121.530 -
 121.531 -    /* Check whether the guest is about to turn on long mode. 
 121.532 -     * If it is, set EFER.LME and EFER.LMA.  Update the shadow EFER.LMA
 121.533 -     * bit too, so svm_long_mode_enabled() will work.
 121.534 -     */
 121.535 -    if ( (value & X86_CR0_PG) && svm_lme_is_set(v) &&
 121.536 -         (vmcb->cr4 & X86_CR4_PAE) && (vmcb->cr0 & X86_CR0_PE) )
 121.537 -    {
 121.538 -        v->arch.hvm_svm.cpu_shadow_efer |= EFER_LMA;
 121.539 -        vmcb->efer |= EFER_LMA | EFER_LME;
 121.540 -    }
 121.541 -
 121.542 -    /* Whenever CR0.PG is cleared under long mode, LMA will be cleared 
 121.543 -     * immediatly. We emulate this process for svm_long_mode_enabled().
 121.544 -     */
 121.545 -    if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
 121.546 -    {
 121.547 -        if ( svm_long_mode_enabled(v) )
 121.548 -        {
 121.549 -            v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
 121.550 -        }
 121.551 -    }
 121.552 -    
 121.553 -    vmcb->cr0 = value | X86_CR0_WP;
 121.554 -    v->arch.hvm_svm.cpu_shadow_cr0 = value;
 121.555 -
 121.556 -    /* TS cleared? Then initialise FPU now. */
 121.557 -    if ( !(value & X86_CR0_TS) ) {
 121.558 -        setup_fpu(v);
 121.559 -        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
 121.560 -    }
 121.561 -    
 121.562 -    paging_update_paging_modes(v);
 121.563 -    
 121.564 -    return 1;
 121.565 -}
 121.566 -
 121.567  static int svm_set_cr0(unsigned long value)
 121.568  {
 121.569      struct vcpu *v = current;
 121.570 -    unsigned long mfn;
 121.571 -    int paging_enabled;
 121.572 +    unsigned long mfn, old_value = v->arch.hvm_svm.cpu_shadow_cr0;
 121.573      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.574      unsigned long old_base_mfn;
 121.575    
 121.576 -    ASSERT(vmcb);
 121.577 +    HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
 121.578 +
 121.579 +    /* ET is reserved and should be always be 1. */
 121.580 +    value |= X86_CR0_ET;
 121.581  
 121.582 -    /* We don't want to lose PG.  ET is reserved and should be always be 1*/
 121.583 -    paging_enabled = svm_paging_enabled(v);
 121.584 -    value |= X86_CR0_ET;
 121.585 -    vmcb->cr0 = value | X86_CR0_PG | X86_CR0_WP;
 121.586 -    v->arch.hvm_svm.cpu_shadow_cr0 = value;
 121.587 +    if ( (value & (X86_CR0_PE|X86_CR0_PG)) == X86_CR0_PG )
 121.588 +    {
 121.589 +        svm_inject_exception(v, TRAP_gp_fault, 1, 0);
 121.590 +        return 0;
 121.591 +    }
 121.592  
 121.593      /* TS cleared? Then initialise FPU now. */
 121.594      if ( !(value & X86_CR0_TS) )
 121.595      {
 121.596          setup_fpu(v);
 121.597 -        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
 121.598 +        vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
 121.599      }
 121.600  
 121.601 -    HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
 121.602 -
 121.603 -    if ( ((value & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG))
 121.604 -         && !paging_enabled ) 
 121.605 +    if ( (value & X86_CR0_PG) && !(old_value & X86_CR0_PG) )
 121.606      {
 121.607 -        /* The guest CR3 must be pointing to the guest physical. */
 121.608 -        mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
 121.609 -        if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
 121.610 -        {
 121.611 -            gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", 
 121.612 -                     v->arch.hvm_svm.cpu_cr3, mfn);
 121.613 -            domain_crash(v->domain);
 121.614 -            return 0;
 121.615 -        }
 121.616 -
 121.617  #if defined(__x86_64__)
 121.618 -        if ( svm_lme_is_set(v) && !svm_cr4_pae_is_set(v) )
 121.619 -        {
 121.620 -            HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
 121.621 -            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
 121.622 -        }
 121.623 -
 121.624          if ( svm_lme_is_set(v) )
 121.625          {
 121.626 +            if ( !svm_cr4_pae_is_set(v) )
 121.627 +            {
 121.628 +                HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
 121.629 +                svm_inject_exception(v, TRAP_gp_fault, 1, 0);
 121.630 +                return 0;
 121.631 +            }
 121.632              HVM_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode\n");
 121.633              v->arch.hvm_svm.cpu_shadow_efer |= EFER_LMA;
 121.634              vmcb->efer |= EFER_LMA | EFER_LME;
 121.635          }
 121.636  #endif  /* __x86_64__ */
 121.637  
 121.638 -        /* Now arch.guest_table points to machine physical. */
 121.639 -        old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
 121.640 -        v->arch.guest_table = pagetable_from_pfn(mfn);
 121.641 -        if ( old_base_mfn )
 121.642 -            put_page(mfn_to_page(old_base_mfn));
 121.643 -        paging_update_paging_modes(v);
 121.644 -
 121.645 -        HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
 121.646 -                    (unsigned long) (mfn << PAGE_SHIFT));
 121.647 -    }
 121.648 +        if ( !paging_mode_hap(v->domain) )
 121.649 +        {
 121.650 +            /* The guest CR3 must be pointing to the guest physical. */
 121.651 +            mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
 121.652 +            if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
 121.653 +            {
 121.654 +                gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", 
 121.655 +                         v->arch.hvm_svm.cpu_cr3, mfn);
 121.656 +                domain_crash(v->domain);
 121.657 +                return 0;
 121.658 +            }
 121.659  
 121.660 -    if ( !((value & X86_CR0_PE) && (value & X86_CR0_PG)) && paging_enabled )
 121.661 -        if ( v->arch.hvm_svm.cpu_cr3 ) {
 121.662 -            put_page(mfn_to_page(get_mfn_from_gpfn(
 121.663 -                v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT)));
 121.664 -            v->arch.guest_table = pagetable_null();
 121.665 -        }
 121.666 +            /* Now arch.guest_table points to machine physical. */
 121.667 +            old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
 121.668 +            v->arch.guest_table = pagetable_from_pfn(mfn);
 121.669 +            if ( old_base_mfn )
 121.670 +                put_page(mfn_to_page(old_base_mfn));
 121.671  
 121.672 -    /*
 121.673 -     * SVM implements paged real-mode and when we return to real-mode
 121.674 -     * we revert back to the physical mappings that the domain builder
 121.675 -     * created.
 121.676 -     */
 121.677 -    if ((value & X86_CR0_PE) == 0) {
 121.678 -        if (value & X86_CR0_PG) {
 121.679 -            svm_inject_exception(v, TRAP_gp_fault, 1, 0);
 121.680 -            return 0;
 121.681 +            HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
 121.682 +                        (unsigned long) (mfn << PAGE_SHIFT));
 121.683          }
 121.684 -        paging_update_paging_modes(v);
 121.685      }
 121.686 -    else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
 121.687 +    else if ( !(value & X86_CR0_PG) && (old_value & X86_CR0_PG) )
 121.688      {
 121.689 +        /* When CR0.PG is cleared, LMA is cleared immediately. */
 121.690          if ( svm_long_mode_enabled(v) )
 121.691          {
 121.692              vmcb->efer &= ~(EFER_LME | EFER_LMA);
 121.693              v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
 121.694          }
 121.695 -        /* we should take care of this kind of situation */
 121.696 +
 121.697 +        if ( !paging_mode_hap(v->domain) && v->arch.hvm_svm.cpu_cr3 )
 121.698 +        {
 121.699 +            put_page(mfn_to_page(get_mfn_from_gpfn(
 121.700 +                v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT)));
 121.701 +            v->arch.guest_table = pagetable_null();
 121.702 +        }
 121.703 +    }
 121.704 +
 121.705 +    vmcb->cr0 = v->arch.hvm_svm.cpu_shadow_cr0 = value;
 121.706 +    if ( !paging_mode_hap(v->domain) )
 121.707 +        vmcb->cr0 |= X86_CR0_PG | X86_CR0_WP;
 121.708 +
 121.709 +    if ( (value ^ old_value) & X86_CR0_PG )
 121.710          paging_update_paging_modes(v);
 121.711 -    }
 121.712  
 121.713      return 1;
 121.714  }
 121.715  
 121.716 -//
 121.717 -// nested paging functions
 121.718 -//
 121.719 -
 121.720 -static int npt_mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
 121.721 -{  
 121.722 -    unsigned long value;
 121.723 -    struct vcpu *v = current;
 121.724 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.725 -    struct vlapic *vlapic = vcpu_vlapic(v);
 121.726 -
 121.727 -    ASSERT(vmcb);
 121.728 -
 121.729 -    value = get_reg(gpreg, regs, vmcb);
 121.730 -
 121.731 -    switch (cr) {
 121.732 -    case 0:
 121.733 -        return npt_set_cr0(value);
 121.734 -
 121.735 -    case 3:
 121.736 -        vmcb->cr3 = value;
 121.737 -        v->arch.hvm_svm.cpu_cr3 = value;
 121.738 -        break;
 121.739 -
 121.740 -    case 4: /* CR4 */
 121.741 -        vmcb->cr4 = value;
 121.742 -        v->arch.hvm_svm.cpu_shadow_cr4 = value;
 121.743 -        paging_update_paging_modes(v);
 121.744 -        break;
 121.745 -
 121.746 -    case 8:
 121.747 -        vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
 121.748 -        vmcb->vintr.fields.tpr = value & 0x0F;
 121.749 -        break;
 121.750 -
 121.751 -    default:
 121.752 -        gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
 121.753 -        domain_crash(v->domain);
 121.754 -        return 0;
 121.755 -    }
 121.756 -    
 121.757 -    return 1;
 121.758 -}
 121.759 -
 121.760 -static void npt_mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
 121.761 -{
 121.762 -    unsigned long value = 0;
 121.763 -    struct vcpu *v = current;
 121.764 -    struct vmcb_struct *vmcb;
 121.765 -    struct vlapic *vlapic = vcpu_vlapic(v);
 121.766 -
 121.767 -    vmcb = v->arch.hvm_svm.vmcb;
 121.768 -    ASSERT(vmcb);
 121.769 -
 121.770 -    switch(cr) {
 121.771 -    case 0:
 121.772 -        value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr0;
 121.773 -        break;
 121.774 -    case 2:
 121.775 -        value = vmcb->cr2;
 121.776 -        break;
 121.777 -    case 3:
 121.778 -        value = (unsigned long) v->arch.hvm_svm.cpu_cr3;
 121.779 -        break;
 121.780 -    case 4:
 121.781 -        value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
 121.782 -       break;
 121.783 -    case 8:
 121.784 -        value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
 121.785 -        value = (value & 0xF0) >> 4;
 121.786 -        break;
 121.787 -    default:
 121.788 -        domain_crash(v->domain);
 121.789 -        return;
 121.790 -    }
 121.791 -    
 121.792 -    set_reg(gp, value, regs, vmcb);
 121.793 -}
 121.794 -
 121.795  /*
 121.796   * Read from control registers. CR0 and CR4 are read from the shadow.
 121.797   */
 121.798 @@ -1959,30 +1668,21 @@ static void mov_from_cr(int cr, int gp, 
 121.799      unsigned long value = 0;
 121.800      struct vcpu *v = current;
 121.801      struct vlapic *vlapic = vcpu_vlapic(v);
 121.802 -    struct vmcb_struct *vmcb;
 121.803 -
 121.804 -    vmcb = v->arch.hvm_svm.vmcb;
 121.805 -    ASSERT(vmcb);
 121.806 +    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.807  
 121.808      switch ( cr )
 121.809      {
 121.810      case 0:
 121.811          value = v->arch.hvm_svm.cpu_shadow_cr0;
 121.812 -        if (svm_dbg_on)
 121.813 -            printk("CR0 read =%lx \n", value );
 121.814          break;
 121.815      case 2:
 121.816          value = vmcb->cr2;
 121.817          break;
 121.818      case 3:
 121.819 -        value = (unsigned long) v->arch.hvm_svm.cpu_cr3;
 121.820 -        if (svm_dbg_on)
 121.821 -            printk("CR3 read =%lx \n", value );
 121.822 +        value = (unsigned long)v->arch.hvm_svm.cpu_cr3;
 121.823          break;
 121.824      case 4:
 121.825 -        value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
 121.826 -        if (svm_dbg_on)
 121.827 -            printk("CR4 read=%lx\n", value);
 121.828 +        value = (unsigned long)v->arch.hvm_svm.cpu_shadow_cr4;
 121.829          break;
 121.830      case 8:
 121.831          value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
 121.832 @@ -2019,24 +1719,27 @@ static int mov_to_cr(int gpreg, int cr, 
 121.833      HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
 121.834      HVM_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current);
 121.835  
 121.836 -    switch (cr) 
 121.837 +    switch ( cr )
 121.838      {
 121.839      case 0: 
 121.840 -        if (svm_dbg_on)
 121.841 -            printk("CR0 write =%lx \n", value );
 121.842          return svm_set_cr0(value);
 121.843  
 121.844 -    case 3: 
 121.845 -        if (svm_dbg_on)
 121.846 -            printk("CR3 write =%lx \n", value );
 121.847 +    case 3:
 121.848 +        if ( paging_mode_hap(v->domain) )
 121.849 +        {
 121.850 +            vmcb->cr3 = v->arch.hvm_svm.cpu_cr3 = value;
 121.851 +            break;
 121.852 +        }
 121.853 +
 121.854          /* If paging is not enabled yet, simply copy the value to CR3. */
 121.855 -        if (!svm_paging_enabled(v)) {
 121.856 +        if ( !svm_paging_enabled(v) )
 121.857 +        {
 121.858              v->arch.hvm_svm.cpu_cr3 = value;
 121.859              break;
 121.860          }
 121.861  
 121.862          /* We make a new one if the shadow does not exist. */
 121.863 -        if (value == v->arch.hvm_svm.cpu_cr3) 
 121.864 +        if ( value == v->arch.hvm_svm.cpu_cr3 )
 121.865          {
 121.866              /* 
 121.867               * This is simple TLB flush, implying the guest has 
 121.868 @@ -2044,7 +1747,7 @@ static int mov_to_cr(int gpreg, int cr, 
 121.869               * We simply invalidate the shadow.
 121.870               */
 121.871              mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
 121.872 -            if (mfn != pagetable_get_pfn(v->arch.guest_table))
 121.873 +            if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
 121.874                  goto bad_cr3;
 121.875              paging_update_cr3(v);
 121.876          }
 121.877 @@ -2056,13 +1759,13 @@ static int mov_to_cr(int gpreg, int cr, 
 121.878               */
 121.879              HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
 121.880              mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
 121.881 -            if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
 121.882 +            if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
 121.883                  goto bad_cr3;
 121.884  
 121.885              old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
 121.886              v->arch.guest_table = pagetable_from_pfn(mfn);
 121.887  
 121.888 -            if (old_base_mfn)
 121.889 +            if ( old_base_mfn )
 121.890                  put_page(mfn_to_page(old_base_mfn));
 121.891  
 121.892              v->arch.hvm_svm.cpu_cr3 = value;
 121.893 @@ -2072,9 +1775,13 @@ static int mov_to_cr(int gpreg, int cr, 
 121.894          break;
 121.895  
 121.896      case 4: /* CR4 */
 121.897 -        if (svm_dbg_on)
 121.898 -            printk( "write cr4=%lx, cr0=%lx\n", 
 121.899 -                    value,  v->arch.hvm_svm.cpu_shadow_cr0 );
 121.900 +        if ( paging_mode_hap(v->domain) )
 121.901 +        {
 121.902 +            vmcb->cr4 = v->arch.hvm_svm.cpu_shadow_cr4 = value;
 121.903 +            paging_update_paging_modes(v);
 121.904 +            break;
 121.905 +        }
 121.906 +
 121.907          old_cr = v->arch.hvm_svm.cpu_shadow_cr4;
 121.908          if ( value & X86_CR4_PAE && !(old_cr & X86_CR4_PAE) )
 121.909          {
 121.910 @@ -2154,18 +1861,18 @@ static int svm_cr_access(struct vcpu *v,
 121.911  {
 121.912      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 121.913      int inst_len = 0;
 121.914 -    int index;
 121.915 -    unsigned int gpreg;
 121.916 -    unsigned long value;
 121.917 +    int index,addr_size,i;
 121.918 +    unsigned int gpreg,offset;
 121.919 +    unsigned long value,addr;
 121.920      u8 buffer[MAX_INST_LEN];   
 121.921      u8 prefix = 0;
 121.922 +    u8 modrm;
 121.923 +    enum x86_segment seg;
 121.924      int result = 1;
 121.925      enum instruction_index list_a[] = {INSTR_MOV2CR, INSTR_CLTS, INSTR_LMSW};
 121.926      enum instruction_index list_b[] = {INSTR_MOVCR2, INSTR_SMSW};
 121.927      enum instruction_index match;
 121.928  
 121.929 -    ASSERT(vmcb);
 121.930 -
 121.931      inst_copy_from_guest(buffer, svm_rip2pointer(v), sizeof(buffer));
 121.932  
 121.933      /* get index to first actual instruction byte - as we will need to know 
 121.934 @@ -2197,60 +1904,83 @@ static int svm_cr_access(struct vcpu *v,
 121.935      {
 121.936      case INSTR_MOV2CR:
 121.937          gpreg = decode_src_reg(prefix, buffer[index+2]);
 121.938 -        if ( paging_mode_hap(v->domain) )
 121.939 -            result = npt_mov_to_cr(gpreg, cr, regs);
 121.940 -        else
 121.941 -            result = mov_to_cr(gpreg, cr, regs);
 121.942 +        result = mov_to_cr(gpreg, cr, regs);
 121.943          break;
 121.944  
 121.945      case INSTR_MOVCR2:
 121.946          gpreg = decode_src_reg(prefix, buffer[index+2]);
 121.947 -        if ( paging_mode_hap(v->domain) )
 121.948 -            npt_mov_from_cr(cr, gpreg, regs);
 121.949 -        else
 121.950 -            mov_from_cr(cr, gpreg, regs);
 121.951 +        mov_from_cr(cr, gpreg, regs);
 121.952          break;
 121.953  
 121.954      case INSTR_CLTS:
 121.955          /* TS being cleared means that it's time to restore fpu state. */
 121.956          setup_fpu(current);
 121.957 -        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
 121.958 +        vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
 121.959          vmcb->cr0 &= ~X86_CR0_TS; /* clear TS */
 121.960          v->arch.hvm_svm.cpu_shadow_cr0 &= ~X86_CR0_TS; /* clear TS */
 121.961          break;
 121.962  
 121.963      case INSTR_LMSW:
 121.964 -        if (svm_dbg_on)
 121.965 -            svm_dump_inst(svm_rip2pointer(v));
 121.966 -        
 121.967          gpreg = decode_src_reg(prefix, buffer[index+2]);
 121.968          value = get_reg(gpreg, regs, vmcb) & 0xF;
 121.969 -
 121.970 -        if (svm_dbg_on)
 121.971 -            printk("CR0-LMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg, 
 121.972 -                   inst_len);
 121.973 -
 121.974          value = (v->arch.hvm_svm.cpu_shadow_cr0 & ~0xF) | value;
 121.975 -
 121.976 -        if (svm_dbg_on)
 121.977 -            printk("CR0-LMSW CR0 - New value=%lx\n", value);
 121.978 -
 121.979 -        if ( paging_mode_hap(v->domain) )
 121.980 -            result = npt_set_cr0(value);
 121.981 -        else
 121.982 -            result = svm_set_cr0(value);
 121.983 +        result = svm_set_cr0(value);
 121.984          break;
 121.985  
 121.986      case INSTR_SMSW:
 121.987 -        if (svm_dbg_on)
 121.988 -            svm_dump_inst(svm_rip2pointer(v));
 121.989 -        value = v->arch.hvm_svm.cpu_shadow_cr0;
 121.990 -        gpreg = decode_src_reg(prefix, buffer[index+2]);
 121.991 -        set_reg(gpreg, value, regs, vmcb);
 121.992 -
 121.993 -        if (svm_dbg_on)
 121.994 -            printk("CR0-SMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg, 
 121.995 -                   inst_len);
 121.996 +        value = v->arch.hvm_svm.cpu_shadow_cr0 & 0xFFFF;
 121.997 +        modrm = buffer[index+2];
 121.998 +        addr_size = svm_guest_x86_mode( v );
 121.999 +        if ( likely((modrm & 0xC0) >> 6 == 3) )
121.1000 +        {
121.1001 +            gpreg = decode_src_reg(prefix, modrm);
121.1002 +            set_reg(gpreg, value, regs, vmcb);
121.1003 +        }
121.1004 +        /*
121.1005 +         * For now, only implement decode of the offset mode, since that's the
121.1006 +         * only mode observed in a real-world OS. This code is also making the
121.1007 +         * assumption that we'll never hit this code in long mode.
121.1008 +         */
121.1009 +        else if ( (modrm == 0x26) || (modrm == 0x25) )
121.1010 +        {   
121.1011 +            seg = x86_seg_ds;
121.1012 +            i = index;
121.1013 +            /* Segment or address size overrides? */
121.1014 +            while ( i-- )
121.1015 +            {
121.1016 +                switch ( buffer[i] )
121.1017 +                {
121.1018 +                   case 0x26: seg = x86_seg_es; break;
121.1019 +                   case 0x2e: seg = x86_seg_cs; break;
121.1020 +                   case 0x36: seg = x86_seg_ss; break;
121.1021 +                   case 0x64: seg = x86_seg_fs; break;
121.1022 +                   case 0x65: seg = x86_seg_gs; break;
121.1023 +                   case 0x67: addr_size ^= 6;   break;
121.1024 +                }
121.1025 +            }
121.1026 +            /* Bail unless this really is a seg_base + offset case */
121.1027 +            if ( ((modrm == 0x26) && (addr_size == 4)) ||
121.1028 +                 ((modrm == 0x25) && (addr_size == 2)) )
121.1029 +            {
121.1030 +                gdprintk(XENLOG_ERR, "SMSW emulation at guest address: "
121.1031 +                         "%lx failed due to unhandled addressing mode."
121.1032 +                         "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
121.1033 +                domain_crash(v->domain);
121.1034 +            }
121.1035 +            inst_len += addr_size;
121.1036 +            offset = *(( unsigned int *) ( void *) &buffer[index + 3]);
121.1037 +            offset = ( addr_size == 4 ) ? offset : ( offset & 0xFFFF );
121.1038 +            addr = hvm_get_segment_base(v, seg);
121.1039 +            addr += offset;
121.1040 +            hvm_copy_to_guest_virt(addr,&value,2);
121.1041 +        }
121.1042 +        else
121.1043 +        {
121.1044 +           gdprintk(XENLOG_ERR, "SMSW emulation at guest address: %lx "
121.1045 +                    "failed due to unhandled addressing mode!"
121.1046 +                    "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
121.1047 +           domain_crash(v->domain);
121.1048 +        }
121.1049          break;
121.1050  
121.1051      default:
121.1052 @@ -2272,8 +2002,6 @@ static inline void svm_do_msr_access(
121.1053      u64 msr_content=0;
121.1054      u32 ecx = regs->ecx, eax, edx;
121.1055  
121.1056 -    ASSERT(vmcb);
121.1057 -
121.1058      HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x, exitinfo = %lx",
121.1059                  ecx, (u32)regs->eax, (u32)regs->edx,
121.1060                  (unsigned long)vmcb->exitinfo1);
121.1061 @@ -2357,7 +2085,6 @@ static inline void svm_do_msr_access(
121.1062      __update_guest_eip(vmcb, inst_len);
121.1063  }
121.1064  
121.1065 -
121.1066  static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
121.1067  {
121.1068      __update_guest_eip(vmcb, 1);
121.1069 @@ -2373,7 +2100,6 @@ static inline void svm_vmexit_do_hlt(str
121.1070      hvm_hlt(vmcb->rflags);
121.1071  }
121.1072  
121.1073 -
121.1074  static void svm_vmexit_do_invd(struct vcpu *v)
121.1075  {
121.1076      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
121.1077 @@ -2387,48 +2113,12 @@ static void svm_vmexit_do_invd(struct vc
121.1078      /* Tell the user that we did this - just in case someone runs some really 
121.1079       * weird operating system and wants to know why it's not working...
121.1080       */
121.1081 -    printk("INVD instruction intercepted - ignored\n");
121.1082 +    gdprintk(XENLOG_WARNING, "INVD instruction intercepted - ignored\n");
121.1083      
121.1084      inst_len = __get_instruction_length(v, INSTR_INVD, NULL);
121.1085      __update_guest_eip(vmcb, inst_len);
121.1086  }    
121.1087          
121.1088 -
121.1089 -
121.1090 -
121.1091 -#ifdef XEN_DEBUGGER
121.1092 -static void svm_debug_save_cpu_user_regs(struct vmcb_struct *vmcb, 
121.1093 -                                         struct cpu_user_regs *regs)
121.1094 -{
121.1095 -    regs->eip = vmcb->rip;
121.1096 -    regs->esp = vmcb->rsp;
121.1097 -    regs->eflags = vmcb->rflags;
121.1098 -
121.1099 -    regs->xcs = vmcb->cs.sel;
121.1100 -    regs->xds = vmcb->ds.sel;
121.1101 -    regs->xes = vmcb->es.sel;
121.1102 -    regs->xfs = vmcb->fs.sel;
121.1103 -    regs->xgs = vmcb->gs.sel;
121.1104 -    regs->xss = vmcb->ss.sel;
121.1105 -}
121.1106 -
121.1107 -
121.1108 -static void svm_debug_restore_cpu_user_regs(struct cpu_user_regs *regs)
121.1109 -{
121.1110 -    vmcb->ss.sel   = regs->xss;
121.1111 -    vmcb->rsp      = regs->esp;
121.1112 -    vmcb->rflags   = regs->eflags;
121.1113 -    vmcb->cs.sel   = regs->xcs;
121.1114 -    vmcb->rip      = regs->eip;
121.1115 -
121.1116 -    vmcb->gs.sel = regs->xgs;
121.1117 -    vmcb->fs.sel = regs->xfs;
121.1118 -    vmcb->es.sel = regs->xes;
121.1119 -    vmcb->ds.sel = regs->xds;
121.1120 -}
121.1121 -#endif
121.1122 -
121.1123 -
121.1124  void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
121.1125  {
121.1126      struct vcpu *v = current;
121.1127 @@ -2494,18 +2184,11 @@ void svm_handle_invlpg(const short invlp
121.1128   *
121.1129   * returns 0 on success, non-zero otherwise
121.1130   */
121.1131 -static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v, 
121.1132 -                                            struct cpu_user_regs *regs)
121.1133 +static int svm_reset_to_realmode(struct vcpu *v, 
121.1134 +                                 struct cpu_user_regs *regs)
121.1135  {
121.1136 -    struct vmcb_struct *vmcb;
121.1137 +    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
121.1138  
121.1139 -    ASSERT(v);
121.1140 -    ASSERT(regs);
121.1141 -
121.1142 -    vmcb = v->arch.hvm_svm.vmcb;
121.1143 -
121.1144 -    ASSERT(vmcb);
121.1145 -    
121.1146      /* clear the vmcb and user regs */
121.1147      memset(regs, 0, sizeof(struct cpu_user_regs));
121.1148     
121.1149 @@ -2587,449 +2270,65 @@ static int svm_do_vmmcall_reset_to_realm
121.1150      return 0;
121.1151  }
121.1152  
121.1153 -
121.1154 -void svm_dump_inst(unsigned long eip)
121.1155 -{
121.1156 -    u8 opcode[256];
121.1157 -    unsigned long ptr;
121.1158 -    int len;
121.1159 -    int i;
121.1160 -
121.1161 -    ptr = eip & ~0xff;
121.1162 -    len = 0;
121.1163 -
121.1164 -    if (hvm_copy_from_guest_virt(opcode, ptr, sizeof(opcode)) == 0)
121.1165 -        len = sizeof(opcode);
121.1166 -
121.1167 -    printk("Code bytes around(len=%d) %lx:", len, eip);
121.1168 -    for (i = 0; i < len; i++)
121.1169 -    {
121.1170 -        if ((i & 0x0f) == 0)
121.1171 -            printk("\n%08lx:", ptr+i);
121.1172 -
121.1173 -        printk("%02x ", opcode[i]);
121.1174 -    }
121.1175 -
121.1176 -    printk("\n");
121.1177 -}
121.1178 -
121.1179 -
121.1180 -void svm_dump_regs(const char *from, struct cpu_user_regs *regs)
121.1181 -{
121.1182 -    struct vcpu *v = current;
121.1183 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
121.1184 -    unsigned long pt = v->arch.hvm_vcpu.hw_cr3;
121.1185 -
121.1186 -    printk("%s: guest registers from %s:\n", __func__, from);
121.1187 -#if defined (__x86_64__)
121.1188 -    printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",
121.1189 -           regs->rax, regs->rbx, regs->rcx);
121.1190 -    printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
121.1191 -           regs->rdx, regs->rsi, regs->rdi);
121.1192 -    printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",
121.1193 -           regs->rbp, regs->rsp, regs->r8);
121.1194 -    printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
121.1195 -           regs->r9,  regs->r10, regs->r11);
121.1196 -    printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
121.1197 -           regs->r12, regs->r13, regs->r14);
121.1198 -    printk("r15: %016lx   cr0: %016lx   cr3: %016lx\n",
121.1199 -           regs->r15, v->arch.hvm_svm.cpu_shadow_cr0, vmcb->cr3);
121.1200 -#else
121.1201 -    printk("eax: %08x, ebx: %08x, ecx: %08x, edx: %08x\n", 
121.1202 -           regs->eax, regs->ebx, regs->ecx, regs->edx);
121.1203 -    printk("edi: %08x, esi: %08x, ebp: %08x, esp: %08x\n", 
121.1204 -           regs->edi, regs->esi, regs->ebp, regs->esp);
121.1205 -    printk("%s: guest cr0: %lx\n", __func__, 
121.1206 -           v->arch.hvm_svm.cpu_shadow_cr0);
121.1207 -    printk("guest CR3 = %llx\n", vmcb->cr3);
121.1208 -#endif
121.1209 -    printk("%s: pt = %lx\n", __func__, pt);
121.1210 -}
121.1211 -
121.1212 -
121.1213 -void svm_dump_host_regs(const char *from)
121.1214 -{
121.1215 -    struct vcpu *v = current;
121.1216 -    unsigned long pt = pt = pagetable_get_paddr(v->arch.monitor_table);
121.1217 -    unsigned long cr3, cr0;
121.1218 -    printk("Host registers at %s\n", from);
121.1219 -
121.1220 -    __asm__ __volatile__ ("\tmov %%cr0,%0\n"
121.1221 -                          "\tmov %%cr3,%1\n"
121.1222 -                          : "=r" (cr0), "=r"(cr3));
121.1223 -    printk("%s: pt = %lx, cr3 = %lx, cr0 = %lx\n", __func__, pt, cr3, cr0);
121.1224 -}
121.1225 -
121.1226 -#ifdef SVM_EXTRA_DEBUG
121.1227 -static char *exit_reasons[] = {
121.1228 -    [VMEXIT_CR0_READ] = "CR0_READ",
121.1229 -    [VMEXIT_CR1_READ] = "CR1_READ",
121.1230 -    [VMEXIT_CR2_READ] = "CR2_READ",
121.1231 -    [VMEXIT_CR3_READ] = "CR3_READ",
121.1232 -    [VMEXIT_CR4_READ] = "CR4_READ",
121.1233 -    [VMEXIT_CR5_READ] = "CR5_READ",
121.1234 -    [VMEXIT_CR6_READ] = "CR6_READ",
121.1235 -    [VMEXIT_CR7_READ] = "CR7_READ",
121.1236 -    [VMEXIT_CR8_READ] = "CR8_READ",
121.1237 -    [VMEXIT_CR9_READ] = "CR9_READ",
121.1238 -    [VMEXIT_CR10_READ] = "CR10_READ",
121.1239 -    [VMEXIT_CR11_READ] = "CR11_READ",
121.1240 -    [VMEXIT_CR12_READ] = "CR12_READ",
121.1241 -    [VMEXIT_CR13_READ] = "CR13_READ",
121.1242 -    [VMEXIT_CR14_READ] = "CR14_READ",
121.1243 -    [VMEXIT_CR15_READ] = "CR15_READ",
121.1244 -    [VMEXIT_CR0_WRITE] = "CR0_WRITE",
121.1245 -    [VMEXIT_CR1_WRITE] = "CR1_WRITE",
121.1246 -    [VMEXIT_CR2_WRITE] = "CR2_WRITE",
121.1247 -    [VMEXIT_CR3_WRITE] = "CR3_WRITE",
121.1248 -    [VMEXIT_CR4_WRITE] = "CR4_WRITE",
121.1249 -    [VMEXIT_CR5_WRITE] = "CR5_WRITE",
121.1250 -    [VMEXIT_CR6_WRITE] = "CR6_WRITE",
121.1251 -    [VMEXIT_CR7_WRITE] = "CR7_WRITE",
121.1252 -    [VMEXIT_CR8_WRITE] = "CR8_WRITE",
121.1253 -    [VMEXIT_CR9_WRITE] = "CR9_WRITE",
121.1254 -    [VMEXIT_CR10_WRITE] = "CR10_WRITE",
121.1255 -    [VMEXIT_CR11_WRITE] = "CR11_WRITE",
121.1256 -    [VMEXIT_CR12_WRITE] = "CR12_WRITE",
121.1257 -    [VMEXIT_CR13_WRITE] = "CR13_WRITE",
121.1258 -    [VMEXIT_CR14_WRITE] = "CR14_WRITE",
121.1259 -    [VMEXIT_CR15_WRITE] = "CR15_WRITE",
121.1260 -    [VMEXIT_DR0_READ] = "DR0_READ",
121.1261 -    [VMEXIT_DR1_READ] = "DR1_READ",
121.1262 -    [VMEXIT_DR2_READ] = "DR2_READ",
121.1263 -    [VMEXIT_DR3_READ] = "DR3_READ",
121.1264 -    [VMEXIT_DR4_READ] = "DR4_READ",
121.1265 -    [VMEXIT_DR5_READ] = "DR5_READ",
121.1266 -    [VMEXIT_DR6_READ] = "DR6_READ",
121.1267 -    [VMEXIT_DR7_READ] = "DR7_READ",
121.1268 -    [VMEXIT_DR8_READ] = "DR8_READ",
121.1269 -    [VMEXIT_DR9_READ] = "DR9_READ",
121.1270 -    [VMEXIT_DR10_READ] = "DR10_READ",
121.1271 -    [VMEXIT_DR11_READ] = "DR11_READ",
121.1272 -    [VMEXIT_DR12_READ] = "DR12_READ",
121.1273 -    [VMEXIT_DR13_READ] = "DR13_READ",
121.1274 -    [VMEXIT_DR14_READ] = "DR14_READ",
121.1275 -    [VMEXIT_DR15_READ] = "DR15_READ",
121.1276 -    [VMEXIT_DR0_WRITE] = "DR0_WRITE",
121.1277 -    [VMEXIT_DR1_WRITE] = "DR1_WRITE",
121.1278 -    [VMEXIT_DR2_WRITE] = "DR2_WRITE",
121.1279 -    [VMEXIT_DR3_WRITE] = "DR3_WRITE",
121.1280 -    [VMEXIT_DR4_WRITE] = "DR4_WRITE",
121.1281 -    [VMEXIT_DR5_WRITE] = "DR5_WRITE",
121.1282 -    [VMEXIT_DR6_WRITE] = "DR6_WRITE",
121.1283 -    [VMEXIT_DR7_WRITE] = "DR7_WRITE",
121.1284 -    [VMEXIT_DR8_WRITE] = "DR8_WRITE",
121.1285 -    [VMEXIT_DR9_WRITE] = "DR9_WRITE",
121.1286 -    [VMEXIT_DR10_WRITE] = "DR10_WRITE",
121.1287 -    [VMEXIT_DR11_WRITE] = "DR11_WRITE",
121.1288 -    [VMEXIT_DR12_WRITE] = "DR12_WRITE",
121.1289 -    [VMEXIT_DR13_WRITE] = "DR13_WRITE",
121.1290 -    [VMEXIT_DR14_WRITE] = "DR14_WRITE",
121.1291 -    [VMEXIT_DR15_WRITE] = "DR15_WRITE",
121.1292 -    [VMEXIT_EXCEPTION_DE] = "EXCEPTION_DE",
121.1293 -    [VMEXIT_EXCEPTION_DB] = "EXCEPTION_DB",
121.1294 -    [VMEXIT_EXCEPTION_NMI] = "EXCEPTION_NMI",
121.1295 -    [VMEXIT_EXCEPTION_BP] = "EXCEPTION_BP",
121.1296 -    [VMEXIT_EXCEPTION_OF] = "EXCEPTION_OF",
121.1297 -    [VMEXIT_EXCEPTION_BR] = "EXCEPTION_BR",
121.1298 -    [VMEXIT_EXCEPTION_UD] = "EXCEPTION_UD",
121.1299 -    [VMEXIT_EXCEPTION_NM] = "EXCEPTION_NM",
121.1300 -    [VMEXIT_EXCEPTION_DF] = "EXCEPTION_DF",
121.1301 -    [VMEXIT_EXCEPTION_09] = "EXCEPTION_09",
121.1302 -    [VMEXIT_EXCEPTION_TS] = "EXCEPTION_TS",
121.1303 -    [VMEXIT_EXCEPTION_NP] = "EXCEPTION_NP",
121.1304 -    [VMEXIT_EXCEPTION_SS] = "EXCEPTION_SS",
121.1305 -    [VMEXIT_EXCEPTION_GP] = "EXCEPTION_GP",
121.1306 -    [VMEXIT_EXCEPTION_PF] = "EXCEPTION_PF",
121.1307 -    [VMEXIT_EXCEPTION_15] = "EXCEPTION_15",
121.1308 -    [VMEXIT_EXCEPTION_MF] = "EXCEPTION_MF",
121.1309 -    [VMEXIT_EXCEPTION_AC] = "EXCEPTION_AC",
121.1310 -    [VMEXIT_EXCEPTION_MC] = "EXCEPTION_MC",
121.1311 -    [VMEXIT_EXCEPTION_XF] = "EXCEPTION_XF",
121.1312 -    [VMEXIT_INTR] = "INTR",
121.1313 -    [VMEXIT_NMI] = "NMI",
121.1314 -    [VMEXIT_SMI] = "SMI",
121.1315 -    [VMEXIT_INIT] = "INIT",
121.1316 -    [VMEXIT_VINTR] = "VINTR",
121.1317 -    [VMEXIT_CR0_SEL_WRITE] = "CR0_SEL_WRITE",
121.1318 -    [VMEXIT_IDTR_READ] = "IDTR_READ",
121.1319 -    [VMEXIT_GDTR_READ] = "GDTR_READ",
121.1320 -    [VMEXIT_LDTR_READ] = "LDTR_READ",
121.1321 -    [VMEXIT_TR_READ] = "TR_READ",
121.1322 -    [VMEXIT_IDTR_WRITE] = "IDTR_WRITE",
121.1323 -    [VMEXIT_GDTR_WRITE] = "GDTR_WRITE",
121.1324 -    [VMEXIT_LDTR_WRITE] = "LDTR_WRITE",
121.1325 -    [VMEXIT_TR_WRITE] = "TR_WRITE",
121.1326 -    [VMEXIT_RDTSC] = "RDTSC",
121.1327 -    [VMEXIT_RDPMC] = "RDPMC",
121.1328 -    [VMEXIT_PUSHF] = "PUSHF",
121.1329 -    [VMEXIT_POPF] = "POPF",
121.1330 -    [VMEXIT_CPUID] = "CPUID",
121.1331 -    [VMEXIT_RSM] = "RSM",
121.1332 -    [VMEXIT_IRET] = "IRET",
121.1333 -    [VMEXIT_SWINT] = "SWINT",
121.1334 -    [VMEXIT_INVD] = "INVD",
121.1335 -    [VMEXIT_PAUSE] = "PAUSE",
121.1336 -    [VMEXIT_HLT] = "HLT",
121.1337 -    [VMEXIT_INVLPG] = "INVLPG",
121.1338 -    [VMEXIT_INVLPGA] = "INVLPGA",
121.1339 -    [VMEXIT_IOIO] = "IOIO",
121.1340 -    [VMEXIT_MSR] = "MSR",
121.1341 -    [VMEXIT_TASK_SWITCH] = "TASK_SWITCH",
121.1342 -    [VMEXIT_FERR_FREEZE] = "FERR_FREEZE",
121.1343 -    [VMEXIT_SHUTDOWN] = "SHUTDOWN",
121.1344 -    [VMEXIT_VMRUN] = "VMRUN",
121.1345 -    [VMEXIT_VMMCALL] = "VMMCALL",
121.1346 -    [VMEXIT_VMLOAD] = "VMLOAD",
121.1347 -    [VMEXIT_VMSAVE] = "VMSAVE",
121.1348 -    [VMEXIT_STGI] = "STGI",
121.1349 -    [VMEXIT_CLGI] = "CLGI",
121.1350 -    [VMEXIT_SKINIT] = "SKINIT",
121.1351 -    [VMEXIT_RDTSCP] = "RDTSCP",
121.1352 -    [VMEXIT_ICEBP] = "ICEBP",
121.1353 -    [VMEXIT_NPF] = "NPF"
121.1354 -};
121.1355 -#endif /* SVM_EXTRA_DEBUG */
121.1356 -
121.1357 -#ifdef SVM_WALK_GUEST_PAGES
121.1358 -void walk_shadow_and_guest_pt(unsigned long gva)
121.1359 -{
121.1360 -    l2_pgentry_t gpde;
121.1361 -    l2_pgentry_t spde;
121.1362 -    l1_pgentry_t gpte;
121.1363 -    l1_pgentry_t spte;
121.1364 -    struct vcpu        *v    = current;
121.1365 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
121.1366 -    paddr_t gpa;
121.1367 -
121.1368 -    gpa = paging_gva_to_gpa(current, gva);
121.1369 -    printk("gva = %lx, gpa=%"PRIpaddr", gCR3=%x\n", gva, gpa, (u32)vmcb->cr3);
121.1370 -    if( !svm_paging_enabled(v) || mmio_space(gpa) )
121.1371 -        return;
121.1372 -
121.1373 -    /* let's dump the guest and shadow page info */
121.1374 -
121.1375 -    __guest_get_l2e(v, gva, &gpde);
121.1376 -    printk( "G-PDE = %x, flags=%x\n", gpde.l2, l2e_get_flags(gpde) );
121.1377 -    __shadow_get_l2e( v, gva, &spde );
121.1378 -    printk( "S-PDE = %x, flags=%x\n", spde.l2, l2e_get_flags(spde) );
121.1379 -
121.1380 -    if ( unlikely(!(l2e_get_flags(gpde) & _PAGE_PRESENT)) )
121.1381 -        return;
121.1382 -
121.1383 -    spte = l1e_empty();
121.1384 -
121.1385 -    /* This is actually overkill - we only need to ensure the hl2 is in-sync.*/
121.1386 -    shadow_sync_va(v, gva);
121.1387 -
121.1388 -    gpte.l1 = 0;
121.1389 -    __copy_from_user(&gpte, &__linear_l1_table[ l1_linear_offset(gva) ],
121.1390 -                     sizeof(gpte) );
121.1391 -    printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) );
121.1392 -
121.1393 -    BUG(); // need to think about this, and convert usage of
121.1394 -    // phys_to_machine_mapping to use pagetable format...
121.1395 -    __copy_from_user( &spte, &phys_to_machine_mapping[ l1e_get_pfn( gpte ) ], 
121.1396 -                      sizeof(spte) );
121.1397 -
121.1398 -    printk( "S-PTE = %x, flags=%x\n", spte.l1, l1e_get_flags(spte));
121.1399 -}
121.1400 -#endif /* SVM_WALK_GUEST_PAGES */
121.1401 -
121.1402 -
121.1403  asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
121.1404  {
121.1405      unsigned int exit_reason;
121.1406      unsigned long eip;
121.1407      struct vcpu *v = current;
121.1408 -    int do_debug = 0;
121.1409      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
121.1410 -
121.1411 -    ASSERT(vmcb);
121.1412 +    int inst_len;
121.1413  
121.1414      exit_reason = vmcb->exitcode;
121.1415      save_svm_cpu_user_regs(v, regs);
121.1416  
121.1417      HVMTRACE_2D(VMEXIT, v, vmcb->rip, exit_reason);
121.1418  
121.1419 -    if (exit_reason == VMEXIT_INVALID)
121.1420 +    if ( unlikely(exit_reason == VMEXIT_INVALID) )
121.1421      {
121.1422          svm_dump_vmcb(__func__, vmcb);
121.1423          goto exit_and_crash;
121.1424      }
121.1425  
121.1426 -#ifdef SVM_EXTRA_DEBUG
121.1427 -    {
121.1428 -#if defined(__i386__)
121.1429 -#define rip eip
121.1430 -#endif
121.1431 -
121.1432 -        static unsigned long intercepts_counter = 0;
121.1433 -
121.1434 -        if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF) 
121.1435 -        {
121.1436 -            if (svm_paging_enabled(v) && 
121.1437 -                !mmio_space(
121.1438 -                    paging_gva_to_gfn(current, vmcb->exitinfo2) << PAGE_SHIFT))
121.1439 -            {
121.1440 -                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
121.1441 -                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64", "
121.1442 -                       "gpa=%"PRIx64"\n", intercepts_counter,
121.1443 -                       exit_reasons[exit_reason], exit_reason, regs->cs,
121.1444 -                       (u64)regs->rip,
121.1445 -                       (u64)vmcb->exitinfo1,
121.1446 -                       (u64)vmcb->exitinfo2,
121.1447 -                       (u64)vmcb->exitintinfo.bytes,
121.1448 -                       (((u64)paging_gva_to_gfn(current, vmcb->exitinfo2)
121.1449 -                        << PAGE_SHIFT) | (vmcb->exitinfo2 & ~PAGE_MASK)));
121.1450 -            }
121.1451 -            else 
121.1452 -            {
121.1453 -                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
121.1454 -                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
121.1455 -                       intercepts_counter,
121.1456 -                       exit_reasons[exit_reason], exit_reason, regs->cs,
121.1457 -                       (u64)regs->rip,
121.1458 -                       (u64)vmcb->exitinfo1,
121.1459 -                       (u64)vmcb->exitinfo2,
121.1460 -                       (u64)vmcb->exitintinfo.bytes );
121.1461 -            }
121.1462 -        } 
121.1463 -        else if ( svm_dbg_on 
121.1464 -                  && exit_reason != VMEXIT_IOIO 
121.1465 -                  && exit_reason != VMEXIT_INTR) 
121.1466 -        {
121.1467 -
121.1468 -            if (exit_reasons[exit_reason])
121.1469 -            {
121.1470 -                printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
121.1471 -                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
121.1472 -                       intercepts_counter,
121.1473 -                       exit_reasons[exit_reason], exit_reason, regs->cs,
121.1474 -                       (u64)regs->rip,
121.1475 -                       (u64)vmcb->exitinfo1,
121.1476 -                       (u64)vmcb->exitinfo2,
121.1477 -                       (u64)vmcb->exitintinfo.bytes);
121.1478 -            } 
121.1479 -            else 
121.1480 -            {
121.1481 -                printk("I%08ld,ExC=%d(0x%x),IP=%x:%"PRIx64","
121.1482 -                       "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n", 
121.1483 -                       intercepts_counter, exit_reason, exit_reason, regs->cs, 
121.1484 -                       (u64)regs->rip,
121.1485 -                       (u64)vmcb->exitinfo1,
121.1486 -                       (u64)vmcb->exitinfo2,
121.1487 -                       (u64)vmcb->exitintinfo.bytes);
121.1488 -            }
121.1489 -        }
121.1490 -
121.1491 -#ifdef SVM_WALK_GUEST_PAGES
121.1492 -        if( exit_reason == VMEXIT_EXCEPTION_PF 
121.1493 -            && ( ( vmcb->exitinfo2 == vmcb->rip )
121.1494 -                 || vmcb->exitintinfo.bytes) )
121.1495 -        {
121.1496 -            if ( svm_paging_enabled(v) &&
121.1497 -                 !mmio_space(gva_to_gpa(vmcb->exitinfo2)) )
121.1498 -                walk_shadow_and_guest_pt(vmcb->exitinfo2);
121.1499 -        }
121.1500 -#endif
121.1501 -
121.1502 -        intercepts_counter++;
121.1503 -
121.1504 -#if 0
121.1505 -        if (svm_dbg_on)
121.1506 -            do_debug = svm_do_debugout(exit_reason);
121.1507 -#endif
121.1508 -
121.1509 -        if (do_debug)
121.1510 -        {
121.1511 -            printk("%s:+ guest_table = 0x%08x, monitor_table = 0x%08x, "
121.1512 -                   "hw_cr3 = 0x%16lx\n", 
121.1513 -                   __func__,
121.1514 -                   (int) v->arch.guest_table.pfn,
121.1515 -                   (int) v->arch.monitor_table.pfn, 
121.1516 -                   (long unsigned int) v->arch.hvm_vcpu.hw_cr3);
121.1517 -
121.1518 -            svm_dump_vmcb(__func__, vmcb);
121.1519 -            svm_dump_regs(__func__, regs);
121.1520 -            svm_dump_inst(svm_rip2pointer(v));
121.1521 -        }
121.1522 -
121.1523 -#if defined(__i386__)
121.1524 -#undef rip
121.1525 -#endif
121.1526 -
121.1527 -    }
121.1528 -#endif /* SVM_EXTRA_DEBUG */
121.1529 -
121.1530 -
121.1531      perfc_incra(svmexits, exit_reason);
121.1532      eip = vmcb->rip;
121.1533  
121.1534 -#ifdef SVM_EXTRA_DEBUG
121.1535 -    if (do_debug)
121.1536 -    {
121.1537 -        printk("eip = %lx, exit_reason = %d (0x%x)\n", 
121.1538 -               eip, exit_reason, exit_reason);
121.1539 -    }
121.1540 -#endif /* SVM_EXTRA_DEBUG */
121.1541 -
121.1542 -    switch (exit_reason) 
121.1543 -    {
121.1544 -    case VMEXIT_EXCEPTION_DB:
121.1545 +    switch ( exit_reason )
121.1546      {
121.1547 -#ifdef XEN_DEBUGGER
121.1548 -        svm_debug_save_cpu_user_regs(regs);
121.1549 -        pdb_handle_exception(1, regs, 1);
121.1550 -        svm_debug_restore_cpu_user_regs(regs);
121.1551 -#else
121.1552 -        svm_store_cpu_user_regs(regs, v);
121.1553 -        domain_pause_for_debugger();  
121.1554 -#endif
121.1555 -    }
121.1556 -    break;
121.1557 -
121.1558      case VMEXIT_INTR:
121.1559          /* Asynchronous event, handled when we STGI'd after the VMEXIT. */
121.1560          HVMTRACE_0D(INTR, v);
121.1561          break;
121.1562 +
121.1563      case VMEXIT_NMI:
121.1564          /* Asynchronous event, handled when we STGI'd after the VMEXIT. */
121.1565          HVMTRACE_0D(NMI, v);
121.1566          break;
121.1567 +
121.1568      case VMEXIT_SMI:
121.1569          /* Asynchronous event, handled when we STGI'd after the VMEXIT. */
121.1570          HVMTRACE_0D(SMI, v);
121.1571          break;
121.1572  
121.1573 -    case VMEXIT_INIT:
121.1574 -        BUG(); /* unreachable */
121.1575 +    case VMEXIT_EXCEPTION_DB:
121.1576 +        if ( !v->domain->debugger_attached )
121.1577 +            goto exit_and_crash;
121.1578 +        domain_pause_for_debugger();
121.1579 +        break;
121.1580  
121.1581      case VMEXIT_EXCEPTION_BP:
121.1582 -#ifdef XEN_DEBUGGER
121.1583 -        svm_debug_save_cpu_user_regs(regs);
121.1584 -        pdb_handle_exception(3, regs, 1);
121.1585 -        svm_debug_restore_cpu_user_regs(regs);
121.1586 -#else
121.1587 -        if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
121.1588 -            domain_pause_for_debugger();
121.1589 -        else 
121.1590 -            svm_inject_exception(v, TRAP_int3, 0, 0);
121.1591 -#endif
121.1592 +        if ( !v->domain->debugger_attached )
121.1593 +            goto exit_and_crash;
121.1594 +        /* AMD Vol2, 15.11: INT3, INTO, BOUND intercepts do not update RIP. */
121.1595 +        inst_len = __get_instruction_length(v, INSTR_INT3, NULL);
121.1596 +        __update_guest_eip(vmcb, inst_len);
121.1597 +        domain_pause_for_debugger();
121.1598          break;
121.1599  
121.1600      case VMEXIT_EXCEPTION_NM:
121.1601          svm_do_no_device_fault(vmcb);
121.1602          break;  
121.1603  
121.1604 -    case VMEXIT_EXCEPTION_GP:
121.1605 -        /* This should probably not be trapped in the future */
121.1606 -        regs->error_code = vmcb->exitinfo1;
121.1607 -        svm_do_general_protection_fault(v, regs);
121.1608 -        break;  
121.1609 -
121.1610 -    case VMEXIT_EXCEPTION_PF:
121.1611 -    {
121.1612 +    case VMEXIT_EXCEPTION_PF: {
121.1613          unsigned long va;
121.1614          va = vmcb->exitinfo2;
121.1615          regs->error_code = vmcb->exitinfo1;
121.1616 @@ -3039,7 +2338,7 @@ asmlinkage void svm_vmexit_handler(struc
121.1617                      (unsigned long)regs->ecx, (unsigned long)regs->edx,
121.1618                      (unsigned long)regs->esi, (unsigned long)regs->edi);
121.1619  
121.1620 -        if ( svm_do_page_fault(va, regs) )
121.1621 +        if ( paging_fault(va, regs) )
121.1622          {
121.1623              HVMTRACE_2D(PF_XEN, v, va, regs->error_code);
121.1624              break;
121.1625 @@ -3050,14 +2349,6 @@ asmlinkage void svm_vmexit_handler(struc
121.1626          break;
121.1627      }
121.1628  
121.1629 -    case VMEXIT_EXCEPTION_DF:
121.1630 -        /* Debug info to hopefully help debug WHY the guest double-faulted. */
121.1631 -        svm_dump_vmcb(__func__, vmcb);
121.1632 -        svm_dump_regs(__func__, regs);
121.1633 -        svm_dump_inst(svm_rip2pointer(v));
121.1634 -        svm_inject_exception(v, TRAP_double_fault, 1, 0);
121.1635 -        break;
121.1636 -
121.1637      case VMEXIT_VINTR:
121.1638          vmcb->vintr.fields.irq = 0;
121.1639          vmcb->general1_intercepts &= ~GENERAL1_INTERCEPT_VINTR;
121.1640 @@ -3090,14 +2381,13 @@ asmlinkage void svm_vmexit_handler(struc
121.1641          svm_handle_invlpg(1, regs);
121.1642          break;
121.1643  
121.1644 -    case VMEXIT_VMMCALL: {
121.1645 -        int inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
121.1646 +    case VMEXIT_VMMCALL:
121.1647 +        inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
121.1648          ASSERT(inst_len > 0);
121.1649          HVMTRACE_1D(VMMCALL, v, regs->eax);
121.1650          __update_guest_eip(vmcb, inst_len);
121.1651          hvm_do_hypercall(regs);
121.1652          break;
121.1653 -    }
121.1654  
121.1655      case VMEXIT_CR0_READ:
121.1656          svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
121.1657 @@ -3156,14 +2446,21 @@ asmlinkage void svm_vmexit_handler(struc
121.1658          hvm_triple_fault();
121.1659          break;
121.1660  
121.1661 +    case VMEXIT_VMRUN:
121.1662 +    case VMEXIT_VMLOAD:
121.1663 +    case VMEXIT_VMSAVE:
121.1664 +    case VMEXIT_STGI:
121.1665 +    case VMEXIT_CLGI:
121.1666 +    case VMEXIT_SKINIT:
121.1667 +        /* Report "Invalid opcode" on any VM-operation except VMMCALL */
121.1668 +        svm_inject_exception(v, TRAP_invalid_op, 0, 0);
121.1669 +        break;
121.1670 +
121.1671      case VMEXIT_NPF:
121.1672 -    {
121.1673          regs->error_code = vmcb->exitinfo1;
121.1674 -        if ( !svm_do_nested_pgfault(vmcb->exitinfo2, regs) ) {
121.1675 +        if ( !svm_do_nested_pgfault(vmcb->exitinfo2, regs) )
121.1676              domain_crash(v->domain);
121.1677 -        }
121.1678          break;
121.1679 -    }
121.1680  
121.1681      default:
121.1682      exit_and_crash:
121.1683 @@ -3174,35 +2471,16 @@ asmlinkage void svm_vmexit_handler(struc
121.1684          domain_crash(v->domain);
121.1685          break;
121.1686      }
121.1687 -
121.1688 -#ifdef SVM_EXTRA_DEBUG
121.1689 -    if (do_debug) 
121.1690 -    {
121.1691 -        printk("%s: Done switch on vmexit_code\n", __func__);
121.1692 -        svm_dump_regs(__func__, regs);
121.1693 -    }
121.1694 -
121.1695 -    if (do_debug) 
121.1696 -    {
121.1697 -        printk("vmexit_handler():- guest_table = 0x%08x, "
121.1698 -               "monitor_table = 0x%08x, hw_cr3 = 0x%16x\n",
121.1699 -               (int)v->arch.guest_table.pfn,
121.1700 -               (int)v->arch.monitor_table.pfn, 
121.1701 -               (int)v->arch.hvm_vcpu.hw_cr3);
121.1702 -        printk("svm_vmexit_handler: Returning\n");
121.1703 -    }
121.1704 -#endif
121.1705  }
121.1706  
121.1707  asmlinkage void svm_load_cr2(void)
121.1708  {
121.1709      struct vcpu *v = current;
121.1710  
121.1711 -    // this is the last C code before the VMRUN instruction
121.1712 +    /* This is the last C code before the VMRUN instruction. */
121.1713      HVMTRACE_0D(VMENTRY, v);
121.1714  
121.1715 -    local_irq_disable();
121.1716 -    asm volatile("mov %0,%%cr2": :"r" (v->arch.hvm_svm.cpu_cr2));
121.1717 +    asm volatile ( "mov %0,%%cr2" : : "r" (v->arch.hvm_svm.cpu_cr2) );
121.1718  }
121.1719    
121.1720  /*
   122.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Fri Mar 30 10:27:15 2007 -0600
   122.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Fri Mar 30 17:18:42 2007 -0600
   122.3 @@ -194,15 +194,17 @@ static int construct_vmcb(struct vcpu *v
   122.4      paging_update_paging_modes(v);
   122.5      vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
   122.6  
   122.7 -    arch_svm->vmcb->exception_intercepts = MONITOR_DEFAULT_EXCEPTION_BITMAP;
   122.8 -
   122.9      if ( paging_mode_hap(v->domain) )
  122.10      {
  122.11          vmcb->cr0 = arch_svm->cpu_shadow_cr0;
  122.12          vmcb->np_enable = 1; /* enable nested paging */
  122.13          vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */
  122.14 -        vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_PG;
  122.15          vmcb->h_cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
  122.16 +        vmcb->cr4 = arch_svm->cpu_shadow_cr4 = 0;
  122.17 +    }
  122.18 +    else
  122.19 +    {
  122.20 +        vmcb->exception_intercepts = 1U << TRAP_page_fault;
  122.21      }
  122.22  
  122.23      return 0;
   123.1 --- a/xen/arch/x86/hvm/vlapic.c	Fri Mar 30 10:27:15 2007 -0600
   123.2 +++ b/xen/arch/x86/hvm/vlapic.c	Fri Mar 30 17:18:42 2007 -0600
   123.3 @@ -303,7 +303,7 @@ static int vlapic_accept_irq(struct vcpu
   123.4          if ( trig_mode && !(level & APIC_INT_ASSERT) )
   123.5              break;
   123.6          /* FIXME How to check the situation after vcpu reset? */
   123.7 -        if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
   123.8 +        if ( v->is_initialised )
   123.9              hvm_vcpu_reset(v);
  123.10          v->arch.hvm_vcpu.init_sipi_sipi_state =
  123.11              HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
  123.12 @@ -318,7 +318,7 @@ static int vlapic_accept_irq(struct vcpu
  123.13          v->arch.hvm_vcpu.init_sipi_sipi_state =
  123.14              HVM_VCPU_INIT_SIPI_SIPI_STATE_NORM;
  123.15  
  123.16 -        if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  123.17 +        if ( v->is_initialised )
  123.18          {
  123.19              gdprintk(XENLOG_ERR, "SIPI for initialized vcpu %x\n", v->vcpu_id);
  123.20              goto exit_and_crash;
   124.1 --- a/xen/arch/x86/hvm/vmx/intr.c	Fri Mar 30 10:27:15 2007 -0600
   124.2 +++ b/xen/arch/x86/hvm/vmx/intr.c	Fri Mar 30 17:18:42 2007 -0600
   124.3 @@ -89,7 +89,7 @@ static void update_tpr_threshold(struct 
   124.4  asmlinkage void vmx_intr_assist(void)
   124.5  {
   124.6      int intr_type = 0;
   124.7 -    int highest_vector;
   124.8 +    int intr_vector;
   124.9      unsigned long eflags;
  124.10      struct vcpu *v = current;
  124.11      unsigned int idtv_info_field;
  124.12 @@ -106,8 +106,9 @@ asmlinkage void vmx_intr_assist(void)
  124.13  
  124.14      if ( unlikely(v->arch.hvm_vmx.vector_injected) )
  124.15      {
  124.16 -        v->arch.hvm_vmx.vector_injected=0;
  124.17 -        if (unlikely(has_ext_irq)) enable_irq_window(v);
  124.18 +        v->arch.hvm_vmx.vector_injected = 0;
  124.19 +        if ( unlikely(has_ext_irq) )
  124.20 +            enable_irq_window(v);
  124.21          return;
  124.22      }
  124.23  
  124.24 @@ -132,7 +133,6 @@ asmlinkage void vmx_intr_assist(void)
  124.25              enable_irq_window(v);
  124.26  
  124.27          HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
  124.28 -
  124.29          return;
  124.30      }
  124.31  
  124.32 @@ -154,30 +154,13 @@ asmlinkage void vmx_intr_assist(void)
  124.33          return;
  124.34      }
  124.35  
  124.36 -    highest_vector = cpu_get_interrupt(v, &intr_type);
  124.37 -    if ( highest_vector < 0 )
  124.38 -        return;
  124.39 +    intr_vector = cpu_get_interrupt(v, &intr_type);
  124.40 +    BUG_ON(intr_vector < 0);
  124.41  
  124.42 -    switch ( intr_type )
  124.43 -    {
  124.44 -    case APIC_DM_EXTINT:
  124.45 -    case APIC_DM_FIXED:
  124.46 -    case APIC_DM_LOWEST:
  124.47 -        HVMTRACE_2D(INJ_VIRQ, v, highest_vector, /*fake=*/ 0);
  124.48 -        vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
  124.49 -        break;
  124.50 +    HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
  124.51 +    vmx_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
  124.52  
  124.53 -    case APIC_DM_SMI:
  124.54 -    case APIC_DM_NMI:
  124.55 -    case APIC_DM_INIT:
  124.56 -    case APIC_DM_STARTUP:
  124.57 -    default:
  124.58 -        printk("Unsupported interrupt type\n");
  124.59 -        BUG();
  124.60 -        break;
  124.61 -    }
  124.62 -
  124.63 -    pt_intr_post(v, highest_vector, intr_type);
  124.64 +    pt_intr_post(v, intr_vector, intr_type);
  124.65  }
  124.66  
  124.67  /*
   125.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Fri Mar 30 10:27:15 2007 -0600
   125.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Fri Mar 30 17:18:42 2007 -0600
   125.3 @@ -37,84 +37,65 @@
   125.4  #include <xen/keyhandler.h>
   125.5  #include <asm/shadow.h>
   125.6  
   125.7 -/* Basic flags for Pin-based VM-execution controls. */
   125.8 -#define MONITOR_PIN_BASED_EXEC_CONTROLS                 \
   125.9 -    ( PIN_BASED_EXT_INTR_MASK |                         \
  125.10 -      PIN_BASED_NMI_EXITING )
  125.11 -
  125.12 -/* Basic flags for CPU-based VM-execution controls. */
  125.13 -#ifdef __x86_64__
  125.14 -#define MONITOR_CPU_BASED_EXEC_CONTROLS_SUBARCH         \
  125.15 -    ( CPU_BASED_CR8_LOAD_EXITING |                      \
  125.16 -      CPU_BASED_CR8_STORE_EXITING )
  125.17 -#else
  125.18 -#define MONITOR_CPU_BASED_EXEC_CONTROLS_SUBARCH 0
  125.19 -#endif
  125.20 -#define MONITOR_CPU_BASED_EXEC_CONTROLS                 \
  125.21 -    ( MONITOR_CPU_BASED_EXEC_CONTROLS_SUBARCH |         \
  125.22 -      CPU_BASED_HLT_EXITING |                           \
  125.23 -      CPU_BASED_INVDPG_EXITING |                        \
  125.24 -      CPU_BASED_MWAIT_EXITING |                         \
  125.25 -      CPU_BASED_MOV_DR_EXITING |                        \
  125.26 -      CPU_BASED_ACTIVATE_IO_BITMAP |                    \
  125.27 -      CPU_BASED_USE_TSC_OFFSETING )
  125.28 -
  125.29 -/* Basic flags for VM-Exit controls. */
  125.30 -#ifdef __x86_64__
  125.31 -#define MONITOR_VM_EXIT_CONTROLS_SUBARCH VM_EXIT_IA32E_MODE
  125.32 -#else
  125.33 -#define MONITOR_VM_EXIT_CONTROLS_SUBARCH 0
  125.34 -#endif
  125.35 -#define MONITOR_VM_EXIT_CONTROLS                        \
  125.36 -    ( MONITOR_VM_EXIT_CONTROLS_SUBARCH |                \
  125.37 -      VM_EXIT_ACK_INTR_ON_EXIT )
  125.38 -
  125.39 -/* Basic flags for VM-Entry controls. */
  125.40 -#define MONITOR_VM_ENTRY_CONTROLS                       0x00000000
  125.41 -
  125.42  /* Dynamic (run-time adjusted) execution control flags. */
  125.43 -static u32 vmx_pin_based_exec_control;
  125.44 -static u32 vmx_cpu_based_exec_control;
  125.45 -static u32 vmx_vmexit_control;
  125.46 -static u32 vmx_vmentry_control;
  125.47 +u32 vmx_pin_based_exec_control;
  125.48 +u32 vmx_cpu_based_exec_control;
  125.49 +u32 vmx_vmexit_control;
  125.50 +u32 vmx_vmentry_control;
  125.51  
  125.52  static u32 vmcs_revision_id;
  125.53  
  125.54 -static u32 adjust_vmx_controls(u32 ctrls, u32 msr)
  125.55 +static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_max, u32 msr)
  125.56  {
  125.57 -    u32 vmx_msr_low, vmx_msr_high;
  125.58 +    u32 vmx_msr_low, vmx_msr_high, ctl = ctl_max;
  125.59  
  125.60      rdmsr(msr, vmx_msr_low, vmx_msr_high);
  125.61  
  125.62 -    /* Bit == 0 means must be zero. */
  125.63 -    BUG_ON(ctrls & ~vmx_msr_high);
  125.64 +    ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */
  125.65 +    ctl |= vmx_msr_low;  /* bit == 1 in low word  ==> must be one  */
  125.66  
  125.67 -    /* Bit == 1 means must be one. */
  125.68 -    ctrls |= vmx_msr_low;
  125.69 +    /* Ensure minimum (required) set of control bits are supported. */
  125.70 +    BUG_ON(ctl_min & ~ctl);
  125.71 +    BUG_ON(ctl_min & ~ctl_max);
  125.72  
  125.73 -    return ctrls;
  125.74 +    return ctl;
  125.75  }
  125.76  
  125.77  void vmx_init_vmcs_config(void)
  125.78  {
  125.79 -    u32 vmx_msr_low, vmx_msr_high;
  125.80 +    u32 vmx_msr_low, vmx_msr_high, min, max;
  125.81      u32 _vmx_pin_based_exec_control;
  125.82      u32 _vmx_cpu_based_exec_control;
  125.83      u32 _vmx_vmexit_control;
  125.84      u32 _vmx_vmentry_control;
  125.85  
  125.86 -    _vmx_pin_based_exec_control =
  125.87 -        adjust_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
  125.88 -                            MSR_IA32_VMX_PINBASED_CTLS_MSR);
  125.89 -    _vmx_cpu_based_exec_control =
  125.90 -        adjust_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
  125.91 -                            MSR_IA32_VMX_PROCBASED_CTLS_MSR);
  125.92 -    _vmx_vmexit_control =
  125.93 -        adjust_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
  125.94 -                            MSR_IA32_VMX_EXIT_CTLS_MSR);
  125.95 -    _vmx_vmentry_control =
  125.96 -        adjust_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
  125.97 -                            MSR_IA32_VMX_ENTRY_CTLS_MSR);
  125.98 +    min = max = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
  125.99 +    _vmx_pin_based_exec_control = adjust_vmx_controls(
 125.100 +        min, max, MSR_IA32_VMX_PINBASED_CTLS_MSR);
 125.101 +
 125.102 +    min = max = (CPU_BASED_HLT_EXITING |
 125.103 +                 CPU_BASED_INVDPG_EXITING |
 125.104 +                 CPU_BASED_MWAIT_EXITING |
 125.105 +                 CPU_BASED_MOV_DR_EXITING |
 125.106 +                 CPU_BASED_ACTIVATE_IO_BITMAP |
 125.107 +                 CPU_BASED_USE_TSC_OFFSETING);
 125.108 +#ifdef __x86_64__
 125.109 +    min = max |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING;
 125.110 +#endif
 125.111 +    max |= CPU_BASED_ACTIVATE_MSR_BITMAP;
 125.112 +    _vmx_cpu_based_exec_control = adjust_vmx_controls(
 125.113 +        min, max, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
 125.114 +
 125.115 +    min = max = VM_EXIT_ACK_INTR_ON_EXIT;
 125.116 +#ifdef __x86_64__
 125.117 +    min = max |= VM_EXIT_IA32E_MODE;
 125.118 +#endif
 125.119 +    _vmx_vmexit_control = adjust_vmx_controls(
 125.120 +        min, max, MSR_IA32_VMX_EXIT_CTLS_MSR);
 125.121 +
 125.122 +    min = max = 0;
 125.123 +    _vmx_vmentry_control = adjust_vmx_controls(
 125.124 +        min, max, MSR_IA32_VMX_ENTRY_CTLS_MSR);
 125.125  
 125.126      rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
 125.127  
 125.128 @@ -210,7 +191,7 @@ void vmx_vmcs_exit(struct vcpu *v)
 125.129      if ( v == current )
 125.130          return;
 125.131  
 125.132 -    /* Don't confuse arch_vmx_do_resume (for @v or @current!) */
 125.133 +    /* Don't confuse vmx_do_resume (for @v or @current!) */
 125.134      vmx_clear_vmcs(v);
 125.135      if ( is_hvm_vcpu(current) )
 125.136          vmx_load_vmcs(current);
 125.137 @@ -307,6 +288,9 @@ static void construct_vmcs(struct vcpu *
 125.138      __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control);
 125.139      v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control;
 125.140  
 125.141 +    if ( cpu_has_vmx_msr_bitmap )
 125.142 +        __vmwrite(MSR_BITMAP, virt_to_maddr(hvm_msr_bitmap));
 125.143 +
 125.144      /* I/O access bitmap. */
 125.145      __vmwrite(IO_BITMAP_A, virt_to_maddr(hvm_io_bitmap));
 125.146      __vmwrite(IO_BITMAP_B, virt_to_maddr(hvm_io_bitmap + PAGE_SIZE));
 125.147 @@ -412,7 +396,7 @@ static void construct_vmcs(struct vcpu *
 125.148      __vmwrite(VMCS_LINK_POINTER_HIGH, ~0UL);
 125.149  #endif
 125.150  
 125.151 -    __vmwrite(EXCEPTION_BITMAP, MONITOR_DEFAULT_EXCEPTION_BITMAP);
 125.152 +    __vmwrite(EXCEPTION_BITMAP, 1U << TRAP_page_fault);
 125.153  
 125.154      /* Guest CR0. */
 125.155      cr0 = read_cr0();
 125.156 @@ -493,8 +477,10 @@ void vm_resume_fail(unsigned long eflags
 125.157      domain_crash_synchronous();
 125.158  }
 125.159  
 125.160 -void arch_vmx_do_resume(struct vcpu *v)
 125.161 +void vmx_do_resume(struct vcpu *v)
 125.162  {
 125.163 +    bool_t debug_state;
 125.164 +
 125.165      if ( v->arch.hvm_vmx.active_cpu == smp_processor_id() )
 125.166      {
 125.167          vmx_load_vmcs(v);
 125.168 @@ -507,6 +493,19 @@ void arch_vmx_do_resume(struct vcpu *v)
 125.169          vmx_set_host_env(v);
 125.170      }
 125.171  
 125.172 +    debug_state = v->domain->debugger_attached;
 125.173 +    if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
 125.174 +    {
 125.175 +        unsigned long intercepts = __vmread(EXCEPTION_BITMAP);
 125.176 +        unsigned long mask = (1U << TRAP_debug) | (1U << TRAP_int3);
 125.177 +        v->arch.hvm_vcpu.debug_state_latch = debug_state;
 125.178 +        if ( debug_state )
 125.179 +            intercepts |= mask;
 125.180 +        else
 125.181 +            intercepts &= ~mask;
 125.182 +        __vmwrite(EXCEPTION_BITMAP, intercepts);
 125.183 +    }
 125.184 +
 125.185      hvm_do_resume(v);
 125.186      reset_stack_and_jump(vmx_asm_do_vmentry);
 125.187  }
   126.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 30 10:27:15 2007 -0600
   126.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 30 17:18:42 2007 -0600
   126.3 @@ -60,7 +60,7 @@ static int vmx_vcpu_initialise(struct vc
   126.4  
   126.5      spin_lock_init(&v->arch.hvm_vmx.vmcs_lock);
   126.6  
   126.7 -    v->arch.schedule_tail    = arch_vmx_do_resume;
   126.8 +    v->arch.schedule_tail    = vmx_do_resume;
   126.9      v->arch.ctxt_switch_from = vmx_ctxt_switch_from;
  126.10      v->arch.ctxt_switch_to   = vmx_ctxt_switch_to;
  126.11  
  126.12 @@ -716,11 +716,6 @@ static void vmx_load_cpu_guest_regs(stru
  126.13      /* NB. Bit 1 of RFLAGS must be set for VMENTRY to succeed. */
  126.14      __vmwrite(GUEST_RFLAGS, regs->eflags | 2UL);
  126.15  
  126.16 -    if ( regs->eflags & EF_TF )
  126.17 -        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  126.18 -    else
  126.19 -        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  126.20 -
  126.21      if ( regs->eflags & EF_VM )
  126.22      {
  126.23          /*
  126.24 @@ -880,7 +875,7 @@ static void vmx_stts(struct vcpu *v)
  126.25      {
  126.26          v->arch.hvm_vmx.cpu_cr0 |= X86_CR0_TS;
  126.27          __vmwrite(GUEST_CR0, v->arch.hvm_vmx.cpu_cr0);
  126.28 -        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
  126.29 +        __vm_set_bit(EXCEPTION_BITMAP, TRAP_no_device);
  126.30      }
  126.31  }
  126.32  
  126.33 @@ -1001,7 +996,28 @@ static int vmx_event_injection_faulted(s
  126.34      return (idtv_info_field & INTR_INFO_VALID_MASK);
  126.35  }
  126.36  
  126.37 +static void disable_intercept_for_msr(u32 msr)
  126.38 +{
  126.39 +    /*
  126.40 +     * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
  126.41 +     * have the write-low and read-high bitmap offsets the wrong way round.
  126.42 +     * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
  126.43 +     */
  126.44 +    if ( msr <= 0x1fff )
  126.45 +    {
  126.46 +        __clear_bit(msr, hvm_msr_bitmap + 0x000); /* read-low */
  126.47 +        __clear_bit(msr, hvm_msr_bitmap + 0x800); /* write-low */
  126.48 +    }
  126.49 +    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
  126.50 +    {
  126.51 +        msr &= 0x1fff;
  126.52 +        __clear_bit(msr, hvm_msr_bitmap + 0x400); /* read-high */
  126.53 +        __clear_bit(msr, hvm_msr_bitmap + 0xc00); /* write-high */
  126.54 +    }
  126.55 +}
  126.56 +
  126.57  static struct hvm_function_table vmx_function_table = {
  126.58 +    .name                 = "VMX",
  126.59      .disable              = stop_vmx,
  126.60      .vcpu_initialise      = vmx_vcpu_initialise,
  126.61      .vcpu_destroy         = vmx_vcpu_destroy,
  126.62 @@ -1079,12 +1095,20 @@ int start_vmx(void)
  126.63          return 0;
  126.64      }
  126.65  
  126.66 -    printk("VMXON is done\n");
  126.67 -
  126.68      vmx_save_host_msrs();
  126.69  
  126.70 +    if ( smp_processor_id() != 0 )
  126.71 +        return 1;
  126.72 +
  126.73      hvm_enable(&vmx_function_table);
  126.74  
  126.75 +    if ( cpu_has_vmx_msr_bitmap )
  126.76 +    {
  126.77 +        printk("VMX: MSR intercept bitmap enabled\n");
  126.78 +        disable_intercept_for_msr(MSR_FS_BASE);
  126.79 +        disable_intercept_for_msr(MSR_GS_BASE);
  126.80 +    }
  126.81 +
  126.82      return 1;
  126.83  }
  126.84  
  126.85 @@ -1109,42 +1133,12 @@ static void inline __update_guest_eip(un
  126.86      __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
  126.87  }
  126.88  
  126.89 -static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
  126.90 -{
  126.91 -    int result;
  126.92 -
  126.93 -#if 0 /* keep for debugging */
  126.94 -    {
  126.95 -        unsigned long eip, cs;
  126.96 -
  126.97 -        cs = __vmread(GUEST_CS_BASE);
  126.98 -        eip = __vmread(GUEST_RIP);
  126.99 -        HVM_DBG_LOG(DBG_LEVEL_VMMU,
 126.100 -                    "vmx_do_page_fault = 0x%lx, cs_base=%lx, "
 126.101 -                    "eip = %lx, error_code = %lx\n",
 126.102 -                    va, cs, eip, (unsigned long)regs->error_code);
 126.103 -    }
 126.104 -#endif
 126.105 -
 126.106 -    result = paging_fault(va, regs);
 126.107 -
 126.108 -#if 0
 126.109 -    if ( !result )
 126.110 -    {
 126.111 -        eip = __vmread(GUEST_RIP);
 126.112 -        printk("vmx pgfault to guest va=%lx eip=%lx\n", va, eip);
 126.113 -    }
 126.114 -#endif
 126.115 -
 126.116 -    return result;
 126.117 -}
 126.118 -
 126.119  static void vmx_do_no_device_fault(void)
 126.120  {
 126.121      struct vcpu *v = current;
 126.122  
 126.123      setup_fpu(current);
 126.124 -    __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 126.125 +    __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
 126.126  
 126.127      /* Disable TS in guest CR0 unless the guest wants the exception too. */
 126.128      if ( !(v->arch.hvm_vmx.cpu_shadow_cr0 & X86_CR0_TS) )
 126.129 @@ -1875,19 +1869,27 @@ static int vmx_set_cr0(unsigned long val
 126.130      unsigned long old_cr0;
 126.131      unsigned long old_base_mfn;
 126.132  
 126.133 -    /*
 126.134 -     * CR0: We don't want to lose PE and PG.
 126.135 -     */
 126.136 -    old_cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
 126.137 -    paging_enabled = (old_cr0 & X86_CR0_PE) && (old_cr0 & X86_CR0_PG);
 126.138 +    HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
 126.139 +
 126.140 +    /* ET is reserved and should be always be 1. */
 126.141 +    value |= X86_CR0_ET;
 126.142 +
 126.143 +    if ( (value & (X86_CR0_PE|X86_CR0_PG)) == X86_CR0_PG )
 126.144 +    {
 126.145 +        vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
 126.146 +        return 0;
 126.147 +    }
 126.148  
 126.149      /* TS cleared? Then initialise FPU now. */
 126.150      if ( !(value & X86_CR0_TS) )
 126.151      {
 126.152          setup_fpu(v);
 126.153 -        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 126.154 +        __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
 126.155      }
 126.156  
 126.157 +    old_cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
 126.158 +    paging_enabled = old_cr0 & X86_CR0_PG;
 126.159 +
 126.160      v->arch.hvm_vmx.cpu_cr0 = (value | X86_CR0_PE | X86_CR0_PG 
 126.161                                 | X86_CR0_NE | X86_CR0_WP);
 126.162      __vmwrite(GUEST_CR0, v->arch.hvm_vmx.cpu_cr0);
 126.163 @@ -1895,8 +1897,6 @@ static int vmx_set_cr0(unsigned long val
 126.164      v->arch.hvm_vmx.cpu_shadow_cr0 = value;
 126.165      __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
 126.166  
 126.167 -    HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
 126.168 -
 126.169      if ( (value & X86_CR0_PE) && (value & X86_CR0_PG) && !paging_enabled )
 126.170      {
 126.171          /*
 126.172 @@ -2259,11 +2259,9 @@ static int vmx_cr_access(unsigned long e
 126.173          mov_from_cr(cr, gp, regs);
 126.174          break;
 126.175      case TYPE_CLTS:
 126.176 -//        TRACE_VMEXIT(1, TYPE_CLTS);
 126.177 -
 126.178          /* We initialise the FPU now, to avoid needing another vmexit. */
 126.179          setup_fpu(v);
 126.180 -        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
 126.181 +        __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
 126.182  
 126.183          v->arch.hvm_vmx.cpu_cr0 &= ~X86_CR0_TS; /* clear TS */
 126.184          __vmwrite(GUEST_CR0, v->arch.hvm_vmx.cpu_cr0);
 126.185 @@ -2275,10 +2273,7 @@ static int vmx_cr_access(unsigned long e
 126.186          value = v->arch.hvm_vmx.cpu_shadow_cr0;
 126.187          value = (value & ~0xF) |
 126.188              (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
 126.189 -//        TRACE_VMEXIT(1, TYPE_LMSW);
 126.190 -//        TRACE_VMEXIT(2, value);
 126.191          return vmx_set_cr0(value);
 126.192 -        break;
 126.193      default:
 126.194          BUG();
 126.195      }
 126.196 @@ -2435,60 +2430,6 @@ static inline void vmx_do_extint(struct 
 126.197      }
 126.198  }
 126.199  
 126.200 -#if defined (__x86_64__)
 126.201 -void store_cpu_user_regs(struct cpu_user_regs *regs)
 126.202 -{
 126.203 -    regs->ss = __vmread(GUEST_SS_SELECTOR);
 126.204 -    regs->rsp = __vmread(GUEST_RSP);
 126.205 -    regs->rflags = __vmread(GUEST_RFLAGS);
 126.206 -    regs->cs = __vmread(GUEST_CS_SELECTOR);
 126.207 -    regs->ds = __vmread(GUEST_DS_SELECTOR);
 126.208 -    regs->es = __vmread(GUEST_ES_SELECTOR);
 126.209 -    regs->rip = __vmread(GUEST_RIP);
 126.210 -}
 126.211 -#elif defined (__i386__)
 126.212 -void store_cpu_user_regs(struct cpu_user_regs *regs)
 126.213 -{
 126.214 -    regs->ss = __vmread(GUEST_SS_SELECTOR);
 126.215 -    regs->esp = __vmread(GUEST_RSP);
 126.216 -    regs->eflags = __vmread(GUEST_RFLAGS);
 126.217 -    regs->cs = __vmread(GUEST_CS_SELECTOR);
 126.218 -    regs->ds = __vmread(GUEST_DS_SELECTOR);
 126.219 -    regs->es = __vmread(GUEST_ES_SELECTOR);
 126.220 -    regs->eip = __vmread(GUEST_RIP);
 126.221 -}
 126.222 -#endif
 126.223 -
 126.224 -#ifdef XEN_DEBUGGER
 126.225 -void save_cpu_user_regs(struct cpu_user_regs *regs)
 126.226 -{
 126.227 -    regs->xss = __vmread(GUEST_SS_SELECTOR);
 126.228 -    regs->esp = __vmread(GUEST_RSP);
 126.229 -    regs->eflags = __vmread(GUEST_RFLAGS);
 126.230 -    regs->xcs = __vmread(GUEST_CS_SELECTOR);
 126.231 -    regs->eip = __vmread(GUEST_RIP);
 126.232 -
 126.233 -    regs->xgs = __vmread(GUEST_GS_SELECTOR);
 126.234 -    regs->xfs = __vmread(GUEST_FS_SELECTOR);
 126.235 -    regs->xes = __vmread(GUEST_ES_SELECTOR);